diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2010-12-25 14:44:01 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2011-01-07 22:33:10 -0500 |
commit | 8e834c2e6d51e053c6bd23fec1d95529f618f760 (patch) | |
tree | 8d4441b90f880c2d7cd4d5ef1799bfb9fa50ba16 | |
parent | b27dcfb0670ea7352a67137f4ff7947c2a9f6892 (diff) |
pata_hpt{37x|3x2n}: SATA mode filtering
The Marvell bridge chips used on HighPoint SATA cards do not seem to support
the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes; these cards are
based on HPT372/372A/372N/374 chips (judging from the vendor drivers), so
the Linux drivers need to have a mode_filter() method for these chips...
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r-- | drivers/ata/pata_hpt37x.c | 54 | ||||
-rw-r--r-- | drivers/ata/pata_hpt3x2n.c | 61 |
2 files changed, 93 insertions, 22 deletions
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 9ae4c0830577..9c62951c3e26 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
10 | * Portions Copyright (C) 2003 Red Hat Inc | 10 | * Portions Copyright (C) 2003 Red Hat Inc |
11 | * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. | 11 | * Portions Copyright (C) 2005-2010 MontaVista Software, Inc. |
12 | * | 12 | * |
13 | * TODO | 13 | * TODO |
14 | * Look into engine reset on timeout errors. Should not be required. | 14 | * Look into engine reset on timeout errors. Should not be required. |
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/libata.h> | 24 | #include <linux/libata.h> |
25 | 25 | ||
26 | #define DRV_NAME "pata_hpt37x" | 26 | #define DRV_NAME "pata_hpt37x" |
27 | #define DRV_VERSION "0.6.15" | 27 | #define DRV_VERSION "0.6.16" |
28 | 28 | ||
29 | struct hpt_clock { | 29 | struct hpt_clock { |
30 | u8 xfer_speed; | 30 | u8 xfer_speed; |
@@ -302,6 +302,22 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) | |||
302 | } | 302 | } |
303 | 303 | ||
304 | /** | 304 | /** |
305 | * hpt372_filter - mode selection filter | ||
306 | * @adev: ATA device | ||
307 | * @mask: mode mask | ||
308 | * | ||
309 | * The Marvell bridge chips used on the HighPoint SATA cards do not seem | ||
310 | * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... | ||
311 | */ | ||
312 | static unsigned long hpt372_filter(struct ata_device *adev, unsigned long mask) | ||
313 | { | ||
314 | if (ata_id_is_sata(adev->id)) | ||
315 | mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA); | ||
316 | |||
317 | return mask; | ||
318 | } | ||
319 | |||
320 | /** | ||
305 | * hpt37x_cable_detect - Detect the cable type | 321 | * hpt37x_cable_detect - Detect the cable type |
306 | * @ap: ATA port to detect on | 322 | * @ap: ATA port to detect on |
307 | * | 323 | * |
@@ -586,11 +602,11 @@ static struct ata_port_operations hpt370a_port_ops = { | |||
586 | }; | 602 | }; |
587 | 603 | ||
588 | /* | 604 | /* |
589 | * Configuration for HPT372, HPT371, HPT302. Slightly different PIO | 605 | * Configuration for HPT371 and HPT302. Slightly different PIO and DMA |
590 | * and DMA mode setting functionality. | 606 | * mode setting functionality. |
591 | */ | 607 | */ |
592 | 608 | ||
593 | static struct ata_port_operations hpt372_port_ops = { | 609 | static struct ata_port_operations hpt302_port_ops = { |
594 | .inherits = &ata_bmdma_port_ops, | 610 | .inherits = &ata_bmdma_port_ops, |
595 | 611 | ||
596 | .bmdma_stop = hpt37x_bmdma_stop, | 612 | .bmdma_stop = hpt37x_bmdma_stop, |
@@ -602,7 +618,17 @@ static struct ata_port_operations hpt372_port_ops = { | |||
602 | }; | 618 | }; |
603 | 619 | ||
604 | /* | 620 | /* |
605 | * Configuration for HPT374. Mode setting works like 372 and friends | 621 | * Configuration for HPT372. Mode setting works like 371 and 302 |
622 | * but we have a mode filter. | ||
623 | */ | ||
624 | |||
625 | static struct ata_port_operations hpt372_port_ops = { | ||
626 | .inherits = &hpt302_port_ops, | ||
627 | .mode_filter = hpt372_filter, | ||
628 | }; | ||
629 | |||
630 | /* | ||
631 | * Configuration for HPT374. Mode setting and filtering works like 372 | ||
606 | * but we have a different cable detection procedure for function 1. | 632 | * but we have a different cable detection procedure for function 1. |
607 | */ | 633 | */ |
608 | 634 | ||
@@ -753,7 +779,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
753 | .udma_mask = ATA_UDMA5, | 779 | .udma_mask = ATA_UDMA5, |
754 | .port_ops = &hpt370a_port_ops | 780 | .port_ops = &hpt370a_port_ops |
755 | }; | 781 | }; |
756 | /* HPT371, 372 and friends - UDMA133 */ | 782 | /* HPT372 - UDMA133 */ |
757 | static const struct ata_port_info info_hpt372 = { | 783 | static const struct ata_port_info info_hpt372 = { |
758 | .flags = ATA_FLAG_SLAVE_POSS, | 784 | .flags = ATA_FLAG_SLAVE_POSS, |
759 | .pio_mask = ATA_PIO4, | 785 | .pio_mask = ATA_PIO4, |
@@ -761,6 +787,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
761 | .udma_mask = ATA_UDMA6, | 787 | .udma_mask = ATA_UDMA6, |
762 | .port_ops = &hpt372_port_ops | 788 | .port_ops = &hpt372_port_ops |
763 | }; | 789 | }; |
790 | /* HPT371, 302 - UDMA133 */ | ||
791 | static const struct ata_port_info info_hpt302 = { | ||
792 | .flags = ATA_FLAG_SLAVE_POSS, | ||
793 | .pio_mask = ATA_PIO4, | ||
794 | .mwdma_mask = ATA_MWDMA2, | ||
795 | .udma_mask = ATA_UDMA6, | ||
796 | .port_ops = &hpt302_port_ops | ||
797 | }; | ||
764 | /* HPT374 - UDMA100, function 1 uses different prereset method */ | 798 | /* HPT374 - UDMA100, function 1 uses different prereset method */ |
765 | static const struct ata_port_info info_hpt374_fn0 = { | 799 | static const struct ata_port_info info_hpt374_fn0 = { |
766 | .flags = ATA_FLAG_SLAVE_POSS, | 800 | .flags = ATA_FLAG_SLAVE_POSS, |
@@ -828,7 +862,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
828 | } else { | 862 | } else { |
829 | switch(dev->device) { | 863 | switch(dev->device) { |
830 | case PCI_DEVICE_ID_TTI_HPT372: | 864 | case PCI_DEVICE_ID_TTI_HPT372: |
831 | /* 372N if rev >= 2*/ | 865 | /* 372N if rev >= 2 */ |
832 | if (rev >= 2) | 866 | if (rev >= 2) |
833 | return -ENODEV; | 867 | return -ENODEV; |
834 | ppi[0] = &info_hpt372; | 868 | ppi[0] = &info_hpt372; |
@@ -838,14 +872,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
838 | /* 302N if rev > 1 */ | 872 | /* 302N if rev > 1 */ |
839 | if (rev > 1) | 873 | if (rev > 1) |
840 | return -ENODEV; | 874 | return -ENODEV; |
841 | ppi[0] = &info_hpt372; | 875 | ppi[0] = &info_hpt302; |
842 | /* Check this */ | 876 | /* Check this */ |
843 | chip_table = &hpt302; | 877 | chip_table = &hpt302; |
844 | break; | 878 | break; |
845 | case PCI_DEVICE_ID_TTI_HPT371: | 879 | case PCI_DEVICE_ID_TTI_HPT371: |
846 | if (rev > 1) | 880 | if (rev > 1) |
847 | return -ENODEV; | 881 | return -ENODEV; |
848 | ppi[0] = &info_hpt372; | 882 | ppi[0] = &info_hpt302; |
849 | chip_table = &hpt371; | 883 | chip_table = &hpt371; |
850 | /* Single channel device, master is not present | 884 | /* Single channel device, master is not present |
851 | but the BIOS (or us for non x86) must mark it | 885 | but the BIOS (or us for non x86) must mark it |
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 32f3463216b8..97c6ded047b8 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
10 | * Portions Copyright (C) 2003 Red Hat Inc | 10 | * Portions Copyright (C) 2003 Red Hat Inc |
11 | * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. | 11 | * Portions Copyright (C) 2005-2010 MontaVista Software, Inc. |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * TODO | 14 | * TODO |
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
26 | 26 | ||
27 | #define DRV_NAME "pata_hpt3x2n" | 27 | #define DRV_NAME "pata_hpt3x2n" |
28 | #define DRV_VERSION "0.3.10" | 28 | #define DRV_VERSION "0.3.11" |
29 | 29 | ||
30 | enum { | 30 | enum { |
31 | HPT_PCI_FAST = (1 << 31), | 31 | HPT_PCI_FAST = (1 << 31), |
@@ -113,6 +113,22 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * hpt372n_filter - mode selection filter | ||
117 | * @adev: ATA device | ||
118 | * @mask: mode mask | ||
119 | * | ||
120 | * The Marvell bridge chips used on the HighPoint SATA cards do not seem | ||
121 | * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... | ||
122 | */ | ||
123 | static unsigned long hpt372n_filter(struct ata_device *adev, unsigned long mask) | ||
124 | { | ||
125 | if (ata_id_is_sata(adev->id)) | ||
126 | mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA); | ||
127 | |||
128 | return mask; | ||
129 | } | ||
130 | |||
131 | /** | ||
116 | * hpt3x2n_cable_detect - Detect the cable type | 132 | * hpt3x2n_cable_detect - Detect the cable type |
117 | * @ap: ATA port to detect on | 133 | * @ap: ATA port to detect on |
118 | * | 134 | * |
@@ -328,10 +344,10 @@ static struct scsi_host_template hpt3x2n_sht = { | |||
328 | }; | 344 | }; |
329 | 345 | ||
330 | /* | 346 | /* |
331 | * Configuration for HPT3x2n. | 347 | * Configuration for HPT302N/371N. |
332 | */ | 348 | */ |
333 | 349 | ||
334 | static struct ata_port_operations hpt3x2n_port_ops = { | 350 | static struct ata_port_operations hpt3xxn_port_ops = { |
335 | .inherits = &ata_bmdma_port_ops, | 351 | .inherits = &ata_bmdma_port_ops, |
336 | 352 | ||
337 | .bmdma_stop = hpt3x2n_bmdma_stop, | 353 | .bmdma_stop = hpt3x2n_bmdma_stop, |
@@ -345,6 +361,15 @@ static struct ata_port_operations hpt3x2n_port_ops = { | |||
345 | .prereset = hpt3x2n_pre_reset, | 361 | .prereset = hpt3x2n_pre_reset, |
346 | }; | 362 | }; |
347 | 363 | ||
364 | /* | ||
365 | * Configuration for HPT372N. Same as 302N/371N but we have a mode filter. | ||
366 | */ | ||
367 | |||
368 | static struct ata_port_operations hpt372n_port_ops = { | ||
369 | .inherits = &hpt3xxn_port_ops, | ||
370 | .mode_filter = &hpt372n_filter, | ||
371 | }; | ||
372 | |||
348 | /** | 373 | /** |
349 | * hpt3xn_calibrate_dpll - Calibrate the DPLL loop | 374 | * hpt3xn_calibrate_dpll - Calibrate the DPLL loop |
350 | * @dev: PCI device | 375 | * @dev: PCI device |
@@ -437,15 +462,23 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) | |||
437 | 462 | ||
438 | static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 463 | static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
439 | { | 464 | { |
440 | /* HPT372N and friends - UDMA133 */ | 465 | /* HPT372N - UDMA133 */ |
441 | static const struct ata_port_info info = { | 466 | static const struct ata_port_info info_hpt372n = { |
442 | .flags = ATA_FLAG_SLAVE_POSS, | 467 | .flags = ATA_FLAG_SLAVE_POSS, |
443 | .pio_mask = ATA_PIO4, | 468 | .pio_mask = ATA_PIO4, |
444 | .mwdma_mask = ATA_MWDMA2, | 469 | .mwdma_mask = ATA_MWDMA2, |
445 | .udma_mask = ATA_UDMA6, | 470 | .udma_mask = ATA_UDMA6, |
446 | .port_ops = &hpt3x2n_port_ops | 471 | .port_ops = &hpt372n_port_ops |
447 | }; | 472 | }; |
448 | const struct ata_port_info *ppi[] = { &info, NULL }; | 473 | /* HPT302N and HPT371N - UDMA133 */ |
474 | static const struct ata_port_info info_hpt3xxn = { | ||
475 | .flags = ATA_FLAG_SLAVE_POSS, | ||
476 | .pio_mask = ATA_PIO4, | ||
477 | .mwdma_mask = ATA_MWDMA2, | ||
478 | .udma_mask = ATA_UDMA6, | ||
479 | .port_ops = &hpt3xxn_port_ops | ||
480 | }; | ||
481 | const struct ata_port_info *ppi[] = { &info_hpt3xxn, NULL }; | ||
449 | u8 rev = dev->revision; | 482 | u8 rev = dev->revision; |
450 | u8 irqmask; | 483 | u8 irqmask; |
451 | unsigned int pci_mhz; | 484 | unsigned int pci_mhz; |
@@ -461,24 +494,28 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
461 | 494 | ||
462 | switch(dev->device) { | 495 | switch(dev->device) { |
463 | case PCI_DEVICE_ID_TTI_HPT366: | 496 | case PCI_DEVICE_ID_TTI_HPT366: |
497 | /* 372N if rev >= 6 */ | ||
464 | if (rev < 6) | 498 | if (rev < 6) |
465 | return -ENODEV; | 499 | return -ENODEV; |
466 | break; | 500 | goto hpt372n; |
467 | case PCI_DEVICE_ID_TTI_HPT371: | 501 | case PCI_DEVICE_ID_TTI_HPT371: |
502 | /* 371N if rev >= 2 */ | ||
468 | if (rev < 2) | 503 | if (rev < 2) |
469 | return -ENODEV; | 504 | return -ENODEV; |
470 | /* 371N if rev > 1 */ | ||
471 | break; | 505 | break; |
472 | case PCI_DEVICE_ID_TTI_HPT372: | 506 | case PCI_DEVICE_ID_TTI_HPT372: |
473 | /* 372N if rev >= 2*/ | 507 | /* 372N if rev >= 2 */ |
474 | if (rev < 2) | 508 | if (rev < 2) |
475 | return -ENODEV; | 509 | return -ENODEV; |
476 | break; | 510 | goto hpt372n; |
477 | case PCI_DEVICE_ID_TTI_HPT302: | 511 | case PCI_DEVICE_ID_TTI_HPT302: |
512 | /* 302N if rev >= 2 */ | ||
478 | if (rev < 2) | 513 | if (rev < 2) |
479 | return -ENODEV; | 514 | return -ENODEV; |
480 | break; | 515 | break; |
481 | case PCI_DEVICE_ID_TTI_HPT372N: | 516 | case PCI_DEVICE_ID_TTI_HPT372N: |
517 | hpt372n: | ||
518 | ppi[0] = &info_hpt372n; | ||
482 | break; | 519 | break; |
483 | default: | 520 | default: |
484 | printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); | 521 | printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); |