diff options
Diffstat (limited to 'drivers/scsi/sata_sil24.c')
-rw-r--r-- | drivers/scsi/sata_sil24.c | 246 |
1 files changed, 165 insertions, 81 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 646756abb10e..e9fd869140c5 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -86,6 +86,13 @@ enum { | |||
86 | /* HOST_SLOT_STAT bits */ | 86 | /* HOST_SLOT_STAT bits */ |
87 | HOST_SSTAT_ATTN = (1 << 31), | 87 | HOST_SSTAT_ATTN = (1 << 31), |
88 | 88 | ||
89 | /* HOST_CTRL bits */ | ||
90 | HOST_CTRL_M66EN = (1 << 16), /* M66EN PCI bus signal */ | ||
91 | HOST_CTRL_TRDY = (1 << 17), /* latched PCI TRDY */ | ||
92 | HOST_CTRL_STOP = (1 << 18), /* latched PCI STOP */ | ||
93 | HOST_CTRL_DEVSEL = (1 << 19), /* latched PCI DEVSEL */ | ||
94 | HOST_CTRL_REQ64 = (1 << 20), /* latched PCI REQ64 */ | ||
95 | |||
89 | /* | 96 | /* |
90 | * Port registers | 97 | * Port registers |
91 | * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2) | 98 | * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2) |
@@ -142,8 +149,12 @@ enum { | |||
142 | PORT_IRQ_PWR_CHG = (1 << 3), /* power management change */ | 149 | PORT_IRQ_PWR_CHG = (1 << 3), /* power management change */ |
143 | PORT_IRQ_PHYRDY_CHG = (1 << 4), /* PHY ready change */ | 150 | PORT_IRQ_PHYRDY_CHG = (1 << 4), /* PHY ready change */ |
144 | PORT_IRQ_COMWAKE = (1 << 5), /* COMWAKE received */ | 151 | PORT_IRQ_COMWAKE = (1 << 5), /* COMWAKE received */ |
145 | PORT_IRQ_UNK_FIS = (1 << 6), /* Unknown FIS received */ | 152 | PORT_IRQ_UNK_FIS = (1 << 6), /* unknown FIS received */ |
146 | PORT_IRQ_SDB_FIS = (1 << 11), /* SDB FIS received */ | 153 | PORT_IRQ_DEV_XCHG = (1 << 7), /* device exchanged */ |
154 | PORT_IRQ_8B10B = (1 << 8), /* 8b/10b decode error threshold */ | ||
155 | PORT_IRQ_CRC = (1 << 9), /* CRC error threshold */ | ||
156 | PORT_IRQ_HANDSHAKE = (1 << 10), /* handshake error threshold */ | ||
157 | PORT_IRQ_SDB_NOTIFY = (1 << 11), /* SDB notify received */ | ||
147 | 158 | ||
148 | /* bits[27:16] are unmasked (raw) */ | 159 | /* bits[27:16] are unmasked (raw) */ |
149 | PORT_IRQ_RAW_SHIFT = 16, | 160 | PORT_IRQ_RAW_SHIFT = 16, |
@@ -174,7 +185,7 @@ enum { | |||
174 | PORT_CERR_CMD_PCIPERR = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */ | 185 | PORT_CERR_CMD_PCIPERR = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */ |
175 | PORT_CERR_XFR_UNDEF = 32, /* PSD ecode 00 - undefined */ | 186 | PORT_CERR_XFR_UNDEF = 32, /* PSD ecode 00 - undefined */ |
176 | PORT_CERR_XFR_TGTABRT = 33, /* PSD ecode 01 - target abort */ | 187 | PORT_CERR_XFR_TGTABRT = 33, /* PSD ecode 01 - target abort */ |
177 | PORT_CERR_XFR_MSGABRT = 34, /* PSD ecode 10 - master abort */ | 188 | PORT_CERR_XFR_MSTABRT = 34, /* PSD ecode 10 - master abort */ |
178 | PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */ | 189 | PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */ |
179 | PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */ | 190 | PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */ |
180 | 191 | ||
@@ -207,6 +218,11 @@ enum { | |||
207 | BID_SIL3132 = 1, | 218 | BID_SIL3132 = 1, |
208 | BID_SIL3131 = 2, | 219 | BID_SIL3131 = 2, |
209 | 220 | ||
221 | /* host flags */ | ||
222 | SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
223 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, | ||
224 | SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ | ||
225 | |||
210 | IRQ_STAT_4PORTS = 0xf, | 226 | IRQ_STAT_4PORTS = 0xf, |
211 | }; | 227 | }; |
212 | 228 | ||
@@ -281,7 +297,6 @@ static struct scsi_host_template sil24_sht = { | |||
281 | .name = DRV_NAME, | 297 | .name = DRV_NAME, |
282 | .ioctl = ata_scsi_ioctl, | 298 | .ioctl = ata_scsi_ioctl, |
283 | .queuecommand = ata_scsi_queuecmd, | 299 | .queuecommand = ata_scsi_queuecmd, |
284 | .eh_strategy_handler = ata_scsi_error, | ||
285 | .can_queue = ATA_DEF_QUEUE, | 300 | .can_queue = ATA_DEF_QUEUE, |
286 | .this_id = ATA_SHT_THIS_ID, | 301 | .this_id = ATA_SHT_THIS_ID, |
287 | .sg_tablesize = LIBATA_MAX_PRD, | 302 | .sg_tablesize = LIBATA_MAX_PRD, |
@@ -334,9 +349,8 @@ static struct ata_port_info sil24_port_info[] = { | |||
334 | /* sil_3124 */ | 349 | /* sil_3124 */ |
335 | { | 350 | { |
336 | .sht = &sil24_sht, | 351 | .sht = &sil24_sht, |
337 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 352 | .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | |
338 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 353 | SIL24_FLAG_PCIX_IRQ_WOC, |
339 | SIL24_NPORTS2FLAG(4), | ||
340 | .pio_mask = 0x1f, /* pio0-4 */ | 354 | .pio_mask = 0x1f, /* pio0-4 */ |
341 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 355 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
342 | .udma_mask = 0x3f, /* udma0-5 */ | 356 | .udma_mask = 0x3f, /* udma0-5 */ |
@@ -345,9 +359,7 @@ static struct ata_port_info sil24_port_info[] = { | |||
345 | /* sil_3132 */ | 359 | /* sil_3132 */ |
346 | { | 360 | { |
347 | .sht = &sil24_sht, | 361 | .sht = &sil24_sht, |
348 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 362 | .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), |
349 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | ||
350 | SIL24_NPORTS2FLAG(2), | ||
351 | .pio_mask = 0x1f, /* pio0-4 */ | 363 | .pio_mask = 0x1f, /* pio0-4 */ |
352 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 364 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
353 | .udma_mask = 0x3f, /* udma0-5 */ | 365 | .udma_mask = 0x3f, /* udma0-5 */ |
@@ -356,9 +368,7 @@ static struct ata_port_info sil24_port_info[] = { | |||
356 | /* sil_3131/sil_3531 */ | 368 | /* sil_3131/sil_3531 */ |
357 | { | 369 | { |
358 | .sht = &sil24_sht, | 370 | .sht = &sil24_sht, |
359 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 371 | .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), |
360 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | ||
361 | SIL24_NPORTS2FLAG(1), | ||
362 | .pio_mask = 0x1f, /* pio0-4 */ | 372 | .pio_mask = 0x1f, /* pio0-4 */ |
363 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 373 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
364 | .udma_mask = 0x3f, /* udma0-5 */ | 374 | .udma_mask = 0x3f, /* udma0-5 */ |
@@ -427,15 +437,30 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
427 | *tf = pp->tf; | 437 | *tf = pp->tf; |
428 | } | 438 | } |
429 | 439 | ||
430 | static int sil24_softreset(struct ata_port *ap, int verbose, | 440 | static int sil24_init_port(struct ata_port *ap) |
431 | unsigned int *class) | 441 | { |
442 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; | ||
443 | u32 tmp; | ||
444 | |||
445 | writel(PORT_CS_INIT, port + PORT_CTRL_STAT); | ||
446 | ata_wait_register(port + PORT_CTRL_STAT, | ||
447 | PORT_CS_INIT, PORT_CS_INIT, 10, 100); | ||
448 | tmp = ata_wait_register(port + PORT_CTRL_STAT, | ||
449 | PORT_CS_RDY, 0, 10, 100); | ||
450 | |||
451 | if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY) | ||
452 | return -EIO; | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int sil24_softreset(struct ata_port *ap, unsigned int *class) | ||
432 | { | 457 | { |
433 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; | 458 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; |
434 | struct sil24_port_priv *pp = ap->private_data; | 459 | struct sil24_port_priv *pp = ap->private_data; |
435 | struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; | 460 | struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; |
436 | dma_addr_t paddr = pp->cmd_block_dma; | 461 | dma_addr_t paddr = pp->cmd_block_dma; |
437 | unsigned long timeout = jiffies + ATA_TMOUT_BOOT * HZ; | 462 | u32 mask, irq_enable, irq_stat; |
438 | u32 irq_enable, irq_stat; | 463 | const char *reason; |
439 | 464 | ||
440 | DPRINTK("ENTER\n"); | 465 | DPRINTK("ENTER\n"); |
441 | 466 | ||
@@ -449,34 +474,35 @@ static int sil24_softreset(struct ata_port *ap, int verbose, | |||
449 | irq_enable = readl(port + PORT_IRQ_ENABLE_SET); | 474 | irq_enable = readl(port + PORT_IRQ_ENABLE_SET); |
450 | writel(irq_enable, port + PORT_IRQ_ENABLE_CLR); | 475 | writel(irq_enable, port + PORT_IRQ_ENABLE_CLR); |
451 | 476 | ||
452 | /* | 477 | /* put the port into known state */ |
453 | * XXX: Not sure whether the following sleep is needed or not. | 478 | if (sil24_init_port(ap)) { |
454 | * The original driver had it. So.... | 479 | reason ="port not ready"; |
455 | */ | 480 | goto err; |
456 | msleep(10); | 481 | } |
457 | 482 | ||
458 | prb->ctrl = PRB_CTRL_SRST; | 483 | /* do SRST */ |
484 | prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); | ||
459 | prb->fis[1] = 0; /* no PM yet */ | 485 | prb->fis[1] = 0; /* no PM yet */ |
460 | 486 | ||
461 | writel((u32)paddr, port + PORT_CMD_ACTIVATE); | 487 | writel((u32)paddr, port + PORT_CMD_ACTIVATE); |
488 | writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); | ||
462 | 489 | ||
463 | do { | 490 | mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; |
464 | irq_stat = readl(port + PORT_IRQ_STAT); | 491 | irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0, |
465 | writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ | 492 | 100, ATA_TMOUT_BOOT / HZ * 1000); |
466 | |||
467 | irq_stat >>= PORT_IRQ_RAW_SHIFT; | ||
468 | if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR)) | ||
469 | break; | ||
470 | 493 | ||
471 | msleep(100); | 494 | writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */ |
472 | } while (time_before(jiffies, timeout)); | 495 | irq_stat >>= PORT_IRQ_RAW_SHIFT; |
473 | 496 | ||
474 | /* restore IRQs */ | 497 | /* restore IRQs */ |
475 | writel(irq_enable, port + PORT_IRQ_ENABLE_SET); | 498 | writel(irq_enable, port + PORT_IRQ_ENABLE_SET); |
476 | 499 | ||
477 | if (!(irq_stat & PORT_IRQ_COMPLETE)) { | 500 | if (!(irq_stat & PORT_IRQ_COMPLETE)) { |
478 | DPRINTK("EXIT, srst failed\n"); | 501 | if (irq_stat & PORT_IRQ_ERROR) |
479 | return -EIO; | 502 | reason = "SRST command error"; |
503 | else | ||
504 | reason = "timeout"; | ||
505 | goto err; | ||
480 | } | 506 | } |
481 | 507 | ||
482 | sil24_update_tf(ap); | 508 | sil24_update_tf(ap); |
@@ -488,15 +514,55 @@ static int sil24_softreset(struct ata_port *ap, int verbose, | |||
488 | out: | 514 | out: |
489 | DPRINTK("EXIT, class=%u\n", *class); | 515 | DPRINTK("EXIT, class=%u\n", *class); |
490 | return 0; | 516 | return 0; |
517 | |||
518 | err: | ||
519 | printk(KERN_ERR "ata%u: softreset failed (%s)\n", ap->id, reason); | ||
520 | return -EIO; | ||
491 | } | 521 | } |
492 | 522 | ||
493 | static int sil24_hardreset(struct ata_port *ap, int verbose, | 523 | static int sil24_hardreset(struct ata_port *ap, unsigned int *class) |
494 | unsigned int *class) | ||
495 | { | 524 | { |
496 | unsigned int dummy_class; | 525 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; |
526 | const char *reason; | ||
527 | int tout_msec; | ||
528 | u32 tmp; | ||
529 | |||
530 | /* sil24 does the right thing(tm) without any protection */ | ||
531 | ata_set_sata_spd(ap); | ||
532 | |||
533 | tout_msec = 100; | ||
534 | if (sata_dev_present(ap)) | ||
535 | tout_msec = 5000; | ||
497 | 536 | ||
498 | /* sil24 doesn't report device signature after hard reset */ | 537 | writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT); |
499 | return sata_std_hardreset(ap, verbose, &dummy_class); | 538 | tmp = ata_wait_register(port + PORT_CTRL_STAT, |
539 | PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec); | ||
540 | |||
541 | /* SStatus oscillates between zero and valid status for short | ||
542 | * duration after DEV_RST, give it time to settle. | ||
543 | */ | ||
544 | msleep(100); | ||
545 | |||
546 | if (tmp & PORT_CS_DEV_RST) { | ||
547 | if (!sata_dev_present(ap)) | ||
548 | return 0; | ||
549 | reason = "link not ready"; | ||
550 | goto err; | ||
551 | } | ||
552 | |||
553 | if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { | ||
554 | reason = "device not ready"; | ||
555 | goto err; | ||
556 | } | ||
557 | |||
558 | /* sil24 doesn't report device class code after hardreset, | ||
559 | * leave *class alone. | ||
560 | */ | ||
561 | return 0; | ||
562 | |||
563 | err: | ||
564 | printk(KERN_ERR "ata%u: hardreset failed (%s)\n", ap->id, reason); | ||
565 | return -EIO; | ||
500 | } | 566 | } |
501 | 567 | ||
502 | static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) | 568 | static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) |
@@ -532,6 +598,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) | |||
532 | union sil24_cmd_block *cb = pp->cmd_block + qc->tag; | 598 | union sil24_cmd_block *cb = pp->cmd_block + qc->tag; |
533 | struct sil24_prb *prb; | 599 | struct sil24_prb *prb; |
534 | struct sil24_sge *sge; | 600 | struct sil24_sge *sge; |
601 | u16 ctrl = 0; | ||
535 | 602 | ||
536 | switch (qc->tf.protocol) { | 603 | switch (qc->tf.protocol) { |
537 | case ATA_PROT_PIO: | 604 | case ATA_PROT_PIO: |
@@ -539,7 +606,6 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) | |||
539 | case ATA_PROT_NODATA: | 606 | case ATA_PROT_NODATA: |
540 | prb = &cb->ata.prb; | 607 | prb = &cb->ata.prb; |
541 | sge = cb->ata.sge; | 608 | sge = cb->ata.sge; |
542 | prb->ctrl = 0; | ||
543 | break; | 609 | break; |
544 | 610 | ||
545 | case ATA_PROT_ATAPI: | 611 | case ATA_PROT_ATAPI: |
@@ -552,12 +618,10 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) | |||
552 | 618 | ||
553 | if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { | 619 | if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { |
554 | if (qc->tf.flags & ATA_TFLAG_WRITE) | 620 | if (qc->tf.flags & ATA_TFLAG_WRITE) |
555 | prb->ctrl = PRB_CTRL_PACKET_WRITE; | 621 | ctrl = PRB_CTRL_PACKET_WRITE; |
556 | else | 622 | else |
557 | prb->ctrl = PRB_CTRL_PACKET_READ; | 623 | ctrl = PRB_CTRL_PACKET_READ; |
558 | } else | 624 | } |
559 | prb->ctrl = 0; | ||
560 | |||
561 | break; | 625 | break; |
562 | 626 | ||
563 | default: | 627 | default: |
@@ -566,6 +630,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) | |||
566 | BUG(); | 630 | BUG(); |
567 | } | 631 | } |
568 | 632 | ||
633 | prb->ctrl = cpu_to_le16(ctrl); | ||
569 | ata_tf_to_fis(&qc->tf, prb->fis, 0); | 634 | ata_tf_to_fis(&qc->tf, prb->fis, 0); |
570 | 635 | ||
571 | if (qc->flags & ATA_QCFLAG_DMAMAP) | 636 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
@@ -580,6 +645,8 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) | |||
580 | dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block); | 645 | dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block); |
581 | 646 | ||
582 | writel((u32)paddr, port + PORT_CMD_ACTIVATE); | 647 | writel((u32)paddr, port + PORT_CMD_ACTIVATE); |
648 | writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); | ||
649 | |||
583 | return 0; | 650 | return 0; |
584 | } | 651 | } |
585 | 652 | ||
@@ -728,6 +795,10 @@ static inline void sil24_host_intr(struct ata_port *ap) | |||
728 | slot_stat = readl(port + PORT_SLOT_STAT); | 795 | slot_stat = readl(port + PORT_SLOT_STAT); |
729 | if (!(slot_stat & HOST_SSTAT_ATTN)) { | 796 | if (!(slot_stat & HOST_SSTAT_ATTN)) { |
730 | struct sil24_port_priv *pp = ap->private_data; | 797 | struct sil24_port_priv *pp = ap->private_data; |
798 | |||
799 | if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) | ||
800 | writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT); | ||
801 | |||
731 | /* | 802 | /* |
732 | * !HOST_SSAT_ATTN guarantees successful completion, | 803 | * !HOST_SSAT_ATTN guarantees successful completion, |
733 | * so reading back tf registers is unnecessary for | 804 | * so reading back tf registers is unnecessary for |
@@ -859,6 +930,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
859 | void __iomem *host_base = NULL; | 930 | void __iomem *host_base = NULL; |
860 | void __iomem *port_base = NULL; | 931 | void __iomem *port_base = NULL; |
861 | int i, rc; | 932 | int i, rc; |
933 | u32 tmp; | ||
862 | 934 | ||
863 | if (!printed_version++) | 935 | if (!printed_version++) |
864 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 936 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
@@ -911,35 +983,51 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
911 | /* | 983 | /* |
912 | * Configure the device | 984 | * Configure the device |
913 | */ | 985 | */ |
914 | /* | 986 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
915 | * FIXME: This device is certainly 64-bit capable. We just | 987 | rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); |
916 | * don't know how to use it. After fixing 32bit activation in | 988 | if (rc) { |
917 | * this function, enable 64bit masks here. | 989 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); |
918 | */ | 990 | if (rc) { |
919 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 991 | dev_printk(KERN_ERR, &pdev->dev, |
920 | if (rc) { | 992 | "64-bit DMA enable failed\n"); |
921 | dev_printk(KERN_ERR, &pdev->dev, | 993 | goto out_free; |
922 | "32-bit DMA enable failed\n"); | 994 | } |
923 | goto out_free; | 995 | } |
924 | } | 996 | } else { |
925 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 997 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
926 | if (rc) { | 998 | if (rc) { |
927 | dev_printk(KERN_ERR, &pdev->dev, | 999 | dev_printk(KERN_ERR, &pdev->dev, |
928 | "32-bit consistent DMA enable failed\n"); | 1000 | "32-bit DMA enable failed\n"); |
929 | goto out_free; | 1001 | goto out_free; |
1002 | } | ||
1003 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
1004 | if (rc) { | ||
1005 | dev_printk(KERN_ERR, &pdev->dev, | ||
1006 | "32-bit consistent DMA enable failed\n"); | ||
1007 | goto out_free; | ||
1008 | } | ||
930 | } | 1009 | } |
931 | 1010 | ||
932 | /* GPIO off */ | 1011 | /* GPIO off */ |
933 | writel(0, host_base + HOST_FLASH_CMD); | 1012 | writel(0, host_base + HOST_FLASH_CMD); |
934 | 1013 | ||
935 | /* Mask interrupts during initialization */ | 1014 | /* Apply workaround for completion IRQ loss on PCI-X errata */ |
1015 | if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) { | ||
1016 | tmp = readl(host_base + HOST_CTRL); | ||
1017 | if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL)) | ||
1018 | dev_printk(KERN_INFO, &pdev->dev, | ||
1019 | "Applying completion IRQ loss on PCI-X " | ||
1020 | "errata fix\n"); | ||
1021 | else | ||
1022 | probe_ent->host_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC; | ||
1023 | } | ||
1024 | |||
1025 | /* clear global reset & mask interrupts during initialization */ | ||
936 | writel(0, host_base + HOST_CTRL); | 1026 | writel(0, host_base + HOST_CTRL); |
937 | 1027 | ||
938 | for (i = 0; i < probe_ent->n_ports; i++) { | 1028 | for (i = 0; i < probe_ent->n_ports; i++) { |
939 | void __iomem *port = port_base + i * PORT_REGS_SIZE; | 1029 | void __iomem *port = port_base + i * PORT_REGS_SIZE; |
940 | unsigned long portu = (unsigned long)port; | 1030 | unsigned long portu = (unsigned long)port; |
941 | u32 tmp; | ||
942 | int cnt; | ||
943 | 1031 | ||
944 | probe_ent->port[i].cmd_addr = portu + PORT_PRB; | 1032 | probe_ent->port[i].cmd_addr = portu + PORT_PRB; |
945 | probe_ent->port[i].scr_addr = portu + PORT_SCONTROL; | 1033 | probe_ent->port[i].scr_addr = portu + PORT_SCONTROL; |
@@ -953,18 +1041,20 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
953 | tmp = readl(port + PORT_CTRL_STAT); | 1041 | tmp = readl(port + PORT_CTRL_STAT); |
954 | if (tmp & PORT_CS_PORT_RST) { | 1042 | if (tmp & PORT_CS_PORT_RST) { |
955 | writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR); | 1043 | writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR); |
956 | readl(port + PORT_CTRL_STAT); /* sync */ | 1044 | tmp = ata_wait_register(port + PORT_CTRL_STAT, |
957 | for (cnt = 0; cnt < 10; cnt++) { | 1045 | PORT_CS_PORT_RST, |
958 | msleep(10); | 1046 | PORT_CS_PORT_RST, 10, 100); |
959 | tmp = readl(port + PORT_CTRL_STAT); | ||
960 | if (!(tmp & PORT_CS_PORT_RST)) | ||
961 | break; | ||
962 | } | ||
963 | if (tmp & PORT_CS_PORT_RST) | 1047 | if (tmp & PORT_CS_PORT_RST) |
964 | dev_printk(KERN_ERR, &pdev->dev, | 1048 | dev_printk(KERN_ERR, &pdev->dev, |
965 | "failed to clear port RST\n"); | 1049 | "failed to clear port RST\n"); |
966 | } | 1050 | } |
967 | 1051 | ||
1052 | /* Configure IRQ WoC */ | ||
1053 | if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) | ||
1054 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT); | ||
1055 | else | ||
1056 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); | ||
1057 | |||
968 | /* Zero error counters. */ | 1058 | /* Zero error counters. */ |
969 | writel(0x8000, port + PORT_DECODE_ERR_THRESH); | 1059 | writel(0x8000, port + PORT_DECODE_ERR_THRESH); |
970 | writel(0x8000, port + PORT_CRC_ERR_THRESH); | 1060 | writel(0x8000, port + PORT_CRC_ERR_THRESH); |
@@ -973,14 +1063,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
973 | writel(0x0000, port + PORT_CRC_ERR_CNT); | 1063 | writel(0x0000, port + PORT_CRC_ERR_CNT); |
974 | writel(0x0000, port + PORT_HSHK_ERR_CNT); | 1064 | writel(0x0000, port + PORT_HSHK_ERR_CNT); |
975 | 1065 | ||
976 | /* FIXME: 32bit activation? */ | 1066 | /* Always use 64bit activation */ |
977 | writel(0, port + PORT_ACTIVATE_UPPER_ADDR); | 1067 | writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR); |
978 | writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT); | ||
979 | 1068 | ||
980 | /* Configure interrupts */ | 1069 | /* Configure interrupts */ |
981 | writel(0xffff, port + PORT_IRQ_ENABLE_CLR); | 1070 | writel(0xffff, port + PORT_IRQ_ENABLE_CLR); |
982 | writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS, | 1071 | writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | |
983 | port + PORT_IRQ_ENABLE_SET); | 1072 | PORT_IRQ_SDB_NOTIFY, port + PORT_IRQ_ENABLE_SET); |
984 | 1073 | ||
985 | /* Clear interrupts */ | 1074 | /* Clear interrupts */ |
986 | writel(0x0fff0fff, port + PORT_IRQ_STAT); | 1075 | writel(0x0fff0fff, port + PORT_IRQ_STAT); |
@@ -988,11 +1077,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
988 | 1077 | ||
989 | /* Clear port multiplier enable and resume bits */ | 1078 | /* Clear port multiplier enable and resume bits */ |
990 | writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR); | 1079 | writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR); |
991 | |||
992 | /* Reset itself */ | ||
993 | if (__sil24_reset_controller(port)) | ||
994 | dev_printk(KERN_ERR, &pdev->dev, | ||
995 | "failed to reset controller\n"); | ||
996 | } | 1080 | } |
997 | 1081 | ||
998 | /* Turn on interrupts */ | 1082 | /* Turn on interrupts */ |