libata basic detection and errata for PATA->SATA bridges
PATCH 1/1 libata basic detection and errata for PATA->SATA bridges
Ok Jeff, I can take a hint! :p)
Patch against 2.6.9-rc1 Vanilla
This patch works around an issue with WD drives (and possibly others) over SiL PATA->SATA Bridges on SATA controllers locking up with transfers > 200 sectors.
Signed-off-by Brad Campbell <[email protected]>
drivers/scsi/libata-core.c renamed from linux-2.6.0/drivers/scsi/libata-core.c +34 -3
@@ -1128,6 +1128,37 @@DPRINTK ("EXIT, err\n" ); } + +static inline u8 ata_dev_knobble (struct ata_port *ap) +{ +return ((ap->cbl ==ATA_CBL_SATA ) && (!ata_id_is_sata (ap->device))); +} + +/** +* ata_dev_config - Run device specific handlers and check for +* SATA->PATA bridges +* @ap: Bus +* @i: Device +* +* LOCKING: +*/ + +void ata_dev_config (struct ata_port *ap,unsigned int i) +{ +/* limit bridge transfers to udma5, 200 sectors */ +if (ata_dev_knobble (ap)) { +printk (KERN_INFO "ata%u(%u): applying bridge limits\n" , + ap->id, ap->device->devno); + ap->udma_mask &=ATA_UDMA5 ; + ap->host->max_sectors =ATA_MAX_SECTORS ; + ap->host->hostt->max_sectors =ATA_MAX_SECTORS ; + ap->device->flags |=ATA_DFLAG_LOCK_SECTORS ; + } + +if (ap->ops->dev_config) + ap->ops->dev_config (ap, &ap->device[i]); +} +/** * ata_bus_probe - Reset and probe ATA bus * @ap: Bus to probe
@@ -1150,8 +1181,7 @@ata_dev_identify (ap, i);if (ata_dev_present (&ap->device[i])) { found =1 ; -if (ap->ops->dev_config) - ap->ops->dev_config (ap, &ap->device[i]); +ata_dev_config (ap,i); } }
@@ -1226,7 +1256,7 @@ata_port_disable (ap);return ; } - + ap->cbl =ATA_CBL_SATA ;ata_bus_reset (ap); }
@@ -3567,3 +3597,4 @@EXPORT_SYMBOL_GPL (ata_scsi_release);EXPORT_SYMBOL_GPL (ata_host_intr);EXPORT_SYMBOL_GPL (ata_dev_id_string); +EXPORT_SYMBOL_GPL (ata_dev_config);
nly in linux-2.6.9-rc1/include: config
include/linux/ata.h renamed from linux-2.6.0/include/linux/ata.h +1 -0
@@ -218,6 +218,7 @@ };#define ata_id_is_ata (dev) (((dev)->id[0] & (1 << 15)) == 0) +#define ata_id_is_sata (dev) ((dev)->id[93] == 0)#define ata_id_rahead_enabled (dev) ((dev)->id[85] & (1 << 6))#define ata_id_wcache_enabled (dev) ((dev)->id[85] & (1 << 5))#define ata_id_has_flush (dev) ((dev)->id[83] & (1 << 12))
include/linux/libata.h renamed from linux-2.6.0/include/linux/libata.h +1 -0
@@ -400,6 +400,7 @@ unsigned int n_elem);extern void ata_dev_id_string (struct ata_device *dev,unsigned char *s,unsigned int ofs,unsigned int len); +extern void ata_dev_config (struct ata_port *ap,unsigned int i);extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc);extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);extern void ata_bmdma_setup_pio (struct ata_queued_cmd *qc);