diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2007-04-10 19:19:00 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 14:16:01 -0400 |
commit | 9bedb799f2d270dc6434473fcab745adc930a85b (patch) | |
tree | 3663b299bccfcd81c508755759a9f572a5692d59 /drivers/ata/pata_pdc2027x.c | |
parent | ad648c08835851b1b447b08144013e86aceafe5f (diff) |
pata_pdc2027x: Updates
Signed-off-by: Alan Cox <alan@redhat.com>
Correct missing modefilter (crash if BAR4 unassigned)
Use Cable Detect method
Wrap ->set_mode instead ready for ->post_set_mode removal
Maxtor errata as per Jeff Garzik report
Remove duplicated private udma_mask hacking
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/pata_pdc2027x.c')
-rw-r--r-- | drivers/ata/pata_pdc2027x.c | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 93bcdadb7be3..8261f4f8c1dc 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/libata.h> | 35 | #include <linux/libata.h> |
36 | 36 | ||
37 | #define DRV_NAME "pata_pdc2027x" | 37 | #define DRV_NAME "pata_pdc2027x" |
38 | #define DRV_VERSION "0.8" | 38 | #define DRV_VERSION "0.9" |
39 | #undef PDC_DEBUG | 39 | #undef PDC_DEBUG |
40 | 40 | ||
41 | #ifdef PDC_DEBUG | 41 | #ifdef PDC_DEBUG |
@@ -66,8 +66,10 @@ static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *e | |||
66 | static void pdc2027x_error_handler(struct ata_port *ap); | 66 | static void pdc2027x_error_handler(struct ata_port *ap); |
67 | static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev); | 67 | static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev); |
68 | static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev); | 68 | static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev); |
69 | static void pdc2027x_post_set_mode(struct ata_port *ap); | ||
70 | static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc); | 69 | static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc); |
70 | static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask); | ||
71 | static int pdc2027x_cable_detect(struct ata_port *ap); | ||
72 | static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed); | ||
71 | 73 | ||
72 | /* | 74 | /* |
73 | * ATA Timing Tables based on 133MHz controller clock. | 75 | * ATA Timing Tables based on 133MHz controller clock. |
@@ -146,6 +148,7 @@ static struct scsi_host_template pdc2027x_sht = { | |||
146 | 148 | ||
147 | static struct ata_port_operations pdc2027x_pata100_ops = { | 149 | static struct ata_port_operations pdc2027x_pata100_ops = { |
148 | .port_disable = ata_port_disable, | 150 | .port_disable = ata_port_disable, |
151 | .mode_filter = ata_pci_default_filter, | ||
149 | 152 | ||
150 | .tf_load = ata_tf_load, | 153 | .tf_load = ata_tf_load, |
151 | .tf_read = ata_tf_read, | 154 | .tf_read = ata_tf_read, |
@@ -166,6 +169,7 @@ static struct ata_port_operations pdc2027x_pata100_ops = { | |||
166 | .thaw = ata_bmdma_thaw, | 169 | .thaw = ata_bmdma_thaw, |
167 | .error_handler = pdc2027x_error_handler, | 170 | .error_handler = pdc2027x_error_handler, |
168 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 171 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
172 | .cable_detect = pdc2027x_cable_detect, | ||
169 | 173 | ||
170 | .irq_handler = ata_interrupt, | 174 | .irq_handler = ata_interrupt, |
171 | .irq_clear = ata_bmdma_irq_clear, | 175 | .irq_clear = ata_bmdma_irq_clear, |
@@ -179,7 +183,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = { | |||
179 | .port_disable = ata_port_disable, | 183 | .port_disable = ata_port_disable, |
180 | .set_piomode = pdc2027x_set_piomode, | 184 | .set_piomode = pdc2027x_set_piomode, |
181 | .set_dmamode = pdc2027x_set_dmamode, | 185 | .set_dmamode = pdc2027x_set_dmamode, |
182 | .post_set_mode = pdc2027x_post_set_mode, | 186 | .set_mode = pdc2027x_set_mode, |
187 | .mode_filter = pdc2027x_mode_filter, | ||
183 | 188 | ||
184 | .tf_load = ata_tf_load, | 189 | .tf_load = ata_tf_load, |
185 | .tf_read = ata_tf_read, | 190 | .tf_read = ata_tf_read, |
@@ -200,6 +205,7 @@ static struct ata_port_operations pdc2027x_pata133_ops = { | |||
200 | .thaw = ata_bmdma_thaw, | 205 | .thaw = ata_bmdma_thaw, |
201 | .error_handler = pdc2027x_error_handler, | 206 | .error_handler = pdc2027x_error_handler, |
202 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 207 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
208 | .cable_detect = pdc2027x_cable_detect, | ||
203 | 209 | ||
204 | .irq_handler = ata_interrupt, | 210 | .irq_handler = ata_interrupt, |
205 | .irq_clear = ata_bmdma_irq_clear, | 211 | .irq_clear = ata_bmdma_irq_clear, |
@@ -261,7 +267,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade | |||
261 | } | 267 | } |
262 | 268 | ||
263 | /** | 269 | /** |
264 | * pdc2027x_pata_cbl_detect - Probe host controller cable detect info | 270 | * pdc2027x_pata_cable_detect - Probe host controller cable detect info |
265 | * @ap: Port for which cable detect info is desired | 271 | * @ap: Port for which cable detect info is desired |
266 | * | 272 | * |
267 | * Read 80c cable indicator from Promise extended register. | 273 | * Read 80c cable indicator from Promise extended register. |
@@ -270,7 +276,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade | |||
270 | * LOCKING: | 276 | * LOCKING: |
271 | * None (inherited from caller). | 277 | * None (inherited from caller). |
272 | */ | 278 | */ |
273 | static void pdc2027x_cbl_detect(struct ata_port *ap) | 279 | static int pdc2027x_cable_detect(struct ata_port *ap) |
274 | { | 280 | { |
275 | u32 cgcr; | 281 | u32 cgcr; |
276 | 282 | ||
@@ -281,13 +287,10 @@ static void pdc2027x_cbl_detect(struct ata_port *ap) | |||
281 | 287 | ||
282 | PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no); | 288 | PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no); |
283 | 289 | ||
284 | ap->cbl = ATA_CBL_PATA80; | 290 | return ATA_CBL_PATA80; |
285 | return; | ||
286 | |||
287 | cbl40: | 291 | cbl40: |
288 | printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no); | 292 | printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no); |
289 | ap->cbl = ATA_CBL_PATA40; | 293 | return ATA_CBL_PATA40; |
290 | ap->udma_mask &= ATA_UDMA_MASK_40C; | ||
291 | } | 294 | } |
292 | 295 | ||
293 | /** | 296 | /** |
@@ -314,7 +317,6 @@ static int pdc2027x_prereset(struct ata_port *ap) | |||
314 | /* Check whether port enabled */ | 317 | /* Check whether port enabled */ |
315 | if (!pdc2027x_port_enabled(ap)) | 318 | if (!pdc2027x_port_enabled(ap)) |
316 | return -ENOENT; | 319 | return -ENOENT; |
317 | pdc2027x_cbl_detect(ap); | ||
318 | return ata_std_prereset(ap); | 320 | return ata_std_prereset(ap); |
319 | } | 321 | } |
320 | 322 | ||
@@ -334,6 +336,32 @@ static void pdc2027x_error_handler(struct ata_port *ap) | |||
334 | } | 336 | } |
335 | 337 | ||
336 | /** | 338 | /** |
339 | * pdc2720x_mode_filter - mode selection filter | ||
340 | * @adev: ATA device | ||
341 | * @mask: list of modes proposed | ||
342 | * | ||
343 | * Block UDMA on devices that cause trouble with this controller. | ||
344 | */ | ||
345 | |||
346 | static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask) | ||
347 | { | ||
348 | unsigned char model_num[ATA_ID_PROD_LEN + 1]; | ||
349 | struct ata_device *pair = ata_dev_pair(adev); | ||
350 | |||
351 | if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL) | ||
352 | return ata_pci_default_filter(adev, mask); | ||
353 | |||
354 | /* Check for slave of a Maxtor at UDMA6 */ | ||
355 | ata_id_c_string(pair->id, model_num, ATA_ID_PROD, | ||
356 | ATA_ID_PROD_LEN + 1); | ||
357 | /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */ | ||
358 | if(strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6) | ||
359 | mask &= ~ (1 << (6 + ATA_SHIFT_UDMA)); | ||
360 | |||
361 | return ata_pci_default_filter(adev, mask); | ||
362 | } | ||
363 | |||
364 | /** | ||
337 | * pdc2027x_set_piomode - Initialize host controller PATA PIO timings | 365 | * pdc2027x_set_piomode - Initialize host controller PATA PIO timings |
338 | * @ap: Port to configure | 366 | * @ap: Port to configure |
339 | * @adev: um | 367 | * @adev: um |
@@ -444,17 +472,22 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
444 | } | 472 | } |
445 | 473 | ||
446 | /** | 474 | /** |
447 | * pdc2027x_post_set_mode - Set the timing registers back to correct values. | 475 | * pdc2027x_set_mode - Set the timing registers back to correct values. |
448 | * @ap: Port to configure | 476 | * @ap: Port to configure |
477 | * @r_failed: Returned device for failure | ||
449 | * | 478 | * |
450 | * The pdc2027x hardware will look at "SET FEATURES" and change the timing registers | 479 | * The pdc2027x hardware will look at "SET FEATURES" and change the timing registers |
451 | * automatically. The values set by the hardware might be incorrect, under 133Mhz PLL. | 480 | * automatically. The values set by the hardware might be incorrect, under 133Mhz PLL. |
452 | * This function overwrites the possibly incorrect values set by the hardware to be correct. | 481 | * This function overwrites the possibly incorrect values set by the hardware to be correct. |
453 | */ | 482 | */ |
454 | static void pdc2027x_post_set_mode(struct ata_port *ap) | 483 | static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed) |
455 | { | 484 | { |
456 | int i; | 485 | int i; |
457 | 486 | ||
487 | i = ata_do_set_mode(ap, r_failed); | ||
488 | if (i < 0) | ||
489 | return i; | ||
490 | |||
458 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 491 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
459 | struct ata_device *dev = &ap->device[i]; | 492 | struct ata_device *dev = &ap->device[i]; |
460 | 493 | ||
@@ -476,6 +509,7 @@ static void pdc2027x_post_set_mode(struct ata_port *ap) | |||
476 | } | 509 | } |
477 | } | 510 | } |
478 | } | 511 | } |
512 | return 0; | ||
479 | } | 513 | } |
480 | 514 | ||
481 | /** | 515 | /** |