diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 04:28:13 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 04:28:13 -0500 |
commit | 99b3738fbf17208ac474420fa6b7e4b0c0c2b9ed (patch) | |
tree | 6f977546112ccbd617ef40ae38a1ca558d71bce9 /drivers/scsi/sata_promise.c | |
parent | 332b5a52f2f96bc2d13bbe594a430318c0ee4425 (diff) | |
parent | 8a19ac89edbe9b702c10fd2039b8cb2db4644a5f (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers/scsi/sata_promise.c')
-rw-r--r-- | drivers/scsi/sata_promise.c | 104 |
1 files changed, 82 insertions, 22 deletions
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 760c56f71632..dcd1667f4144 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include "sata_promise.h" | 46 | #include "sata_promise.h" |
47 | 47 | ||
48 | #define DRV_NAME "sata_promise" | 48 | #define DRV_NAME "sata_promise" |
49 | #define DRV_VERSION "1.03" | 49 | #define DRV_VERSION "1.04" |
50 | 50 | ||
51 | 51 | ||
52 | enum { | 52 | enum { |
@@ -58,6 +58,7 @@ enum { | |||
58 | PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ | 58 | PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ |
59 | PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ | 59 | PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ |
60 | PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ | 60 | PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ |
61 | PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ | ||
61 | PDC_SLEW_CTL = 0x470, /* slew rate control reg */ | 62 | PDC_SLEW_CTL = 0x470, /* slew rate control reg */ |
62 | 63 | ||
63 | PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) | | 64 | PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) | |
@@ -67,8 +68,10 @@ enum { | |||
67 | board_20319 = 1, /* FastTrak S150 TX4 */ | 68 | board_20319 = 1, /* FastTrak S150 TX4 */ |
68 | board_20619 = 2, /* FastTrak TX4000 */ | 69 | board_20619 = 2, /* FastTrak TX4000 */ |
69 | board_20771 = 3, /* FastTrak TX2300 */ | 70 | board_20771 = 3, /* FastTrak TX2300 */ |
71 | board_2057x = 4, /* SATAII150 Tx2plus */ | ||
72 | board_40518 = 5, /* SATAII150 Tx4 */ | ||
70 | 73 | ||
71 | PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */ | 74 | PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ |
72 | 75 | ||
73 | PDC_RESET = (1 << 11), /* HDMA reset */ | 76 | PDC_RESET = (1 << 11), /* HDMA reset */ |
74 | 77 | ||
@@ -83,6 +86,10 @@ struct pdc_port_priv { | |||
83 | dma_addr_t pkt_dma; | 86 | dma_addr_t pkt_dma; |
84 | }; | 87 | }; |
85 | 88 | ||
89 | struct pdc_host_priv { | ||
90 | int hotplug_offset; | ||
91 | }; | ||
92 | |||
86 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); | 93 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); |
87 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 94 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
88 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 95 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
@@ -97,6 +104,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | |||
97 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 104 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); |
98 | static void pdc_irq_clear(struct ata_port *ap); | 105 | static void pdc_irq_clear(struct ata_port *ap); |
99 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); | 106 | static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); |
107 | static void pdc_host_stop(struct ata_host_set *host_set); | ||
100 | 108 | ||
101 | 109 | ||
102 | static struct scsi_host_template pdc_ata_sht = { | 110 | static struct scsi_host_template pdc_ata_sht = { |
@@ -138,7 +146,7 @@ static const struct ata_port_operations pdc_sata_ops = { | |||
138 | .scr_write = pdc_sata_scr_write, | 146 | .scr_write = pdc_sata_scr_write, |
139 | .port_start = pdc_port_start, | 147 | .port_start = pdc_port_start, |
140 | .port_stop = pdc_port_stop, | 148 | .port_stop = pdc_port_stop, |
141 | .host_stop = ata_pci_host_stop, | 149 | .host_stop = pdc_host_stop, |
142 | }; | 150 | }; |
143 | 151 | ||
144 | static const struct ata_port_operations pdc_pata_ops = { | 152 | static const struct ata_port_operations pdc_pata_ops = { |
@@ -159,7 +167,7 @@ static const struct ata_port_operations pdc_pata_ops = { | |||
159 | 167 | ||
160 | .port_start = pdc_port_start, | 168 | .port_start = pdc_port_start, |
161 | .port_stop = pdc_port_stop, | 169 | .port_stop = pdc_port_stop, |
162 | .host_stop = ata_pci_host_stop, | 170 | .host_stop = pdc_host_stop, |
163 | }; | 171 | }; |
164 | 172 | ||
165 | static const struct ata_port_info pdc_port_info[] = { | 173 | static const struct ata_port_info pdc_port_info[] = { |
@@ -202,6 +210,26 @@ static const struct ata_port_info pdc_port_info[] = { | |||
202 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 210 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
203 | .port_ops = &pdc_sata_ops, | 211 | .port_ops = &pdc_sata_ops, |
204 | }, | 212 | }, |
213 | |||
214 | /* board_2057x */ | ||
215 | { | ||
216 | .sht = &pdc_ata_sht, | ||
217 | .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, | ||
218 | .pio_mask = 0x1f, /* pio0-4 */ | ||
219 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
220 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
221 | .port_ops = &pdc_sata_ops, | ||
222 | }, | ||
223 | |||
224 | /* board_40518 */ | ||
225 | { | ||
226 | .sht = &pdc_ata_sht, | ||
227 | .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, | ||
228 | .pio_mask = 0x1f, /* pio0-4 */ | ||
229 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
230 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
231 | .port_ops = &pdc_sata_ops, | ||
232 | }, | ||
205 | }; | 233 | }; |
206 | 234 | ||
207 | static const struct pci_device_id pdc_ata_pci_tbl[] = { | 235 | static const struct pci_device_id pdc_ata_pci_tbl[] = { |
@@ -218,9 +246,9 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { | |||
218 | { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 246 | { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
219 | board_2037x }, | 247 | board_2037x }, |
220 | { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 248 | { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
221 | board_2037x }, | 249 | board_2057x }, |
222 | { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 250 | { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
223 | board_2037x }, | 251 | board_2057x }, |
224 | { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 252 | { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
225 | board_2037x }, | 253 | board_2037x }, |
226 | 254 | ||
@@ -233,7 +261,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { | |||
233 | { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 261 | { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
234 | board_20319 }, | 262 | board_20319 }, |
235 | { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 263 | { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
236 | board_20319 }, | 264 | board_40518 }, |
237 | 265 | ||
238 | { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 266 | { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
239 | board_20619 }, | 267 | board_20619 }, |
@@ -262,12 +290,11 @@ static int pdc_port_start(struct ata_port *ap) | |||
262 | if (rc) | 290 | if (rc) |
263 | return rc; | 291 | return rc; |
264 | 292 | ||
265 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | 293 | pp = kzalloc(sizeof(*pp), GFP_KERNEL); |
266 | if (!pp) { | 294 | if (!pp) { |
267 | rc = -ENOMEM; | 295 | rc = -ENOMEM; |
268 | goto err_out; | 296 | goto err_out; |
269 | } | 297 | } |
270 | memset(pp, 0, sizeof(*pp)); | ||
271 | 298 | ||
272 | pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL); | 299 | pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL); |
273 | if (!pp->pkt) { | 300 | if (!pp->pkt) { |
@@ -299,6 +326,16 @@ static void pdc_port_stop(struct ata_port *ap) | |||
299 | } | 326 | } |
300 | 327 | ||
301 | 328 | ||
329 | static void pdc_host_stop(struct ata_host_set *host_set) | ||
330 | { | ||
331 | struct pdc_host_priv *hp = host_set->private_data; | ||
332 | |||
333 | ata_pci_host_stop(host_set); | ||
334 | |||
335 | kfree(hp); | ||
336 | } | ||
337 | |||
338 | |||
302 | static void pdc_reset_port(struct ata_port *ap) | 339 | static void pdc_reset_port(struct ata_port *ap) |
303 | { | 340 | { |
304 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT; | 341 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT; |
@@ -488,14 +525,15 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r | |||
488 | VPRINTK("QUICK EXIT 2\n"); | 525 | VPRINTK("QUICK EXIT 2\n"); |
489 | return IRQ_NONE; | 526 | return IRQ_NONE; |
490 | } | 527 | } |
528 | |||
529 | spin_lock(&host_set->lock); | ||
530 | |||
491 | mask &= 0xffff; /* only 16 tags possible */ | 531 | mask &= 0xffff; /* only 16 tags possible */ |
492 | if (!mask) { | 532 | if (!mask) { |
493 | VPRINTK("QUICK EXIT 3\n"); | 533 | VPRINTK("QUICK EXIT 3\n"); |
494 | return IRQ_NONE; | 534 | goto done_irq; |
495 | } | 535 | } |
496 | 536 | ||
497 | spin_lock(&host_set->lock); | ||
498 | |||
499 | writel(mask, mmio_base + PDC_INT_SEQMASK); | 537 | writel(mask, mmio_base + PDC_INT_SEQMASK); |
500 | 538 | ||
501 | for (i = 0; i < host_set->n_ports; i++) { | 539 | for (i = 0; i < host_set->n_ports; i++) { |
@@ -512,10 +550,10 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r | |||
512 | } | 550 | } |
513 | } | 551 | } |
514 | 552 | ||
515 | spin_unlock(&host_set->lock); | ||
516 | |||
517 | VPRINTK("EXIT\n"); | 553 | VPRINTK("EXIT\n"); |
518 | 554 | ||
555 | done_irq: | ||
556 | spin_unlock(&host_set->lock); | ||
519 | return IRQ_RETVAL(handled); | 557 | return IRQ_RETVAL(handled); |
520 | } | 558 | } |
521 | 559 | ||
@@ -593,6 +631,8 @@ static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base) | |||
593 | static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | 631 | static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) |
594 | { | 632 | { |
595 | void __iomem *mmio = pe->mmio_base; | 633 | void __iomem *mmio = pe->mmio_base; |
634 | struct pdc_host_priv *hp = pe->private_data; | ||
635 | int hotplug_offset = hp->hotplug_offset; | ||
596 | u32 tmp; | 636 | u32 tmp; |
597 | 637 | ||
598 | /* | 638 | /* |
@@ -607,12 +647,12 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | |||
607 | writel(tmp, mmio + PDC_FLASH_CTL); | 647 | writel(tmp, mmio + PDC_FLASH_CTL); |
608 | 648 | ||
609 | /* clear plug/unplug flags for all ports */ | 649 | /* clear plug/unplug flags for all ports */ |
610 | tmp = readl(mmio + PDC_SATA_PLUG_CSR); | 650 | tmp = readl(mmio + hotplug_offset); |
611 | writel(tmp | 0xff, mmio + PDC_SATA_PLUG_CSR); | 651 | writel(tmp | 0xff, mmio + hotplug_offset); |
612 | 652 | ||
613 | /* mask plug/unplug ints */ | 653 | /* mask plug/unplug ints */ |
614 | tmp = readl(mmio + PDC_SATA_PLUG_CSR); | 654 | tmp = readl(mmio + hotplug_offset); |
615 | writel(tmp | 0xff0000, mmio + PDC_SATA_PLUG_CSR); | 655 | writel(tmp | 0xff0000, mmio + hotplug_offset); |
616 | 656 | ||
617 | /* reduce TBG clock to 133 Mhz. */ | 657 | /* reduce TBG clock to 133 Mhz. */ |
618 | tmp = readl(mmio + PDC_TBG_MODE); | 658 | tmp = readl(mmio + PDC_TBG_MODE); |
@@ -634,6 +674,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
634 | { | 674 | { |
635 | static int printed_version; | 675 | static int printed_version; |
636 | struct ata_probe_ent *probe_ent = NULL; | 676 | struct ata_probe_ent *probe_ent = NULL; |
677 | struct pdc_host_priv *hp; | ||
637 | unsigned long base; | 678 | unsigned long base; |
638 | void __iomem *mmio_base; | 679 | void __iomem *mmio_base; |
639 | unsigned int board_idx = (unsigned int) ent->driver_data; | 680 | unsigned int board_idx = (unsigned int) ent->driver_data; |
@@ -664,13 +705,12 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
664 | if (rc) | 705 | if (rc) |
665 | goto err_out_regions; | 706 | goto err_out_regions; |
666 | 707 | ||
667 | probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); | 708 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); |
668 | if (probe_ent == NULL) { | 709 | if (probe_ent == NULL) { |
669 | rc = -ENOMEM; | 710 | rc = -ENOMEM; |
670 | goto err_out_regions; | 711 | goto err_out_regions; |
671 | } | 712 | } |
672 | 713 | ||
673 | memset(probe_ent, 0, sizeof(*probe_ent)); | ||
674 | probe_ent->dev = pci_dev_to_dev(pdev); | 714 | probe_ent->dev = pci_dev_to_dev(pdev); |
675 | INIT_LIST_HEAD(&probe_ent->node); | 715 | INIT_LIST_HEAD(&probe_ent->node); |
676 | 716 | ||
@@ -681,6 +721,16 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
681 | } | 721 | } |
682 | base = (unsigned long) mmio_base; | 722 | base = (unsigned long) mmio_base; |
683 | 723 | ||
724 | hp = kzalloc(sizeof(*hp), GFP_KERNEL); | ||
725 | if (hp == NULL) { | ||
726 | rc = -ENOMEM; | ||
727 | goto err_out_free_ent; | ||
728 | } | ||
729 | |||
730 | /* Set default hotplug offset */ | ||
731 | hp->hotplug_offset = PDC_SATA_PLUG_CSR; | ||
732 | probe_ent->private_data = hp; | ||
733 | |||
684 | probe_ent->sht = pdc_port_info[board_idx].sht; | 734 | probe_ent->sht = pdc_port_info[board_idx].sht; |
685 | probe_ent->host_flags = pdc_port_info[board_idx].host_flags; | 735 | probe_ent->host_flags = pdc_port_info[board_idx].host_flags; |
686 | probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask; | 736 | probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask; |
@@ -700,6 +750,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
700 | 750 | ||
701 | /* notice 4-port boards */ | 751 | /* notice 4-port boards */ |
702 | switch (board_idx) { | 752 | switch (board_idx) { |
753 | case board_40518: | ||
754 | /* Override hotplug offset for SATAII150 */ | ||
755 | hp->hotplug_offset = PDC2_SATA_PLUG_CSR; | ||
756 | /* Fall through */ | ||
703 | case board_20319: | 757 | case board_20319: |
704 | probe_ent->n_ports = 4; | 758 | probe_ent->n_ports = 4; |
705 | 759 | ||
@@ -709,6 +763,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
709 | probe_ent->port[2].scr_addr = base + 0x600; | 763 | probe_ent->port[2].scr_addr = base + 0x600; |
710 | probe_ent->port[3].scr_addr = base + 0x700; | 764 | probe_ent->port[3].scr_addr = base + 0x700; |
711 | break; | 765 | break; |
766 | case board_2057x: | ||
767 | /* Override hotplug offset for SATAII150 */ | ||
768 | hp->hotplug_offset = PDC2_SATA_PLUG_CSR; | ||
769 | /* Fall through */ | ||
712 | case board_2037x: | 770 | case board_2037x: |
713 | probe_ent->n_ports = 2; | 771 | probe_ent->n_ports = 2; |
714 | break; | 772 | break; |
@@ -734,8 +792,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
734 | /* initialize adapter */ | 792 | /* initialize adapter */ |
735 | pdc_host_init(board_idx, probe_ent); | 793 | pdc_host_init(board_idx, probe_ent); |
736 | 794 | ||
737 | /* FIXME: check ata_device_add return value */ | 795 | /* FIXME: Need any other frees than hp? */ |
738 | ata_device_add(probe_ent); | 796 | if (!ata_device_add(probe_ent)) |
797 | kfree(hp); | ||
798 | |||
739 | kfree(probe_ent); | 799 | kfree(probe_ent); |
740 | 800 | ||
741 | return 0; | 801 | return 0; |