diff options
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r-- | drivers/ata/sata_promise.c | 78 |
1 files changed, 34 insertions, 44 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 6dc0b011a6b7..2ad5872fe90c 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -45,8 +45,7 @@ | |||
45 | #include "sata_promise.h" | 45 | #include "sata_promise.h" |
46 | 46 | ||
47 | #define DRV_NAME "sata_promise" | 47 | #define DRV_NAME "sata_promise" |
48 | #define DRV_VERSION "2.07" | 48 | #define DRV_VERSION "2.08" |
49 | |||
50 | 49 | ||
51 | enum { | 50 | enum { |
52 | PDC_MAX_PORTS = 4, | 51 | PDC_MAX_PORTS = 4, |
@@ -94,7 +93,7 @@ enum { | |||
94 | board_20319 = 2, /* FastTrak S150 TX4 */ | 93 | board_20319 = 2, /* FastTrak S150 TX4 */ |
95 | board_20619 = 3, /* FastTrak TX4000 */ | 94 | board_20619 = 3, /* FastTrak TX4000 */ |
96 | board_2057x = 4, /* SATAII150 Tx2plus */ | 95 | board_2057x = 4, /* SATAII150 Tx2plus */ |
97 | board_2057x_pata = 5, /* SATAII150 Tx2plus */ | 96 | board_2057x_pata = 5, /* SATAII150 Tx2plus PATA port */ |
98 | board_40518 = 6, /* SATAII150 Tx4 */ | 97 | board_40518 = 6, /* SATAII150 Tx4 */ |
99 | 98 | ||
100 | PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ | 99 | PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ |
@@ -124,7 +123,6 @@ enum { | |||
124 | PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */ | 123 | PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */ |
125 | }; | 124 | }; |
126 | 125 | ||
127 | |||
128 | struct pdc_port_priv { | 126 | struct pdc_port_priv { |
129 | u8 *pkt; | 127 | u8 *pkt; |
130 | dma_addr_t pkt_dma; | 128 | dma_addr_t pkt_dma; |
@@ -252,7 +250,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
252 | PDC_FLAG_SATA_PATA, | 250 | PDC_FLAG_SATA_PATA, |
253 | .pio_mask = 0x1f, /* pio0-4 */ | 251 | .pio_mask = 0x1f, /* pio0-4 */ |
254 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 252 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
255 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 253 | .udma_mask = ATA_UDMA6, |
256 | .port_ops = &pdc_old_sata_ops, | 254 | .port_ops = &pdc_old_sata_ops, |
257 | }, | 255 | }, |
258 | 256 | ||
@@ -261,7 +259,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
261 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, | 259 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, |
262 | .pio_mask = 0x1f, /* pio0-4 */ | 260 | .pio_mask = 0x1f, /* pio0-4 */ |
263 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 261 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
264 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 262 | .udma_mask = ATA_UDMA6, |
265 | .port_ops = &pdc_pata_ops, | 263 | .port_ops = &pdc_pata_ops, |
266 | }, | 264 | }, |
267 | 265 | ||
@@ -271,7 +269,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
271 | PDC_FLAG_4_PORTS, | 269 | PDC_FLAG_4_PORTS, |
272 | .pio_mask = 0x1f, /* pio0-4 */ | 270 | .pio_mask = 0x1f, /* pio0-4 */ |
273 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 271 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
274 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 272 | .udma_mask = ATA_UDMA6, |
275 | .port_ops = &pdc_old_sata_ops, | 273 | .port_ops = &pdc_old_sata_ops, |
276 | }, | 274 | }, |
277 | 275 | ||
@@ -281,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
281 | PDC_FLAG_4_PORTS, | 279 | PDC_FLAG_4_PORTS, |
282 | .pio_mask = 0x1f, /* pio0-4 */ | 280 | .pio_mask = 0x1f, /* pio0-4 */ |
283 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 281 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
284 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 282 | .udma_mask = ATA_UDMA6, |
285 | .port_ops = &pdc_pata_ops, | 283 | .port_ops = &pdc_pata_ops, |
286 | }, | 284 | }, |
287 | 285 | ||
@@ -291,7 +289,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
291 | PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, | 289 | PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, |
292 | .pio_mask = 0x1f, /* pio0-4 */ | 290 | .pio_mask = 0x1f, /* pio0-4 */ |
293 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 291 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
294 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 292 | .udma_mask = ATA_UDMA6, |
295 | .port_ops = &pdc_sata_ops, | 293 | .port_ops = &pdc_sata_ops, |
296 | }, | 294 | }, |
297 | 295 | ||
@@ -301,7 +299,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
301 | PDC_FLAG_GEN_II, | 299 | PDC_FLAG_GEN_II, |
302 | .pio_mask = 0x1f, /* pio0-4 */ | 300 | .pio_mask = 0x1f, /* pio0-4 */ |
303 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 301 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
304 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 302 | .udma_mask = ATA_UDMA6, |
305 | .port_ops = &pdc_pata_ops, | 303 | .port_ops = &pdc_pata_ops, |
306 | }, | 304 | }, |
307 | 305 | ||
@@ -311,7 +309,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
311 | PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, | 309 | PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, |
312 | .pio_mask = 0x1f, /* pio0-4 */ | 310 | .pio_mask = 0x1f, /* pio0-4 */ |
313 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 311 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
314 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 312 | .udma_mask = ATA_UDMA6, |
315 | .port_ops = &pdc_sata_ops, | 313 | .port_ops = &pdc_sata_ops, |
316 | }, | 314 | }, |
317 | }; | 315 | }; |
@@ -340,7 +338,6 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { | |||
340 | { } /* terminate list */ | 338 | { } /* terminate list */ |
341 | }; | 339 | }; |
342 | 340 | ||
343 | |||
344 | static struct pci_driver pdc_ata_pci_driver = { | 341 | static struct pci_driver pdc_ata_pci_driver = { |
345 | .name = DRV_NAME, | 342 | .name = DRV_NAME, |
346 | .id_table = pdc_ata_pci_tbl, | 343 | .id_table = pdc_ata_pci_tbl, |
@@ -348,7 +345,6 @@ static struct pci_driver pdc_ata_pci_driver = { | |||
348 | .remove = ata_pci_remove_one, | 345 | .remove = ata_pci_remove_one, |
349 | }; | 346 | }; |
350 | 347 | ||
351 | |||
352 | static int pdc_common_port_start(struct ata_port *ap) | 348 | static int pdc_common_port_start(struct ata_port *ap) |
353 | { | 349 | { |
354 | struct device *dev = ap->host->dev; | 350 | struct device *dev = ap->host->dev; |
@@ -382,7 +378,7 @@ static int pdc_sata_port_start(struct ata_port *ap) | |||
382 | 378 | ||
383 | /* fix up PHYMODE4 align timing */ | 379 | /* fix up PHYMODE4 align timing */ |
384 | if (ap->flags & PDC_FLAG_GEN_II) { | 380 | if (ap->flags & PDC_FLAG_GEN_II) { |
385 | void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; | 381 | void __iomem *mmio = ap->ioaddr.scr_addr; |
386 | unsigned int tmp; | 382 | unsigned int tmp; |
387 | 383 | ||
388 | tmp = readl(mmio + 0x014); | 384 | tmp = readl(mmio + 0x014); |
@@ -418,7 +414,7 @@ static void pdc_reset_port(struct ata_port *ap) | |||
418 | static int pdc_pata_cable_detect(struct ata_port *ap) | 414 | static int pdc_pata_cable_detect(struct ata_port *ap) |
419 | { | 415 | { |
420 | u8 tmp; | 416 | u8 tmp; |
421 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; | 417 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; |
422 | 418 | ||
423 | tmp = readb(mmio); | 419 | tmp = readb(mmio); |
424 | if (tmp & 0x01) | 420 | if (tmp & 0x01) |
@@ -438,7 +434,6 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | |||
438 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); | 434 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); |
439 | } | 435 | } |
440 | 436 | ||
441 | |||
442 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, | 437 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, |
443 | u32 val) | 438 | u32 val) |
444 | { | 439 | { |
@@ -573,7 +568,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) | |||
573 | 568 | ||
574 | static void pdc_freeze(struct ata_port *ap) | 569 | static void pdc_freeze(struct ata_port *ap) |
575 | { | 570 | { |
576 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 571 | void __iomem *mmio = ap->ioaddr.cmd_addr; |
577 | u32 tmp; | 572 | u32 tmp; |
578 | 573 | ||
579 | tmp = readl(mmio + PDC_CTLSTAT); | 574 | tmp = readl(mmio + PDC_CTLSTAT); |
@@ -585,7 +580,7 @@ static void pdc_freeze(struct ata_port *ap) | |||
585 | 580 | ||
586 | static void pdc_thaw(struct ata_port *ap) | 581 | static void pdc_thaw(struct ata_port *ap) |
587 | { | 582 | { |
588 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 583 | void __iomem *mmio = ap->ioaddr.cmd_addr; |
589 | u32 tmp; | 584 | u32 tmp; |
590 | 585 | ||
591 | /* clear IRQ */ | 586 | /* clear IRQ */ |
@@ -657,8 +652,8 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | |||
657 | ata_port_abort(ap); | 652 | ata_port_abort(ap); |
658 | } | 653 | } |
659 | 654 | ||
660 | static inline unsigned int pdc_host_intr( struct ata_port *ap, | 655 | static inline unsigned int pdc_host_intr(struct ata_port *ap, |
661 | struct ata_queued_cmd *qc) | 656 | struct ata_queued_cmd *qc) |
662 | { | 657 | { |
663 | unsigned int handled = 0; | 658 | unsigned int handled = 0; |
664 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; | 659 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; |
@@ -685,10 +680,10 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap, | |||
685 | handled = 1; | 680 | handled = 1; |
686 | break; | 681 | break; |
687 | 682 | ||
688 | default: | 683 | default: |
689 | ap->stats.idle_irq++; | 684 | ap->stats.idle_irq++; |
690 | break; | 685 | break; |
691 | } | 686 | } |
692 | 687 | ||
693 | return handled; | 688 | return handled; |
694 | } | 689 | } |
@@ -701,6 +696,18 @@ static void pdc_irq_clear(struct ata_port *ap) | |||
701 | readl(mmio + PDC_INT_SEQMASK); | 696 | readl(mmio + PDC_INT_SEQMASK); |
702 | } | 697 | } |
703 | 698 | ||
699 | static inline int pdc_is_sataii_tx4(unsigned long flags) | ||
700 | { | ||
701 | const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS; | ||
702 | return (flags & mask) == mask; | ||
703 | } | ||
704 | |||
705 | static inline unsigned int pdc_port_no_to_ata_no(unsigned int port_no, int is_sataii_tx4) | ||
706 | { | ||
707 | static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2}; | ||
708 | return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no; | ||
709 | } | ||
710 | |||
704 | static irqreturn_t pdc_interrupt (int irq, void *dev_instance) | 711 | static irqreturn_t pdc_interrupt (int irq, void *dev_instance) |
705 | { | 712 | { |
706 | struct ata_host *host = dev_instance; | 713 | struct ata_host *host = dev_instance; |
@@ -807,7 +814,6 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | |||
807 | ata_tf_load(ap, tf); | 814 | ata_tf_load(ap, tf); |
808 | } | 815 | } |
809 | 816 | ||
810 | |||
811 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | 817 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) |
812 | { | 818 | { |
813 | WARN_ON (tf->protocol == ATA_PROT_DMA || | 819 | WARN_ON (tf->protocol == ATA_PROT_DMA || |
@@ -867,7 +873,6 @@ static void pdc_ata_setup_port(struct ata_port *ap, | |||
867 | ap->ioaddr.scr_addr = scr_addr; | 873 | ap->ioaddr.scr_addr = scr_addr; |
868 | } | 874 | } |
869 | 875 | ||
870 | |||
871 | static void pdc_host_init(struct ata_host *host) | 876 | static void pdc_host_init(struct ata_host *host) |
872 | { | 877 | { |
873 | void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; | 878 | void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; |
@@ -955,10 +960,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
955 | 960 | ||
956 | if (pi->flags & PDC_FLAG_SATA_PATA) { | 961 | if (pi->flags & PDC_FLAG_SATA_PATA) { |
957 | u8 tmp = readb(base + PDC_FLASH_CTL+1); | 962 | u8 tmp = readb(base + PDC_FLASH_CTL+1); |
958 | if (!(tmp & 0x80)) { | 963 | if (!(tmp & 0x80)) |
959 | ppi[n_ports++] = pi + 1; | 964 | ppi[n_ports++] = pi + 1; |
960 | dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n"); | ||
961 | } | ||
962 | } | 965 | } |
963 | 966 | ||
964 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | 967 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
@@ -968,22 +971,12 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
968 | } | 971 | } |
969 | host->iomap = pcim_iomap_table(pdev); | 972 | host->iomap = pcim_iomap_table(pdev); |
970 | 973 | ||
971 | is_sataii_tx4 = 0; | 974 | is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags); |
972 | if ((pi->flags & (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) == (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) { | ||
973 | is_sataii_tx4 = 1; | ||
974 | dev_printk(KERN_INFO, &pdev->dev, "applying SATAII TX4 port numbering workaround\n"); | ||
975 | } | ||
976 | for (i = 0; i < host->n_ports; i++) { | 975 | for (i = 0; i < host->n_ports; i++) { |
977 | static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2}; | 976 | unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4); |
978 | int ata_nr; | ||
979 | |||
980 | ata_nr = i; | ||
981 | if (is_sataii_tx4) | ||
982 | ata_nr = sataii_tx4_port_remap[i]; | ||
983 | |||
984 | pdc_ata_setup_port(host->ports[i], | 977 | pdc_ata_setup_port(host->ports[i], |
985 | base + 0x200 + ata_nr * 0x80, | 978 | base + 0x200 + ata_no * 0x80, |
986 | base + 0x400 + ata_nr * 0x100); | 979 | base + 0x400 + ata_no * 0x100); |
987 | } | 980 | } |
988 | 981 | ||
989 | /* initialize adapter */ | 982 | /* initialize adapter */ |
@@ -1002,19 +995,16 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
1002 | &pdc_ata_sht); | 995 | &pdc_ata_sht); |
1003 | } | 996 | } |
1004 | 997 | ||
1005 | |||
1006 | static int __init pdc_ata_init(void) | 998 | static int __init pdc_ata_init(void) |
1007 | { | 999 | { |
1008 | return pci_register_driver(&pdc_ata_pci_driver); | 1000 | return pci_register_driver(&pdc_ata_pci_driver); |
1009 | } | 1001 | } |
1010 | 1002 | ||
1011 | |||
1012 | static void __exit pdc_ata_exit(void) | 1003 | static void __exit pdc_ata_exit(void) |
1013 | { | 1004 | { |
1014 | pci_unregister_driver(&pdc_ata_pci_driver); | 1005 | pci_unregister_driver(&pdc_ata_pci_driver); |
1015 | } | 1006 | } |
1016 | 1007 | ||
1017 | |||
1018 | MODULE_AUTHOR("Jeff Garzik"); | 1008 | MODULE_AUTHOR("Jeff Garzik"); |
1019 | MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver"); | 1009 | MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver"); |
1020 | MODULE_LICENSE("GPL"); | 1010 | MODULE_LICENSE("GPL"); |