aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Campbell <brad@wasp.net.au>2005-05-12 15:07:47 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-05-12 15:07:47 -0400
commit6f2f38128170814e151cfedf79532e19cd179567 (patch)
tree6728b987c6d4199c4d03335407f5b55859b34a86
parent88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (diff)
[PATCH] libata basic detection and errata for PATA->SATA bridges
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 <brad@wasp.net.au>
-rw-r--r--drivers/scsi/libata-core.c35
-rw-r--r--include/linux/ata.h1
-rw-r--r--include/linux/libata.h1
3 files changed, 35 insertions, 2 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 0b5d3a5b7eda..8b5a3f00083d 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1186,6 +1186,37 @@ err_out:
1186 DPRINTK("EXIT, err\n"); 1186 DPRINTK("EXIT, err\n");
1187} 1187}
1188 1188
1189
1190static inline u8 ata_dev_knobble(struct ata_port *ap)
1191{
1192 return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
1193}
1194
1195/**
1196 * ata_dev_config - Run device specific handlers and check for
1197 * SATA->PATA bridges
1198 * @ap: Bus
1199 * @i: Device
1200 *
1201 * LOCKING:
1202 */
1203
1204void ata_dev_config(struct ata_port *ap, unsigned int i)
1205{
1206 /* limit bridge transfers to udma5, 200 sectors */
1207 if (ata_dev_knobble(ap)) {
1208 printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
1209 ap->id, ap->device->devno);
1210 ap->udma_mask &= ATA_UDMA5;
1211 ap->host->max_sectors = ATA_MAX_SECTORS;
1212 ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
1213 ap->device->flags |= ATA_DFLAG_LOCK_SECTORS;
1214 }
1215
1216 if (ap->ops->dev_config)
1217 ap->ops->dev_config(ap, &ap->device[i]);
1218}
1219
1189/** 1220/**
1190 * ata_bus_probe - Reset and probe ATA bus 1221 * ata_bus_probe - Reset and probe ATA bus
1191 * @ap: Bus to probe 1222 * @ap: Bus to probe
@@ -1208,8 +1239,7 @@ static int ata_bus_probe(struct ata_port *ap)
1208 ata_dev_identify(ap, i); 1239 ata_dev_identify(ap, i);
1209 if (ata_dev_present(&ap->device[i])) { 1240 if (ata_dev_present(&ap->device[i])) {
1210 found = 1; 1241 found = 1;
1211 if (ap->ops->dev_config) 1242 ata_dev_config(ap,i);
1212 ap->ops->dev_config(ap, &ap->device[i]);
1213 } 1243 }
1214 } 1244 }
1215 1245
@@ -4014,6 +4044,7 @@ EXPORT_SYMBOL_GPL(ata_scsi_release);
4014EXPORT_SYMBOL_GPL(ata_host_intr); 4044EXPORT_SYMBOL_GPL(ata_host_intr);
4015EXPORT_SYMBOL_GPL(ata_dev_classify); 4045EXPORT_SYMBOL_GPL(ata_dev_classify);
4016EXPORT_SYMBOL_GPL(ata_dev_id_string); 4046EXPORT_SYMBOL_GPL(ata_dev_id_string);
4047EXPORT_SYMBOL_GPL(ata_dev_config);
4017EXPORT_SYMBOL_GPL(ata_scsi_simulate); 4048EXPORT_SYMBOL_GPL(ata_scsi_simulate);
4018 4049
4019#ifdef CONFIG_PCI 4050#ifdef CONFIG_PCI
diff --git a/include/linux/ata.h b/include/linux/ata.h
index f178894edd04..ca5fcadf9981 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -224,6 +224,7 @@ struct ata_taskfile {
224}; 224};
225 225
226#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) 226#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
227#define ata_id_is_sata(id) ((id)[93] == 0)
227#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6)) 228#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
228#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5)) 229#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
229#define ata_id_has_flush(id) ((id)[83] & (1 << 12)) 230#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 505160ab472b..d33e70361a7d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -420,6 +420,7 @@ extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
420extern unsigned int ata_dev_classify(struct ata_taskfile *tf); 420extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
421extern void ata_dev_id_string(u16 *id, unsigned char *s, 421extern void ata_dev_id_string(u16 *id, unsigned char *s,
422 unsigned int ofs, unsigned int len); 422 unsigned int ofs, unsigned int len);
423extern void ata_dev_config(struct ata_port *ap, unsigned int i);
423extern void ata_bmdma_setup (struct ata_queued_cmd *qc); 424extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
424extern void ata_bmdma_start (struct ata_queued_cmd *qc); 425extern void ata_bmdma_start (struct ata_queued_cmd *qc);
425extern void ata_bmdma_stop(struct ata_port *ap); 426extern void ata_bmdma_stop(struct ata_port *ap);