aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-02-28 11:25:39 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-03 15:39:54 -0500
commitd33f58b883a3f624b9362227bf73fc52a6cbd4b4 (patch)
tree13a5571a6a1f3b6bf3c97c3418eec6e962231598
parentd435804803befedbda9fdc1be088e7930b60982b (diff)
[PATCH] ata_piix: implement proper port map
Replace combined mode handling via PIIX_COMB/COMB_PATA_P0 with proper port map. PIIX now prints port configuration during initialization. ATA_FLAG_SLAVE_POSS is now turned on for SATA ports only when the slave device is actually avaliable. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/scsi/ata_piix.c182
1 files changed, 122 insertions, 60 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 987a7ccac917..4080b8be847b 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -112,9 +112,6 @@ enum {
112 /* combined mode. if set, PATA is channel 0. 112 /* combined mode. if set, PATA is channel 0.
113 * if clear, PATA is channel 1. 113 * if clear, PATA is channel 1.
114 */ 114 */
115 PIIX_COMB_PATA_P0 = (1 << 1),
116 PIIX_COMB = (1 << 2), /* combined mode enabled? */
117
118 PIIX_PORT_ENABLED = (1 << 0), 115 PIIX_PORT_ENABLED = (1 << 0),
119 PIIX_PORT_PRESENT = (1 << 4), 116 PIIX_PORT_PRESENT = (1 << 4),
120 117
@@ -130,9 +127,23 @@ enum {
130 ich6_sata_ahci = 5, 127 ich6_sata_ahci = 5,
131 ich6m_sata_ahci = 6, 128 ich6m_sata_ahci = 6,
132 129
130 /* constants for mapping table */
131 P0 = 0, /* port 0 */
132 P1 = 1, /* port 1 */
133 P2 = 2, /* port 2 */
134 P3 = 3, /* port 3 */
135 IDE = -1, /* IDE */
136 NA = -2, /* not avaliable */
137 RV = -3, /* reserved */
138
133 PIIX_AHCI_DEVICE = 6, 139 PIIX_AHCI_DEVICE = 6,
134}; 140};
135 141
142struct piix_map_db {
143 const u32 mask;
144 const int map[][4];
145};
146
136static int piix_init_one (struct pci_dev *pdev, 147static int piix_init_one (struct pci_dev *pdev,
137 const struct pci_device_id *ent); 148 const struct pci_device_id *ent);
138 149
@@ -272,6 +283,43 @@ static const struct ata_port_operations piix_sata_ops = {
272 .host_stop = ata_host_stop, 283 .host_stop = ata_host_stop,
273}; 284};
274 285
286static struct piix_map_db ich5_map_db = {
287 .mask = 0x7,
288 .map = {
289 /* PM PS SM SS MAP */
290 { P0, NA, P1, NA }, /* 000b */
291 { P1, NA, P0, NA }, /* 001b */
292 { RV, RV, RV, RV },
293 { RV, RV, RV, RV },
294 { P0, P1, IDE, IDE }, /* 100b */
295 { P1, P0, IDE, IDE }, /* 101b */
296 { IDE, IDE, P0, P1 }, /* 110b */
297 { IDE, IDE, P1, P0 }, /* 111b */
298 },
299};
300
301static struct piix_map_db ich6_map_db = {
302 .mask = 0x3,
303 .map = {
304 /* PM PS SM SS MAP */
305 { P0, P1, P2, P3 }, /* 00b */
306 { IDE, IDE, P1, P3 }, /* 01b */
307 { P0, P2, IDE, IDE }, /* 10b */
308 { RV, RV, RV, RV },
309 },
310};
311
312static struct piix_map_db ich6m_map_db = {
313 .mask = 0x3,
314 .map = {
315 /* PM PS SM SS MAP */
316 { P0, P1, P2, P3 }, /* 00b */
317 { RV, RV, RV, RV },
318 { P0, P2, IDE, IDE }, /* 10b */
319 { RV, RV, RV, RV },
320 },
321};
322
275static struct ata_port_info piix_port_info[] = { 323static struct ata_port_info piix_port_info[] = {
276 /* piix4_pata */ 324 /* piix4_pata */
277 { 325 {
@@ -310,6 +358,7 @@ static struct ata_port_info piix_port_info[] = {
310 .mwdma_mask = 0x07, /* mwdma0-2 */ 358 .mwdma_mask = 0x07, /* mwdma0-2 */
311 .udma_mask = 0x7f, /* udma0-6 */ 359 .udma_mask = 0x7f, /* udma0-6 */
312 .port_ops = &piix_sata_ops, 360 .port_ops = &piix_sata_ops,
361 .private_data = &ich5_map_db,
313 }, 362 },
314 363
315 /* i6300esb_sata */ 364 /* i6300esb_sata */
@@ -321,42 +370,45 @@ static struct ata_port_info piix_port_info[] = {
321 .mwdma_mask = 0x07, /* mwdma0-2 */ 370 .mwdma_mask = 0x07, /* mwdma0-2 */
322 .udma_mask = 0x7f, /* udma0-6 */ 371 .udma_mask = 0x7f, /* udma0-6 */
323 .port_ops = &piix_sata_ops, 372 .port_ops = &piix_sata_ops,
373 .private_data = &ich5_map_db,
324 }, 374 },
325 375
326 /* ich6_sata */ 376 /* ich6_sata */
327 { 377 {
328 .sht = &piix_sht, 378 .sht = &piix_sht,
329 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | 379 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
330 PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS | 380 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
331 PIIX_FLAG_SCR,
332 .pio_mask = 0x1f, /* pio0-4 */ 381 .pio_mask = 0x1f, /* pio0-4 */
333 .mwdma_mask = 0x07, /* mwdma0-2 */ 382 .mwdma_mask = 0x07, /* mwdma0-2 */
334 .udma_mask = 0x7f, /* udma0-6 */ 383 .udma_mask = 0x7f, /* udma0-6 */
335 .port_ops = &piix_sata_ops, 384 .port_ops = &piix_sata_ops,
385 .private_data = &ich6_map_db,
336 }, 386 },
337 387
338 /* ich6_sata_ahci */ 388 /* ich6_sata_ahci */
339 { 389 {
340 .sht = &piix_sht, 390 .sht = &piix_sht,
341 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | 391 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
342 PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS | 392 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
343 PIIX_FLAG_SCR | PIIX_FLAG_AHCI, 393 PIIX_FLAG_AHCI,
344 .pio_mask = 0x1f, /* pio0-4 */ 394 .pio_mask = 0x1f, /* pio0-4 */
345 .mwdma_mask = 0x07, /* mwdma0-2 */ 395 .mwdma_mask = 0x07, /* mwdma0-2 */
346 .udma_mask = 0x7f, /* udma0-6 */ 396 .udma_mask = 0x7f, /* udma0-6 */
347 .port_ops = &piix_sata_ops, 397 .port_ops = &piix_sata_ops,
398 .private_data = &ich6_map_db,
348 }, 399 },
349 400
350 /* ich6m_sata_ahci */ 401 /* ich6m_sata_ahci */
351 { 402 {
352 .sht = &piix_sht, 403 .sht = &piix_sht,
353 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | 404 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
354 PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS | 405 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
355 PIIX_FLAG_SCR | PIIX_FLAG_AHCI, 406 PIIX_FLAG_AHCI,
356 .pio_mask = 0x1f, /* pio0-4 */ 407 .pio_mask = 0x1f, /* pio0-4 */
357 .mwdma_mask = 0x07, /* mwdma0-2 */ 408 .mwdma_mask = 0x07, /* mwdma0-2 */
358 .udma_mask = 0x7f, /* udma0-6 */ 409 .udma_mask = 0x7f, /* udma0-6 */
359 .port_ops = &piix_sata_ops, 410 .port_ops = &piix_sata_ops,
411 .private_data = &ich6m_map_db,
360 }, 412 },
361}; 413};
362 414
@@ -708,6 +760,54 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
708 return no_piix_dma; 760 return no_piix_dma;
709} 761}
710 762
763static void __devinit piix_init_sata_map(struct pci_dev *pdev,
764 struct ata_port_info *pinfo)
765{
766 struct piix_map_db *map_db = pinfo[0].private_data;
767 const unsigned int *map;
768 int i, invalid_map = 0;
769 u8 map_value;
770
771 pci_read_config_byte(pdev, ICH5_PMR, &map_value);
772
773 map = map_db->map[map_value & map_db->mask];
774
775 dev_printk(KERN_INFO, &pdev->dev, "MAP [");
776 for (i = 0; i < 4; i++) {
777 switch (map[i]) {
778 case RV:
779 invalid_map = 1;
780 printk(" XX");
781 break;
782
783 case NA:
784 printk(" --");
785 break;
786
787 case IDE:
788 WARN_ON((i & 1) || map[i + 1] != IDE);
789 pinfo[i / 2] = piix_port_info[ich5_pata];
790 i++;
791 printk(" IDE IDE");
792 break;
793
794 default:
795 printk(" P%d", map[i]);
796 if (i & 1)
797 pinfo[i / 2].host_flags |= ATA_FLAG_SLAVE_POSS;
798 break;
799 }
800 }
801 printk(" ]\n");
802
803 if (invalid_map)
804 dev_printk(KERN_ERR, &pdev->dev,
805 "invalid MAP value %u\n", map_value);
806
807 pinfo[0].private_data = (void *)map;
808 pinfo[1].private_data = (void *)map;
809}
810
711/** 811/**
712 * piix_init_one - Register PIIX ATA PCI device with kernel services 812 * piix_init_one - Register PIIX ATA PCI device with kernel services
713 * @pdev: PCI device to register 813 * @pdev: PCI device to register
@@ -726,9 +826,8 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
726static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 826static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
727{ 827{
728 static int printed_version; 828 static int printed_version;
729 struct ata_port_info *port_info[2]; 829 struct ata_port_info port_info[2];
730 unsigned int combined = 0; 830 struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
731 unsigned int pata_chan = 0, sata_chan = 0;
732 unsigned long host_flags; 831 unsigned long host_flags;
733 832
734 if (!printed_version++) 833 if (!printed_version++)
@@ -739,10 +838,10 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
739 if (!in_module_init) 838 if (!in_module_init)
740 return -ENODEV; 839 return -ENODEV;
741 840
742 port_info[0] = &piix_port_info[ent->driver_data]; 841 port_info[0] = piix_port_info[ent->driver_data];
743 port_info[1] = &piix_port_info[ent->driver_data]; 842 port_info[1] = piix_port_info[ent->driver_data];
744 843
745 host_flags = port_info[0]->host_flags; 844 host_flags = port_info[0].host_flags;
746 845
747 if (host_flags & PIIX_FLAG_AHCI) { 846 if (host_flags & PIIX_FLAG_AHCI) {
748 u8 tmp; 847 u8 tmp;
@@ -754,37 +853,9 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
754 } 853 }
755 } 854 }
756 855
757 if (host_flags & PIIX_FLAG_COMBINED) { 856 /* Initialize SATA map */
758 u8 tmp; 857 if (host_flags & ATA_FLAG_SATA)
759 pci_read_config_byte(pdev, ICH5_PMR, &tmp); 858 piix_init_sata_map(pdev, port_info);
760
761 if (host_flags & PIIX_FLAG_COMBINED_ICH6) {
762 switch (tmp & 0x3) {
763 case 0:
764 break;
765 case 1:
766 combined = 1;
767 sata_chan = 1;
768 break;
769 case 2:
770 combined = 1;
771 pata_chan = 1;
772 break;
773 case 3:
774 dev_printk(KERN_WARNING, &pdev->dev,
775 "invalid MAP value %u\n", tmp);
776 break;
777 }
778 } else {
779 if (tmp & PIIX_COMB) {
780 combined = 1;
781 if (tmp & PIIX_COMB_PATA_P0)
782 sata_chan = 1;
783 else
784 pata_chan = 1;
785 }
786 }
787 }
788 859
789 /* On ICH5, some BIOSen disable the interrupt using the 860 /* On ICH5, some BIOSen disable the interrupt using the
790 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3. 861 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
@@ -795,25 +866,16 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
795 if (host_flags & PIIX_FLAG_CHECKINTR) 866 if (host_flags & PIIX_FLAG_CHECKINTR)
796 pci_intx(pdev, 1); 867 pci_intx(pdev, 1);
797 868
798 if (combined) {
799 port_info[sata_chan] = &piix_port_info[ent->driver_data];
800 port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
801 port_info[pata_chan] = &piix_port_info[ich5_pata];
802
803 dev_printk(KERN_WARNING, &pdev->dev,
804 "combined mode detected (p=%u, s=%u)\n",
805 pata_chan, sata_chan);
806 }
807 if (piix_check_450nx_errata(pdev)) { 869 if (piix_check_450nx_errata(pdev)) {
808 /* This writes into the master table but it does not 870 /* This writes into the master table but it does not
809 really matter for this errata as we will apply it to 871 really matter for this errata as we will apply it to
810 all the PIIX devices on the board */ 872 all the PIIX devices on the board */
811 port_info[0]->mwdma_mask = 0; 873 port_info[0].mwdma_mask = 0;
812 port_info[0]->udma_mask = 0; 874 port_info[0].udma_mask = 0;
813 port_info[1]->mwdma_mask = 0; 875 port_info[1].mwdma_mask = 0;
814 port_info[1]->udma_mask = 0; 876 port_info[1].udma_mask = 0;
815 } 877 }
816 return ata_pci_init_one(pdev, port_info, 2); 878 return ata_pci_init_one(pdev, ppinfo, 2);
817} 879}
818 880
819static int __init piix_init(void) 881static int __init piix_init(void)