diff options
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r-- | drivers/ata/ata_piix.c | 393 |
1 files changed, 317 insertions, 76 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index b406b39b878e..a65c8ae5c461 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -101,39 +101,21 @@ enum { | |||
101 | ICH5_PMR = 0x90, /* port mapping register */ | 101 | ICH5_PMR = 0x90, /* port mapping register */ |
102 | ICH5_PCS = 0x92, /* port control and status */ | 102 | ICH5_PCS = 0x92, /* port control and status */ |
103 | PIIX_SCC = 0x0A, /* sub-class code register */ | 103 | PIIX_SCC = 0x0A, /* sub-class code register */ |
104 | PIIX_SIDPR_BAR = 5, | ||
105 | PIIX_SIDPR_LEN = 16, | ||
106 | PIIX_SIDPR_IDX = 0, | ||
107 | PIIX_SIDPR_DATA = 4, | ||
104 | 108 | ||
105 | PIIX_FLAG_SCR = (1 << 26), /* SCR available */ | ||
106 | PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ | 109 | PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ |
107 | PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ | 110 | PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ |
111 | PIIX_FLAG_SIDPR = (1 << 29), /* SATA idx/data pair regs */ | ||
108 | 112 | ||
109 | PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, | 113 | PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, |
110 | PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, | 114 | PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, |
111 | 115 | ||
112 | /* combined mode. if set, PATA is channel 0. | ||
113 | * if clear, PATA is channel 1. | ||
114 | */ | ||
115 | PIIX_PORT_ENABLED = (1 << 0), | ||
116 | PIIX_PORT_PRESENT = (1 << 4), | ||
117 | |||
118 | PIIX_80C_PRI = (1 << 5) | (1 << 4), | 116 | PIIX_80C_PRI = (1 << 5) | (1 << 4), |
119 | PIIX_80C_SEC = (1 << 7) | (1 << 6), | 117 | PIIX_80C_SEC = (1 << 7) | (1 << 6), |
120 | 118 | ||
121 | /* controller IDs */ | ||
122 | piix_pata_mwdma = 0, /* PIIX3 MWDMA only */ | ||
123 | piix_pata_33, /* PIIX4 at 33Mhz */ | ||
124 | ich_pata_33, /* ICH up to UDMA 33 only */ | ||
125 | ich_pata_66, /* ICH up to 66 Mhz */ | ||
126 | ich_pata_100, /* ICH up to UDMA 100 */ | ||
127 | ich5_sata, | ||
128 | ich6_sata, | ||
129 | ich6_sata_ahci, | ||
130 | ich6m_sata_ahci, | ||
131 | ich8_sata_ahci, | ||
132 | ich8_2port_sata, | ||
133 | ich8m_apple_sata_ahci, /* locks up on second port enable */ | ||
134 | tolapai_sata_ahci, | ||
135 | piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ | ||
136 | |||
137 | /* constants for mapping table */ | 119 | /* constants for mapping table */ |
138 | P0 = 0, /* port 0 */ | 120 | P0 = 0, /* port 0 */ |
139 | P1 = 1, /* port 1 */ | 121 | P1 = 1, /* port 1 */ |
@@ -149,6 +131,24 @@ enum { | |||
149 | PIIX_HOST_BROKEN_SUSPEND = (1 << 24), | 131 | PIIX_HOST_BROKEN_SUSPEND = (1 << 24), |
150 | }; | 132 | }; |
151 | 133 | ||
134 | enum piix_controller_ids { | ||
135 | /* controller IDs */ | ||
136 | piix_pata_mwdma, /* PIIX3 MWDMA only */ | ||
137 | piix_pata_33, /* PIIX4 at 33Mhz */ | ||
138 | ich_pata_33, /* ICH up to UDMA 33 only */ | ||
139 | ich_pata_66, /* ICH up to 66 Mhz */ | ||
140 | ich_pata_100, /* ICH up to UDMA 100 */ | ||
141 | ich5_sata, | ||
142 | ich6_sata, | ||
143 | ich6_sata_ahci, | ||
144 | ich6m_sata_ahci, | ||
145 | ich8_sata_ahci, | ||
146 | ich8_2port_sata, | ||
147 | ich8m_apple_sata_ahci, /* locks up on second port enable */ | ||
148 | tolapai_sata_ahci, | ||
149 | piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ | ||
150 | }; | ||
151 | |||
152 | struct piix_map_db { | 152 | struct piix_map_db { |
153 | const u32 mask; | 153 | const u32 mask; |
154 | const u16 port_enable; | 154 | const u16 port_enable; |
@@ -157,6 +157,7 @@ struct piix_map_db { | |||
157 | 157 | ||
158 | struct piix_host_priv { | 158 | struct piix_host_priv { |
159 | const int *map; | 159 | const int *map; |
160 | void __iomem *sidpr; | ||
160 | }; | 161 | }; |
161 | 162 | ||
162 | static int piix_init_one(struct pci_dev *pdev, | 163 | static int piix_init_one(struct pci_dev *pdev, |
@@ -167,6 +168,9 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev); | |||
167 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); | 168 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); |
168 | static int ich_pata_cable_detect(struct ata_port *ap); | 169 | static int ich_pata_cable_detect(struct ata_port *ap); |
169 | static u8 piix_vmw_bmdma_status(struct ata_port *ap); | 170 | static u8 piix_vmw_bmdma_status(struct ata_port *ap); |
171 | static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val); | ||
172 | static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val); | ||
173 | static void piix_sidpr_error_handler(struct ata_port *ap); | ||
170 | #ifdef CONFIG_PM | 174 | #ifdef CONFIG_PM |
171 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | 175 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); |
172 | static int piix_pci_device_resume(struct pci_dev *pdev); | 176 | static int piix_pci_device_resume(struct pci_dev *pdev); |
@@ -321,7 +325,6 @@ static const struct ata_port_operations piix_pata_ops = { | |||
321 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 325 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
322 | .cable_detect = ata_cable_40wire, | 326 | .cable_detect = ata_cable_40wire, |
323 | 327 | ||
324 | .irq_handler = ata_interrupt, | ||
325 | .irq_clear = ata_bmdma_irq_clear, | 328 | .irq_clear = ata_bmdma_irq_clear, |
326 | .irq_on = ata_irq_on, | 329 | .irq_on = ata_irq_on, |
327 | 330 | ||
@@ -353,7 +356,6 @@ static const struct ata_port_operations ich_pata_ops = { | |||
353 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 356 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
354 | .cable_detect = ich_pata_cable_detect, | 357 | .cable_detect = ich_pata_cable_detect, |
355 | 358 | ||
356 | .irq_handler = ata_interrupt, | ||
357 | .irq_clear = ata_bmdma_irq_clear, | 359 | .irq_clear = ata_bmdma_irq_clear, |
358 | .irq_on = ata_irq_on, | 360 | .irq_on = ata_irq_on, |
359 | 361 | ||
@@ -380,7 +382,6 @@ static const struct ata_port_operations piix_sata_ops = { | |||
380 | .error_handler = ata_bmdma_error_handler, | 382 | .error_handler = ata_bmdma_error_handler, |
381 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 383 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
382 | 384 | ||
383 | .irq_handler = ata_interrupt, | ||
384 | .irq_clear = ata_bmdma_irq_clear, | 385 | .irq_clear = ata_bmdma_irq_clear, |
385 | .irq_on = ata_irq_on, | 386 | .irq_on = ata_irq_on, |
386 | 387 | ||
@@ -419,6 +420,35 @@ static const struct ata_port_operations piix_vmw_ops = { | |||
419 | .port_start = ata_port_start, | 420 | .port_start = ata_port_start, |
420 | }; | 421 | }; |
421 | 422 | ||
423 | static const struct ata_port_operations piix_sidpr_sata_ops = { | ||
424 | .tf_load = ata_tf_load, | ||
425 | .tf_read = ata_tf_read, | ||
426 | .check_status = ata_check_status, | ||
427 | .exec_command = ata_exec_command, | ||
428 | .dev_select = ata_std_dev_select, | ||
429 | |||
430 | .bmdma_setup = ata_bmdma_setup, | ||
431 | .bmdma_start = ata_bmdma_start, | ||
432 | .bmdma_stop = ata_bmdma_stop, | ||
433 | .bmdma_status = ata_bmdma_status, | ||
434 | .qc_prep = ata_qc_prep, | ||
435 | .qc_issue = ata_qc_issue_prot, | ||
436 | .data_xfer = ata_data_xfer, | ||
437 | |||
438 | .scr_read = piix_sidpr_scr_read, | ||
439 | .scr_write = piix_sidpr_scr_write, | ||
440 | |||
441 | .freeze = ata_bmdma_freeze, | ||
442 | .thaw = ata_bmdma_thaw, | ||
443 | .error_handler = piix_sidpr_error_handler, | ||
444 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
445 | |||
446 | .irq_clear = ata_bmdma_irq_clear, | ||
447 | .irq_on = ata_irq_on, | ||
448 | |||
449 | .port_start = ata_port_start, | ||
450 | }; | ||
451 | |||
422 | static const struct piix_map_db ich5_map_db = { | 452 | static const struct piix_map_db ich5_map_db = { |
423 | .mask = 0x7, | 453 | .mask = 0x7, |
424 | .port_enable = 0x3, | 454 | .port_enable = 0x3, |
@@ -526,7 +556,6 @@ static const struct piix_map_db *piix_map_db_table[] = { | |||
526 | static struct ata_port_info piix_port_info[] = { | 556 | static struct ata_port_info piix_port_info[] = { |
527 | [piix_pata_mwdma] = /* PIIX3 MWDMA only */ | 557 | [piix_pata_mwdma] = /* PIIX3 MWDMA only */ |
528 | { | 558 | { |
529 | .sht = &piix_sht, | ||
530 | .flags = PIIX_PATA_FLAGS, | 559 | .flags = PIIX_PATA_FLAGS, |
531 | .pio_mask = 0x1f, /* pio0-4 */ | 560 | .pio_mask = 0x1f, /* pio0-4 */ |
532 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ | 561 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ |
@@ -535,7 +564,6 @@ static struct ata_port_info piix_port_info[] = { | |||
535 | 564 | ||
536 | [piix_pata_33] = /* PIIX4 at 33MHz */ | 565 | [piix_pata_33] = /* PIIX4 at 33MHz */ |
537 | { | 566 | { |
538 | .sht = &piix_sht, | ||
539 | .flags = PIIX_PATA_FLAGS, | 567 | .flags = PIIX_PATA_FLAGS, |
540 | .pio_mask = 0x1f, /* pio0-4 */ | 568 | .pio_mask = 0x1f, /* pio0-4 */ |
541 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ | 569 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ |
@@ -545,7 +573,6 @@ static struct ata_port_info piix_port_info[] = { | |||
545 | 573 | ||
546 | [ich_pata_33] = /* ICH0 - ICH at 33Mhz*/ | 574 | [ich_pata_33] = /* ICH0 - ICH at 33Mhz*/ |
547 | { | 575 | { |
548 | .sht = &piix_sht, | ||
549 | .flags = PIIX_PATA_FLAGS, | 576 | .flags = PIIX_PATA_FLAGS, |
550 | .pio_mask = 0x1f, /* pio 0-4 */ | 577 | .pio_mask = 0x1f, /* pio 0-4 */ |
551 | .mwdma_mask = 0x06, /* Check: maybe 0x07 */ | 578 | .mwdma_mask = 0x06, /* Check: maybe 0x07 */ |
@@ -555,7 +582,6 @@ static struct ata_port_info piix_port_info[] = { | |||
555 | 582 | ||
556 | [ich_pata_66] = /* ICH controllers up to 66MHz */ | 583 | [ich_pata_66] = /* ICH controllers up to 66MHz */ |
557 | { | 584 | { |
558 | .sht = &piix_sht, | ||
559 | .flags = PIIX_PATA_FLAGS, | 585 | .flags = PIIX_PATA_FLAGS, |
560 | .pio_mask = 0x1f, /* pio 0-4 */ | 586 | .pio_mask = 0x1f, /* pio 0-4 */ |
561 | .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ | 587 | .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ |
@@ -565,7 +591,6 @@ static struct ata_port_info piix_port_info[] = { | |||
565 | 591 | ||
566 | [ich_pata_100] = | 592 | [ich_pata_100] = |
567 | { | 593 | { |
568 | .sht = &piix_sht, | ||
569 | .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, | 594 | .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, |
570 | .pio_mask = 0x1f, /* pio0-4 */ | 595 | .pio_mask = 0x1f, /* pio0-4 */ |
571 | .mwdma_mask = 0x06, /* mwdma1-2 */ | 596 | .mwdma_mask = 0x06, /* mwdma1-2 */ |
@@ -575,7 +600,6 @@ static struct ata_port_info piix_port_info[] = { | |||
575 | 600 | ||
576 | [ich5_sata] = | 601 | [ich5_sata] = |
577 | { | 602 | { |
578 | .sht = &piix_sht, | ||
579 | .flags = PIIX_SATA_FLAGS, | 603 | .flags = PIIX_SATA_FLAGS, |
580 | .pio_mask = 0x1f, /* pio0-4 */ | 604 | .pio_mask = 0x1f, /* pio0-4 */ |
581 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 605 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
@@ -585,8 +609,7 @@ static struct ata_port_info piix_port_info[] = { | |||
585 | 609 | ||
586 | [ich6_sata] = | 610 | [ich6_sata] = |
587 | { | 611 | { |
588 | .sht = &piix_sht, | 612 | .flags = PIIX_SATA_FLAGS, |
589 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR, | ||
590 | .pio_mask = 0x1f, /* pio0-4 */ | 613 | .pio_mask = 0x1f, /* pio0-4 */ |
591 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 614 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
592 | .udma_mask = ATA_UDMA6, | 615 | .udma_mask = ATA_UDMA6, |
@@ -595,9 +618,7 @@ static struct ata_port_info piix_port_info[] = { | |||
595 | 618 | ||
596 | [ich6_sata_ahci] = | 619 | [ich6_sata_ahci] = |
597 | { | 620 | { |
598 | .sht = &piix_sht, | 621 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, |
599 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | | ||
600 | PIIX_FLAG_AHCI, | ||
601 | .pio_mask = 0x1f, /* pio0-4 */ | 622 | .pio_mask = 0x1f, /* pio0-4 */ |
602 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 623 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
603 | .udma_mask = ATA_UDMA6, | 624 | .udma_mask = ATA_UDMA6, |
@@ -606,9 +627,7 @@ static struct ata_port_info piix_port_info[] = { | |||
606 | 627 | ||
607 | [ich6m_sata_ahci] = | 628 | [ich6m_sata_ahci] = |
608 | { | 629 | { |
609 | .sht = &piix_sht, | 630 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, |
610 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | | ||
611 | PIIX_FLAG_AHCI, | ||
612 | .pio_mask = 0x1f, /* pio0-4 */ | 631 | .pio_mask = 0x1f, /* pio0-4 */ |
613 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 632 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
614 | .udma_mask = ATA_UDMA6, | 633 | .udma_mask = ATA_UDMA6, |
@@ -617,9 +636,8 @@ static struct ata_port_info piix_port_info[] = { | |||
617 | 636 | ||
618 | [ich8_sata_ahci] = | 637 | [ich8_sata_ahci] = |
619 | { | 638 | { |
620 | .sht = &piix_sht, | 639 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI | |
621 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | | 640 | PIIX_FLAG_SIDPR, |
622 | PIIX_FLAG_AHCI, | ||
623 | .pio_mask = 0x1f, /* pio0-4 */ | 641 | .pio_mask = 0x1f, /* pio0-4 */ |
624 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 642 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
625 | .udma_mask = ATA_UDMA6, | 643 | .udma_mask = ATA_UDMA6, |
@@ -628,9 +646,8 @@ static struct ata_port_info piix_port_info[] = { | |||
628 | 646 | ||
629 | [ich8_2port_sata] = | 647 | [ich8_2port_sata] = |
630 | { | 648 | { |
631 | .sht = &piix_sht, | 649 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI | |
632 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | | 650 | PIIX_FLAG_SIDPR, |
633 | PIIX_FLAG_AHCI, | ||
634 | .pio_mask = 0x1f, /* pio0-4 */ | 651 | .pio_mask = 0x1f, /* pio0-4 */ |
635 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 652 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
636 | .udma_mask = ATA_UDMA6, | 653 | .udma_mask = ATA_UDMA6, |
@@ -639,9 +656,7 @@ static struct ata_port_info piix_port_info[] = { | |||
639 | 656 | ||
640 | [tolapai_sata_ahci] = | 657 | [tolapai_sata_ahci] = |
641 | { | 658 | { |
642 | .sht = &piix_sht, | 659 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, |
643 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | | ||
644 | PIIX_FLAG_AHCI, | ||
645 | .pio_mask = 0x1f, /* pio0-4 */ | 660 | .pio_mask = 0x1f, /* pio0-4 */ |
646 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 661 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
647 | .udma_mask = ATA_UDMA6, | 662 | .udma_mask = ATA_UDMA6, |
@@ -650,9 +665,8 @@ static struct ata_port_info piix_port_info[] = { | |||
650 | 665 | ||
651 | [ich8m_apple_sata_ahci] = | 666 | [ich8m_apple_sata_ahci] = |
652 | { | 667 | { |
653 | .sht = &piix_sht, | 668 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI | |
654 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | | 669 | PIIX_FLAG_SIDPR, |
655 | PIIX_FLAG_AHCI, | ||
656 | .pio_mask = 0x1f, /* pio0-4 */ | 670 | .pio_mask = 0x1f, /* pio0-4 */ |
657 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 671 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
658 | .udma_mask = ATA_UDMA6, | 672 | .udma_mask = ATA_UDMA6, |
@@ -1001,6 +1015,180 @@ static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
1001 | do_pata_set_dmamode(ap, adev, 1); | 1015 | do_pata_set_dmamode(ap, adev, 1); |
1002 | } | 1016 | } |
1003 | 1017 | ||
1018 | /* | ||
1019 | * Serial ATA Index/Data Pair Superset Registers access | ||
1020 | * | ||
1021 | * Beginning from ICH8, there's a sane way to access SCRs using index | ||
1022 | * and data register pair located at BAR5. This creates an | ||
1023 | * interesting problem of mapping two SCRs to one port. | ||
1024 | * | ||
1025 | * Although they have separate SCRs, the master and slave aren't | ||
1026 | * independent enough to be treated as separate links - e.g. softreset | ||
1027 | * resets both. Also, there's no protocol defined for hard resetting | ||
1028 | * singled device sharing the virtual port (no defined way to acquire | ||
1029 | * device signature). This is worked around by merging the SCR values | ||
1030 | * into one sensible value and requesting follow-up SRST after | ||
1031 | * hardreset. | ||
1032 | * | ||
1033 | * SCR merging is perfomed in nibbles which is the unit contents in | ||
1034 | * SCRs are organized. If two values are equal, the value is used. | ||
1035 | * When they differ, merge table which lists precedence of possible | ||
1036 | * values is consulted and the first match or the last entry when | ||
1037 | * nothing matches is used. When there's no merge table for the | ||
1038 | * specific nibble, value from the first port is used. | ||
1039 | */ | ||
1040 | static const int piix_sidx_map[] = { | ||
1041 | [SCR_STATUS] = 0, | ||
1042 | [SCR_ERROR] = 2, | ||
1043 | [SCR_CONTROL] = 1, | ||
1044 | }; | ||
1045 | |||
1046 | static void piix_sidpr_sel(struct ata_device *dev, unsigned int reg) | ||
1047 | { | ||
1048 | struct ata_port *ap = dev->link->ap; | ||
1049 | struct piix_host_priv *hpriv = ap->host->private_data; | ||
1050 | |||
1051 | iowrite32(((ap->port_no * 2 + dev->devno) << 8) | piix_sidx_map[reg], | ||
1052 | hpriv->sidpr + PIIX_SIDPR_IDX); | ||
1053 | } | ||
1054 | |||
1055 | static int piix_sidpr_read(struct ata_device *dev, unsigned int reg) | ||
1056 | { | ||
1057 | struct piix_host_priv *hpriv = dev->link->ap->host->private_data; | ||
1058 | |||
1059 | piix_sidpr_sel(dev, reg); | ||
1060 | return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA); | ||
1061 | } | ||
1062 | |||
1063 | static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val) | ||
1064 | { | ||
1065 | struct piix_host_priv *hpriv = dev->link->ap->host->private_data; | ||
1066 | |||
1067 | piix_sidpr_sel(dev, reg); | ||
1068 | iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA); | ||
1069 | } | ||
1070 | |||
1071 | u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl) | ||
1072 | { | ||
1073 | u32 val = 0; | ||
1074 | int i, mi; | ||
1075 | |||
1076 | for (i = 0, mi = 0; i < 32 / 4; i++) { | ||
1077 | u8 c0 = (val0 >> (i * 4)) & 0xf; | ||
1078 | u8 c1 = (val1 >> (i * 4)) & 0xf; | ||
1079 | u8 merged = c0; | ||
1080 | const int *cur; | ||
1081 | |||
1082 | /* if no merge preference, assume the first value */ | ||
1083 | cur = merge_tbl[mi]; | ||
1084 | if (!cur) | ||
1085 | goto done; | ||
1086 | mi++; | ||
1087 | |||
1088 | /* if two values equal, use it */ | ||
1089 | if (c0 == c1) | ||
1090 | goto done; | ||
1091 | |||
1092 | /* choose the first match or the last from the merge table */ | ||
1093 | while (*cur != -1) { | ||
1094 | if (c0 == *cur || c1 == *cur) | ||
1095 | break; | ||
1096 | cur++; | ||
1097 | } | ||
1098 | if (*cur == -1) | ||
1099 | cur--; | ||
1100 | merged = *cur; | ||
1101 | done: | ||
1102 | val |= merged << (i * 4); | ||
1103 | } | ||
1104 | |||
1105 | return val; | ||
1106 | } | ||
1107 | |||
1108 | static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val) | ||
1109 | { | ||
1110 | const int * const sstatus_merge_tbl[] = { | ||
1111 | /* DET */ (const int []){ 1, 3, 0, 4, 3, -1 }, | ||
1112 | /* SPD */ (const int []){ 2, 1, 0, -1 }, | ||
1113 | /* IPM */ (const int []){ 6, 2, 1, 0, -1 }, | ||
1114 | NULL, | ||
1115 | }; | ||
1116 | const int * const scontrol_merge_tbl[] = { | ||
1117 | /* DET */ (const int []){ 1, 0, 4, 0, -1 }, | ||
1118 | /* SPD */ (const int []){ 0, 2, 1, 0, -1 }, | ||
1119 | /* IPM */ (const int []){ 0, 1, 2, 3, 0, -1 }, | ||
1120 | NULL, | ||
1121 | }; | ||
1122 | u32 v0, v1; | ||
1123 | |||
1124 | if (reg >= ARRAY_SIZE(piix_sidx_map)) | ||
1125 | return -EINVAL; | ||
1126 | |||
1127 | if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) { | ||
1128 | *val = piix_sidpr_read(&ap->link.device[0], reg); | ||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | v0 = piix_sidpr_read(&ap->link.device[0], reg); | ||
1133 | v1 = piix_sidpr_read(&ap->link.device[1], reg); | ||
1134 | |||
1135 | switch (reg) { | ||
1136 | case SCR_STATUS: | ||
1137 | *val = piix_merge_scr(v0, v1, sstatus_merge_tbl); | ||
1138 | break; | ||
1139 | case SCR_ERROR: | ||
1140 | *val = v0 | v1; | ||
1141 | break; | ||
1142 | case SCR_CONTROL: | ||
1143 | *val = piix_merge_scr(v0, v1, scontrol_merge_tbl); | ||
1144 | break; | ||
1145 | } | ||
1146 | |||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val) | ||
1151 | { | ||
1152 | if (reg >= ARRAY_SIZE(piix_sidx_map)) | ||
1153 | return -EINVAL; | ||
1154 | |||
1155 | piix_sidpr_write(&ap->link.device[0], reg, val); | ||
1156 | |||
1157 | if (ap->flags & ATA_FLAG_SLAVE_POSS) | ||
1158 | piix_sidpr_write(&ap->link.device[1], reg, val); | ||
1159 | |||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1163 | static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class, | ||
1164 | unsigned long deadline) | ||
1165 | { | ||
1166 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | ||
1167 | int rc; | ||
1168 | |||
1169 | /* do hardreset */ | ||
1170 | rc = sata_link_hardreset(link, timing, deadline); | ||
1171 | if (rc) { | ||
1172 | ata_link_printk(link, KERN_ERR, | ||
1173 | "COMRESET failed (errno=%d)\n", rc); | ||
1174 | return rc; | ||
1175 | } | ||
1176 | |||
1177 | /* TODO: phy layer with polling, timeouts, etc. */ | ||
1178 | if (ata_link_offline(link)) { | ||
1179 | *class = ATA_DEV_NONE; | ||
1180 | return 0; | ||
1181 | } | ||
1182 | |||
1183 | return -EAGAIN; | ||
1184 | } | ||
1185 | |||
1186 | static void piix_sidpr_error_handler(struct ata_port *ap) | ||
1187 | { | ||
1188 | ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, | ||
1189 | piix_sidpr_hardreset, ata_std_postreset); | ||
1190 | } | ||
1191 | |||
1004 | #ifdef CONFIG_PM | 1192 | #ifdef CONFIG_PM |
1005 | static int piix_broken_suspend(void) | 1193 | static int piix_broken_suspend(void) |
1006 | { | 1194 | { |
@@ -1034,6 +1222,13 @@ static int piix_broken_suspend(void) | |||
1034 | }, | 1222 | }, |
1035 | }, | 1223 | }, |
1036 | { | 1224 | { |
1225 | .ident = "TECRA M6", | ||
1226 | .matches = { | ||
1227 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
1228 | DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M6"), | ||
1229 | }, | ||
1230 | }, | ||
1231 | { | ||
1037 | .ident = "TECRA M7", | 1232 | .ident = "TECRA M7", |
1038 | .matches = { | 1233 | .matches = { |
1039 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 1234 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
@@ -1048,6 +1243,13 @@ static int piix_broken_suspend(void) | |||
1048 | }, | 1243 | }, |
1049 | }, | 1244 | }, |
1050 | { | 1245 | { |
1246 | .ident = "Satellite R20", | ||
1247 | .matches = { | ||
1248 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
1249 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite R20"), | ||
1250 | }, | ||
1251 | }, | ||
1252 | { | ||
1051 | .ident = "Satellite R25", | 1253 | .ident = "Satellite R25", |
1052 | .matches = { | 1254 | .matches = { |
1053 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 1255 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
@@ -1253,10 +1455,10 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev) | |||
1253 | return no_piix_dma; | 1455 | return no_piix_dma; |
1254 | } | 1456 | } |
1255 | 1457 | ||
1256 | static void __devinit piix_init_pcs(struct pci_dev *pdev, | 1458 | static void __devinit piix_init_pcs(struct ata_host *host, |
1257 | struct ata_port_info *pinfo, | ||
1258 | const struct piix_map_db *map_db) | 1459 | const struct piix_map_db *map_db) |
1259 | { | 1460 | { |
1461 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
1260 | u16 pcs, new_pcs; | 1462 | u16 pcs, new_pcs; |
1261 | 1463 | ||
1262 | pci_read_config_word(pdev, ICH5_PCS, &pcs); | 1464 | pci_read_config_word(pdev, ICH5_PCS, &pcs); |
@@ -1270,11 +1472,10 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev, | |||
1270 | } | 1472 | } |
1271 | } | 1473 | } |
1272 | 1474 | ||
1273 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, | 1475 | static const int *__devinit piix_init_sata_map(struct pci_dev *pdev, |
1274 | struct ata_port_info *pinfo, | 1476 | struct ata_port_info *pinfo, |
1275 | const struct piix_map_db *map_db) | 1477 | const struct piix_map_db *map_db) |
1276 | { | 1478 | { |
1277 | struct piix_host_priv *hpriv = pinfo[0].private_data; | ||
1278 | const int *map; | 1479 | const int *map; |
1279 | int i, invalid_map = 0; | 1480 | int i, invalid_map = 0; |
1280 | u8 map_value; | 1481 | u8 map_value; |
@@ -1298,7 +1499,6 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, | |||
1298 | case IDE: | 1499 | case IDE: |
1299 | WARN_ON((i & 1) || map[i + 1] != IDE); | 1500 | WARN_ON((i & 1) || map[i + 1] != IDE); |
1300 | pinfo[i / 2] = piix_port_info[ich_pata_100]; | 1501 | pinfo[i / 2] = piix_port_info[ich_pata_100]; |
1301 | pinfo[i / 2].private_data = hpriv; | ||
1302 | i++; | 1502 | i++; |
1303 | printk(" IDE IDE"); | 1503 | printk(" IDE IDE"); |
1304 | break; | 1504 | break; |
@@ -1316,7 +1516,33 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, | |||
1316 | dev_printk(KERN_ERR, &pdev->dev, | 1516 | dev_printk(KERN_ERR, &pdev->dev, |
1317 | "invalid MAP value %u\n", map_value); | 1517 | "invalid MAP value %u\n", map_value); |
1318 | 1518 | ||
1319 | hpriv->map = map; | 1519 | return map; |
1520 | } | ||
1521 | |||
1522 | static void __devinit piix_init_sidpr(struct ata_host *host) | ||
1523 | { | ||
1524 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
1525 | struct piix_host_priv *hpriv = host->private_data; | ||
1526 | int i; | ||
1527 | |||
1528 | /* check for availability */ | ||
1529 | for (i = 0; i < 4; i++) | ||
1530 | if (hpriv->map[i] == IDE) | ||
1531 | return; | ||
1532 | |||
1533 | if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) | ||
1534 | return; | ||
1535 | |||
1536 | if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 || | ||
1537 | pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN) | ||
1538 | return; | ||
1539 | |||
1540 | if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME)) | ||
1541 | return; | ||
1542 | |||
1543 | hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR]; | ||
1544 | host->ports[0]->ops = &piix_sidpr_sata_ops; | ||
1545 | host->ports[1]->ops = &piix_sidpr_sata_ops; | ||
1320 | } | 1546 | } |
1321 | 1547 | ||
1322 | static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) | 1548 | static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) |
@@ -1375,8 +1601,10 @@ static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1375 | struct device *dev = &pdev->dev; | 1601 | struct device *dev = &pdev->dev; |
1376 | struct ata_port_info port_info[2]; | 1602 | struct ata_port_info port_info[2]; |
1377 | const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] }; | 1603 | const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] }; |
1378 | struct piix_host_priv *hpriv; | ||
1379 | unsigned long port_flags; | 1604 | unsigned long port_flags; |
1605 | struct ata_host *host; | ||
1606 | struct piix_host_priv *hpriv; | ||
1607 | int rc; | ||
1380 | 1608 | ||
1381 | if (!printed_version++) | 1609 | if (!printed_version++) |
1382 | dev_printk(KERN_DEBUG, &pdev->dev, | 1610 | dev_printk(KERN_DEBUG, &pdev->dev, |
@@ -1386,17 +1614,31 @@ static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1386 | if (!in_module_init) | 1614 | if (!in_module_init) |
1387 | return -ENODEV; | 1615 | return -ENODEV; |
1388 | 1616 | ||
1617 | port_info[0] = piix_port_info[ent->driver_data]; | ||
1618 | port_info[1] = piix_port_info[ent->driver_data]; | ||
1619 | |||
1620 | port_flags = port_info[0].flags; | ||
1621 | |||
1622 | /* enable device and prepare host */ | ||
1623 | rc = pcim_enable_device(pdev); | ||
1624 | if (rc) | ||
1625 | return rc; | ||
1626 | |||
1627 | /* SATA map init can change port_info, do it before prepping host */ | ||
1389 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); | 1628 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); |
1390 | if (!hpriv) | 1629 | if (!hpriv) |
1391 | return -ENOMEM; | 1630 | return -ENOMEM; |
1392 | 1631 | ||
1393 | port_info[0] = piix_port_info[ent->driver_data]; | 1632 | if (port_flags & ATA_FLAG_SATA) |
1394 | port_info[1] = piix_port_info[ent->driver_data]; | 1633 | hpriv->map = piix_init_sata_map(pdev, port_info, |
1395 | port_info[0].private_data = hpriv; | 1634 | piix_map_db_table[ent->driver_data]); |
1396 | port_info[1].private_data = hpriv; | ||
1397 | 1635 | ||
1398 | port_flags = port_info[0].flags; | 1636 | rc = ata_pci_prepare_sff_host(pdev, ppi, &host); |
1637 | if (rc) | ||
1638 | return rc; | ||
1639 | host->private_data = hpriv; | ||
1399 | 1640 | ||
1641 | /* initialize controller */ | ||
1400 | if (port_flags & PIIX_FLAG_AHCI) { | 1642 | if (port_flags & PIIX_FLAG_AHCI) { |
1401 | u8 tmp; | 1643 | u8 tmp; |
1402 | pci_read_config_byte(pdev, PIIX_SCC, &tmp); | 1644 | pci_read_config_byte(pdev, PIIX_SCC, &tmp); |
@@ -1407,12 +1649,9 @@ static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1407 | } | 1649 | } |
1408 | } | 1650 | } |
1409 | 1651 | ||
1410 | /* Initialize SATA map */ | ||
1411 | if (port_flags & ATA_FLAG_SATA) { | 1652 | if (port_flags & ATA_FLAG_SATA) { |
1412 | piix_init_sata_map(pdev, port_info, | 1653 | piix_init_pcs(host, piix_map_db_table[ent->driver_data]); |
1413 | piix_map_db_table[ent->driver_data]); | 1654 | piix_init_sidpr(host); |
1414 | piix_init_pcs(pdev, port_info, | ||
1415 | piix_map_db_table[ent->driver_data]); | ||
1416 | } | 1655 | } |
1417 | 1656 | ||
1418 | /* apply IOCFG bit18 quirk */ | 1657 | /* apply IOCFG bit18 quirk */ |
@@ -1431,12 +1670,14 @@ static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1431 | /* This writes into the master table but it does not | 1670 | /* This writes into the master table but it does not |
1432 | really matter for this errata as we will apply it to | 1671 | really matter for this errata as we will apply it to |
1433 | all the PIIX devices on the board */ | 1672 | all the PIIX devices on the board */ |
1434 | port_info[0].mwdma_mask = 0; | 1673 | host->ports[0]->mwdma_mask = 0; |
1435 | port_info[0].udma_mask = 0; | 1674 | host->ports[0]->udma_mask = 0; |
1436 | port_info[1].mwdma_mask = 0; | 1675 | host->ports[1]->mwdma_mask = 0; |
1437 | port_info[1].udma_mask = 0; | 1676 | host->ports[1]->udma_mask = 0; |
1438 | } | 1677 | } |
1439 | return ata_pci_init_one(pdev, ppi); | 1678 | |
1679 | pci_set_master(pdev); | ||
1680 | return ata_pci_activate_sff_host(host, ata_interrupt, &piix_sht); | ||
1440 | } | 1681 | } |
1441 | 1682 | ||
1442 | static int __init piix_init(void) | 1683 | static int __init piix_init(void) |