diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 229 |
1 files changed, 175 insertions, 54 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index bddb14e91d3c..f36da488a2c1 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -53,6 +53,7 @@ | |||
53 | 53 | ||
54 | enum { | 54 | enum { |
55 | AHCI_PCI_BAR = 5, | 55 | AHCI_PCI_BAR = 5, |
56 | AHCI_MAX_PORTS = 32, | ||
56 | AHCI_MAX_SG = 168, /* hardware max is 64K */ | 57 | AHCI_MAX_SG = 168, /* hardware max is 64K */ |
57 | AHCI_DMA_BOUNDARY = 0xffffffff, | 58 | AHCI_DMA_BOUNDARY = 0xffffffff, |
58 | AHCI_USE_CLUSTERING = 0, | 59 | AHCI_USE_CLUSTERING = 0, |
@@ -77,8 +78,9 @@ enum { | |||
77 | RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ | 78 | RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ |
78 | 79 | ||
79 | board_ahci = 0, | 80 | board_ahci = 0, |
80 | board_ahci_vt8251 = 1, | 81 | board_ahci_pi = 1, |
81 | board_ahci_ign_iferr = 2, | 82 | board_ahci_vt8251 = 2, |
83 | board_ahci_ign_iferr = 3, | ||
82 | 84 | ||
83 | /* global controller registers */ | 85 | /* global controller registers */ |
84 | HOST_CAP = 0x00, /* host capabilities */ | 86 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -167,9 +169,9 @@ enum { | |||
167 | AHCI_FLAG_MSI = (1 << 0), | 169 | AHCI_FLAG_MSI = (1 << 0), |
168 | 170 | ||
169 | /* ap->flags bits */ | 171 | /* ap->flags bits */ |
170 | AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24), | 172 | AHCI_FLAG_NO_NCQ = (1 << 24), |
171 | AHCI_FLAG_NO_NCQ = (1 << 25), | 173 | AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */ |
172 | AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 26), /* ignore IRQ_IF_ERR */ | 174 | AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */ |
173 | }; | 175 | }; |
174 | 176 | ||
175 | struct ahci_cmd_hdr { | 177 | struct ahci_cmd_hdr { |
@@ -216,6 +218,7 @@ static u8 ahci_check_status(struct ata_port *ap); | |||
216 | static void ahci_freeze(struct ata_port *ap); | 218 | static void ahci_freeze(struct ata_port *ap); |
217 | static void ahci_thaw(struct ata_port *ap); | 219 | static void ahci_thaw(struct ata_port *ap); |
218 | static void ahci_error_handler(struct ata_port *ap); | 220 | static void ahci_error_handler(struct ata_port *ap); |
221 | static void ahci_vt8251_error_handler(struct ata_port *ap); | ||
219 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 222 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); |
220 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); | 223 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); |
221 | static int ahci_port_resume(struct ata_port *ap); | 224 | static int ahci_port_resume(struct ata_port *ap); |
@@ -275,6 +278,37 @@ static const struct ata_port_operations ahci_ops = { | |||
275 | .port_stop = ahci_port_stop, | 278 | .port_stop = ahci_port_stop, |
276 | }; | 279 | }; |
277 | 280 | ||
281 | static const struct ata_port_operations ahci_vt8251_ops = { | ||
282 | .port_disable = ata_port_disable, | ||
283 | |||
284 | .check_status = ahci_check_status, | ||
285 | .check_altstatus = ahci_check_status, | ||
286 | .dev_select = ata_noop_dev_select, | ||
287 | |||
288 | .tf_read = ahci_tf_read, | ||
289 | |||
290 | .qc_prep = ahci_qc_prep, | ||
291 | .qc_issue = ahci_qc_issue, | ||
292 | |||
293 | .irq_handler = ahci_interrupt, | ||
294 | .irq_clear = ahci_irq_clear, | ||
295 | |||
296 | .scr_read = ahci_scr_read, | ||
297 | .scr_write = ahci_scr_write, | ||
298 | |||
299 | .freeze = ahci_freeze, | ||
300 | .thaw = ahci_thaw, | ||
301 | |||
302 | .error_handler = ahci_vt8251_error_handler, | ||
303 | .post_internal_cmd = ahci_post_internal_cmd, | ||
304 | |||
305 | .port_suspend = ahci_port_suspend, | ||
306 | .port_resume = ahci_port_resume, | ||
307 | |||
308 | .port_start = ahci_port_start, | ||
309 | .port_stop = ahci_port_stop, | ||
310 | }; | ||
311 | |||
278 | static const struct ata_port_info ahci_port_info[] = { | 312 | static const struct ata_port_info ahci_port_info[] = { |
279 | /* board_ahci */ | 313 | /* board_ahci */ |
280 | { | 314 | { |
@@ -286,16 +320,26 @@ static const struct ata_port_info ahci_port_info[] = { | |||
286 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 320 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
287 | .port_ops = &ahci_ops, | 321 | .port_ops = &ahci_ops, |
288 | }, | 322 | }, |
323 | /* board_ahci_pi */ | ||
324 | { | ||
325 | .sht = &ahci_sht, | ||
326 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
327 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | ||
328 | ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI, | ||
329 | .pio_mask = 0x1f, /* pio0-4 */ | ||
330 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
331 | .port_ops = &ahci_ops, | ||
332 | }, | ||
289 | /* board_ahci_vt8251 */ | 333 | /* board_ahci_vt8251 */ |
290 | { | 334 | { |
291 | .sht = &ahci_sht, | 335 | .sht = &ahci_sht, |
292 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 336 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
293 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 337 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
294 | ATA_FLAG_SKIP_D2H_BSY | | 338 | ATA_FLAG_SKIP_D2H_BSY | |
295 | AHCI_FLAG_RESET_NEEDS_CLO | AHCI_FLAG_NO_NCQ, | 339 | ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ, |
296 | .pio_mask = 0x1f, /* pio0-4 */ | 340 | .pio_mask = 0x1f, /* pio0-4 */ |
297 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 341 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
298 | .port_ops = &ahci_ops, | 342 | .port_ops = &ahci_vt8251_ops, |
299 | }, | 343 | }, |
300 | /* board_ahci_ign_iferr */ | 344 | /* board_ahci_ign_iferr */ |
301 | { | 345 | { |
@@ -322,22 +366,22 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
322 | { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ | 366 | { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ |
323 | { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ | 367 | { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ |
324 | { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ | 368 | { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ |
325 | { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */ | 369 | { PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */ |
326 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */ | 370 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */ |
327 | { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ | 371 | { PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */ |
328 | { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ | 372 | { PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */ |
329 | { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ | 373 | { PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */ |
330 | { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */ | 374 | { PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */ |
331 | { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */ | 375 | { PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */ |
332 | { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ | 376 | { PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */ |
333 | { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ | 377 | { PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */ |
334 | { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ | 378 | { PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */ |
335 | { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */ | 379 | { PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */ |
336 | { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */ | 380 | { PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */ |
337 | { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */ | 381 | { PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */ |
338 | { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */ | 382 | { PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */ |
339 | { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ | 383 | { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */ |
340 | { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */ | 384 | { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */ |
341 | 385 | ||
342 | /* JMicron */ | 386 | /* JMicron */ |
343 | { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ | 387 | { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ |
@@ -372,6 +416,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
372 | { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ | 416 | { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ |
373 | { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ | 417 | { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ |
374 | 418 | ||
419 | /* Generic, PCI class code for AHCI */ | ||
420 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
421 | 0x010601, 0xffffff, board_ahci }, | ||
422 | |||
375 | { } /* terminate list */ | 423 | { } /* terminate list */ |
376 | }; | 424 | }; |
377 | 425 | ||
@@ -386,6 +434,11 @@ static struct pci_driver ahci_pci_driver = { | |||
386 | }; | 434 | }; |
387 | 435 | ||
388 | 436 | ||
437 | static inline int ahci_nr_ports(u32 cap) | ||
438 | { | ||
439 | return (cap & 0x1f) + 1; | ||
440 | } | ||
441 | |||
389 | static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port) | 442 | static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port) |
390 | { | 443 | { |
391 | return base + 0x100 + (port * 0x80); | 444 | return base + 0x100 + (port * 0x80); |
@@ -559,9 +612,6 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap) | |||
559 | static void ahci_init_port(void __iomem *port_mmio, u32 cap, | 612 | static void ahci_init_port(void __iomem *port_mmio, u32 cap, |
560 | dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) | 613 | dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) |
561 | { | 614 | { |
562 | /* power up */ | ||
563 | ahci_power_up(port_mmio, cap); | ||
564 | |||
565 | /* enable FIS reception */ | 615 | /* enable FIS reception */ |
566 | ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma); | 616 | ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma); |
567 | 617 | ||
@@ -587,19 +637,17 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg) | |||
587 | return rc; | 637 | return rc; |
588 | } | 638 | } |
589 | 639 | ||
590 | /* put device into slumber mode */ | ||
591 | ahci_power_down(port_mmio, cap); | ||
592 | |||
593 | return 0; | 640 | return 0; |
594 | } | 641 | } |
595 | 642 | ||
596 | static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) | 643 | static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) |
597 | { | 644 | { |
598 | u32 cap_save, tmp; | 645 | u32 cap_save, impl_save, tmp; |
599 | 646 | ||
600 | cap_save = readl(mmio + HOST_CAP); | 647 | cap_save = readl(mmio + HOST_CAP); |
601 | cap_save &= ( (1<<28) | (1<<17) ); | 648 | cap_save &= ( (1<<28) | (1<<17) ); |
602 | cap_save |= (1 << 27); | 649 | cap_save |= (1 << 27); |
650 | impl_save = readl(mmio + HOST_PORTS_IMPL); | ||
603 | 651 | ||
604 | /* global controller reset */ | 652 | /* global controller reset */ |
605 | tmp = readl(mmio + HOST_CTL); | 653 | tmp = readl(mmio + HOST_CTL); |
@@ -620,10 +668,21 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) | |||
620 | return -EIO; | 668 | return -EIO; |
621 | } | 669 | } |
622 | 670 | ||
671 | /* turn on AHCI mode */ | ||
623 | writel(HOST_AHCI_EN, mmio + HOST_CTL); | 672 | writel(HOST_AHCI_EN, mmio + HOST_CTL); |
624 | (void) readl(mmio + HOST_CTL); /* flush */ | 673 | (void) readl(mmio + HOST_CTL); /* flush */ |
674 | |||
675 | /* These write-once registers are normally cleared on reset. | ||
676 | * Restore BIOS values... which we HOPE were present before | ||
677 | * reset. | ||
678 | */ | ||
679 | if (!impl_save) { | ||
680 | impl_save = (1 << ahci_nr_ports(cap_save)) - 1; | ||
681 | dev_printk(KERN_WARNING, &pdev->dev, | ||
682 | "PORTS_IMPL is zero, forcing 0x%x\n", impl_save); | ||
683 | } | ||
625 | writel(cap_save, mmio + HOST_CAP); | 684 | writel(cap_save, mmio + HOST_CAP); |
626 | writel(0xf, mmio + HOST_PORTS_IMPL); | 685 | writel(impl_save, mmio + HOST_PORTS_IMPL); |
627 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ | 686 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ |
628 | 687 | ||
629 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { | 688 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { |
@@ -639,7 +698,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) | |||
639 | } | 698 | } |
640 | 699 | ||
641 | static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, | 700 | static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, |
642 | int n_ports, u32 cap) | 701 | int n_ports, unsigned int port_flags, |
702 | struct ahci_host_priv *hpriv) | ||
643 | { | 703 | { |
644 | int i, rc; | 704 | int i, rc; |
645 | u32 tmp; | 705 | u32 tmp; |
@@ -648,13 +708,12 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, | |||
648 | void __iomem *port_mmio = ahci_port_base(mmio, i); | 708 | void __iomem *port_mmio = ahci_port_base(mmio, i); |
649 | const char *emsg = NULL; | 709 | const char *emsg = NULL; |
650 | 710 | ||
651 | #if 0 /* BIOSen initialize this incorrectly */ | 711 | if ((port_flags & AHCI_FLAG_HONOR_PI) && |
652 | if (!(hpriv->port_map & (1 << i))) | 712 | !(hpriv->port_map & (1 << i))) |
653 | continue; | 713 | continue; |
654 | #endif | ||
655 | 714 | ||
656 | /* make sure port is not active */ | 715 | /* make sure port is not active */ |
657 | rc = ahci_deinit_port(port_mmio, cap, &emsg); | 716 | rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); |
658 | if (rc) | 717 | if (rc) |
659 | dev_printk(KERN_WARNING, &pdev->dev, | 718 | dev_printk(KERN_WARNING, &pdev->dev, |
660 | "%s (%d)\n", emsg, rc); | 719 | "%s (%d)\n", emsg, rc); |
@@ -729,17 +788,6 @@ static int ahci_clo(struct ata_port *ap) | |||
729 | return 0; | 788 | return 0; |
730 | } | 789 | } |
731 | 790 | ||
732 | static int ahci_prereset(struct ata_port *ap) | ||
733 | { | ||
734 | if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) && | ||
735 | (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) { | ||
736 | /* ATA_BUSY hasn't cleared, so send a CLO */ | ||
737 | ahci_clo(ap); | ||
738 | } | ||
739 | |||
740 | return ata_std_prereset(ap); | ||
741 | } | ||
742 | |||
743 | static int ahci_softreset(struct ata_port *ap, unsigned int *class) | 791 | static int ahci_softreset(struct ata_port *ap, unsigned int *class) |
744 | { | 792 | { |
745 | struct ahci_port_priv *pp = ap->private_data; | 793 | struct ahci_port_priv *pp = ap->private_data; |
@@ -877,6 +925,31 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) | |||
877 | return rc; | 925 | return rc; |
878 | } | 926 | } |
879 | 927 | ||
928 | static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class) | ||
929 | { | ||
930 | void __iomem *mmio = ap->host->mmio_base; | ||
931 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
932 | int rc; | ||
933 | |||
934 | DPRINTK("ENTER\n"); | ||
935 | |||
936 | ahci_stop_engine(port_mmio); | ||
937 | |||
938 | rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context)); | ||
939 | |||
940 | /* vt8251 needs SError cleared for the port to operate */ | ||
941 | ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR)); | ||
942 | |||
943 | ahci_start_engine(port_mmio); | ||
944 | |||
945 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); | ||
946 | |||
947 | /* vt8251 doesn't clear BSY on signature FIS reception, | ||
948 | * request follow-up softreset. | ||
949 | */ | ||
950 | return rc ?: -EAGAIN; | ||
951 | } | ||
952 | |||
880 | static void ahci_postreset(struct ata_port *ap, unsigned int *class) | 953 | static void ahci_postreset(struct ata_port *ap, unsigned int *class) |
881 | { | 954 | { |
882 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 955 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
@@ -1196,7 +1269,23 @@ static void ahci_error_handler(struct ata_port *ap) | |||
1196 | } | 1269 | } |
1197 | 1270 | ||
1198 | /* perform recovery */ | 1271 | /* perform recovery */ |
1199 | ata_do_eh(ap, ahci_prereset, ahci_softreset, ahci_hardreset, | 1272 | ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_hardreset, |
1273 | ahci_postreset); | ||
1274 | } | ||
1275 | |||
1276 | static void ahci_vt8251_error_handler(struct ata_port *ap) | ||
1277 | { | ||
1278 | void __iomem *mmio = ap->host->mmio_base; | ||
1279 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1280 | |||
1281 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { | ||
1282 | /* restart engine */ | ||
1283 | ahci_stop_engine(port_mmio); | ||
1284 | ahci_start_engine(port_mmio); | ||
1285 | } | ||
1286 | |||
1287 | /* perform recovery */ | ||
1288 | ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_vt8251_hardreset, | ||
1200 | ahci_postreset); | 1289 | ahci_postreset); |
1201 | } | 1290 | } |
1202 | 1291 | ||
@@ -1226,7 +1315,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) | |||
1226 | int rc; | 1315 | int rc; |
1227 | 1316 | ||
1228 | rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); | 1317 | rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); |
1229 | if (rc) { | 1318 | if (rc == 0) |
1319 | ahci_power_down(port_mmio, hpriv->cap); | ||
1320 | else { | ||
1230 | ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); | 1321 | ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); |
1231 | ahci_init_port(port_mmio, hpriv->cap, | 1322 | ahci_init_port(port_mmio, hpriv->cap, |
1232 | pp->cmd_slot_dma, pp->rx_fis_dma); | 1323 | pp->cmd_slot_dma, pp->rx_fis_dma); |
@@ -1242,6 +1333,7 @@ static int ahci_port_resume(struct ata_port *ap) | |||
1242 | void __iomem *mmio = ap->host->mmio_base; | 1333 | void __iomem *mmio = ap->host->mmio_base; |
1243 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 1334 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
1244 | 1335 | ||
1336 | ahci_power_up(port_mmio, hpriv->cap); | ||
1245 | ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); | 1337 | ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); |
1246 | 1338 | ||
1247 | return 0; | 1339 | return 0; |
@@ -1281,7 +1373,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) | |||
1281 | if (rc) | 1373 | if (rc) |
1282 | return rc; | 1374 | return rc; |
1283 | 1375 | ||
1284 | ahci_init_controller(mmio, pdev, host->n_ports, hpriv->cap); | 1376 | ahci_init_controller(mmio, pdev, host->n_ports, |
1377 | host->ports[0]->flags, hpriv); | ||
1285 | } | 1378 | } |
1286 | 1379 | ||
1287 | ata_host_resume(host); | 1380 | ata_host_resume(host); |
@@ -1347,6 +1440,9 @@ static int ahci_port_start(struct ata_port *ap) | |||
1347 | 1440 | ||
1348 | ap->private_data = pp; | 1441 | ap->private_data = pp; |
1349 | 1442 | ||
1443 | /* power up port */ | ||
1444 | ahci_power_up(port_mmio, hpriv->cap); | ||
1445 | |||
1350 | /* initialize port */ | 1446 | /* initialize port */ |
1351 | ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); | 1447 | ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); |
1352 | 1448 | ||
@@ -1393,7 +1489,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
1393 | struct ahci_host_priv *hpriv = probe_ent->private_data; | 1489 | struct ahci_host_priv *hpriv = probe_ent->private_data; |
1394 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); | 1490 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); |
1395 | void __iomem *mmio = probe_ent->mmio_base; | 1491 | void __iomem *mmio = probe_ent->mmio_base; |
1396 | unsigned int i, using_dac; | 1492 | unsigned int i, cap_n_ports, using_dac; |
1397 | int rc; | 1493 | int rc; |
1398 | 1494 | ||
1399 | rc = ahci_reset_controller(mmio, pdev); | 1495 | rc = ahci_reset_controller(mmio, pdev); |
@@ -1402,10 +1498,34 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
1402 | 1498 | ||
1403 | hpriv->cap = readl(mmio + HOST_CAP); | 1499 | hpriv->cap = readl(mmio + HOST_CAP); |
1404 | hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); | 1500 | hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); |
1405 | probe_ent->n_ports = (hpriv->cap & 0x1f) + 1; | 1501 | cap_n_ports = ahci_nr_ports(hpriv->cap); |
1406 | 1502 | ||
1407 | VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", | 1503 | VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", |
1408 | hpriv->cap, hpriv->port_map, probe_ent->n_ports); | 1504 | hpriv->cap, hpriv->port_map, cap_n_ports); |
1505 | |||
1506 | if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) { | ||
1507 | unsigned int n_ports = cap_n_ports; | ||
1508 | u32 port_map = hpriv->port_map; | ||
1509 | int max_port = 0; | ||
1510 | |||
1511 | for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) { | ||
1512 | if (port_map & (1 << i)) { | ||
1513 | n_ports--; | ||
1514 | port_map &= ~(1 << i); | ||
1515 | max_port = i; | ||
1516 | } else | ||
1517 | probe_ent->dummy_port_mask |= 1 << i; | ||
1518 | } | ||
1519 | |||
1520 | if (n_ports || port_map) | ||
1521 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1522 | "nr_ports (%u) and implemented port map " | ||
1523 | "(0x%x) don't match\n", | ||
1524 | cap_n_ports, hpriv->port_map); | ||
1525 | |||
1526 | probe_ent->n_ports = max_port + 1; | ||
1527 | } else | ||
1528 | probe_ent->n_ports = cap_n_ports; | ||
1409 | 1529 | ||
1410 | using_dac = hpriv->cap & HOST_CAP_64; | 1530 | using_dac = hpriv->cap & HOST_CAP_64; |
1411 | if (using_dac && | 1531 | if (using_dac && |
@@ -1437,7 +1557,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
1437 | for (i = 0; i < probe_ent->n_ports; i++) | 1557 | for (i = 0; i < probe_ent->n_ports; i++) |
1438 | ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); | 1558 | ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); |
1439 | 1559 | ||
1440 | ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap); | 1560 | ahci_init_controller(mmio, pdev, probe_ent->n_ports, |
1561 | probe_ent->port_flags, hpriv); | ||
1441 | 1562 | ||
1442 | pci_set_master(pdev); | 1563 | pci_set_master(pdev); |
1443 | 1564 | ||