diff options
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r-- | drivers/ata/ata_piix.c | 194 |
1 files changed, 54 insertions, 140 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 720174d628fa..c7de0bb1591f 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * Documentation | 40 | * Documentation |
41 | * Publically available from Intel web site. Errata documentation | 41 | * Publically available from Intel web site. Errata documentation |
42 | * is also publically available. As an aide to anyone hacking on this | 42 | * is also publically available. As an aide to anyone hacking on this |
43 | * driver the list of errata that are relevant is below.going back to | 43 | * driver the list of errata that are relevant is below, going back to |
44 | * PIIX4. Older device documentation is now a bit tricky to find. | 44 | * PIIX4. Older device documentation is now a bit tricky to find. |
45 | * | 45 | * |
46 | * The chipsets all follow very much the same design. The orginal Triton | 46 | * The chipsets all follow very much the same design. The orginal Triton |
@@ -93,7 +93,7 @@ | |||
93 | #include <linux/libata.h> | 93 | #include <linux/libata.h> |
94 | 94 | ||
95 | #define DRV_NAME "ata_piix" | 95 | #define DRV_NAME "ata_piix" |
96 | #define DRV_VERSION "2.00ac6" | 96 | #define DRV_VERSION "2.00ac7" |
97 | 97 | ||
98 | enum { | 98 | enum { |
99 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ | 99 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ |
@@ -101,11 +101,13 @@ enum { | |||
101 | ICH5_PCS = 0x92, /* port control and status */ | 101 | ICH5_PCS = 0x92, /* port control and status */ |
102 | PIIX_SCC = 0x0A, /* sub-class code register */ | 102 | PIIX_SCC = 0x0A, /* sub-class code register */ |
103 | 103 | ||
104 | PIIX_FLAG_IGNORE_PCS = (1 << 25), /* ignore PCS present bits */ | ||
105 | PIIX_FLAG_SCR = (1 << 26), /* SCR available */ | 104 | PIIX_FLAG_SCR = (1 << 26), /* SCR available */ |
106 | PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ | 105 | PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ |
107 | PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ | 106 | PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ |
108 | 107 | ||
108 | PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, | ||
109 | PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, | ||
110 | |||
109 | /* combined mode. if set, PATA is channel 0. | 111 | /* combined mode. if set, PATA is channel 0. |
110 | * if clear, PATA is channel 1. | 112 | * if clear, PATA is channel 1. |
111 | */ | 113 | */ |
@@ -122,11 +124,10 @@ enum { | |||
122 | ich_pata_100 = 3, /* ICH up to UDMA 100 */ | 124 | ich_pata_100 = 3, /* ICH up to UDMA 100 */ |
123 | ich_pata_133 = 4, /* ICH up to UDMA 133 */ | 125 | ich_pata_133 = 4, /* ICH up to UDMA 133 */ |
124 | ich5_sata = 5, | 126 | ich5_sata = 5, |
125 | esb_sata = 6, | 127 | ich6_sata = 6, |
126 | ich6_sata = 7, | 128 | ich6_sata_ahci = 7, |
127 | ich6_sata_ahci = 8, | 129 | ich6m_sata_ahci = 8, |
128 | ich6m_sata_ahci = 9, | 130 | ich8_sata_ahci = 9, |
129 | ich8_sata_ahci = 10, | ||
130 | 131 | ||
131 | /* constants for mapping table */ | 132 | /* constants for mapping table */ |
132 | P0 = 0, /* port 0 */ | 133 | P0 = 0, /* port 0 */ |
@@ -143,13 +144,11 @@ enum { | |||
143 | struct piix_map_db { | 144 | struct piix_map_db { |
144 | const u32 mask; | 145 | const u32 mask; |
145 | const u16 port_enable; | 146 | const u16 port_enable; |
146 | const int present_shift; | ||
147 | const int map[][4]; | 147 | const int map[][4]; |
148 | }; | 148 | }; |
149 | 149 | ||
150 | struct piix_host_priv { | 150 | struct piix_host_priv { |
151 | const int *map; | 151 | const int *map; |
152 | const struct piix_map_db *map_db; | ||
153 | }; | 152 | }; |
154 | 153 | ||
155 | static int piix_init_one (struct pci_dev *pdev, | 154 | static int piix_init_one (struct pci_dev *pdev, |
@@ -214,9 +213,9 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
214 | /* 82801EB (ICH5) */ | 213 | /* 82801EB (ICH5) */ |
215 | { 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, | 214 | { 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, |
216 | /* 6300ESB (ICH5 variant with broken PCS present bits) */ | 215 | /* 6300ESB (ICH5 variant with broken PCS present bits) */ |
217 | { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata }, | 216 | { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, |
218 | /* 6300ESB pretending RAID */ | 217 | /* 6300ESB pretending RAID */ |
219 | { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata }, | 218 | { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, |
220 | /* 82801FB/FW (ICH6/ICH6W) */ | 219 | /* 82801FB/FW (ICH6/ICH6W) */ |
221 | { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, | 220 | { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, |
222 | /* 82801FR/FRW (ICH6R/ICH6RW) */ | 221 | /* 82801FR/FRW (ICH6R/ICH6RW) */ |
@@ -367,7 +366,6 @@ static const struct ata_port_operations piix_sata_ops = { | |||
367 | static const struct piix_map_db ich5_map_db = { | 366 | static const struct piix_map_db ich5_map_db = { |
368 | .mask = 0x7, | 367 | .mask = 0x7, |
369 | .port_enable = 0x3, | 368 | .port_enable = 0x3, |
370 | .present_shift = 4, | ||
371 | .map = { | 369 | .map = { |
372 | /* PM PS SM SS MAP */ | 370 | /* PM PS SM SS MAP */ |
373 | { P0, NA, P1, NA }, /* 000b */ | 371 | { P0, NA, P1, NA }, /* 000b */ |
@@ -384,7 +382,6 @@ static const struct piix_map_db ich5_map_db = { | |||
384 | static const struct piix_map_db ich6_map_db = { | 382 | static const struct piix_map_db ich6_map_db = { |
385 | .mask = 0x3, | 383 | .mask = 0x3, |
386 | .port_enable = 0xf, | 384 | .port_enable = 0xf, |
387 | .present_shift = 4, | ||
388 | .map = { | 385 | .map = { |
389 | /* PM PS SM SS MAP */ | 386 | /* PM PS SM SS MAP */ |
390 | { P0, P2, P1, P3 }, /* 00b */ | 387 | { P0, P2, P1, P3 }, /* 00b */ |
@@ -397,7 +394,6 @@ static const struct piix_map_db ich6_map_db = { | |||
397 | static const struct piix_map_db ich6m_map_db = { | 394 | static const struct piix_map_db ich6m_map_db = { |
398 | .mask = 0x3, | 395 | .mask = 0x3, |
399 | .port_enable = 0x5, | 396 | .port_enable = 0x5, |
400 | .present_shift = 4, | ||
401 | 397 | ||
402 | /* Map 01b isn't specified in the doc but some notebooks use | 398 | /* Map 01b isn't specified in the doc but some notebooks use |
403 | * it anyway. MAP 01b have been spotted on both ICH6M and | 399 | * it anyway. MAP 01b have been spotted on both ICH6M and |
@@ -415,7 +411,6 @@ static const struct piix_map_db ich6m_map_db = { | |||
415 | static const struct piix_map_db ich8_map_db = { | 411 | static const struct piix_map_db ich8_map_db = { |
416 | .mask = 0x3, | 412 | .mask = 0x3, |
417 | .port_enable = 0x3, | 413 | .port_enable = 0x3, |
418 | .present_shift = 8, | ||
419 | .map = { | 414 | .map = { |
420 | /* PM PS SM SS MAP */ | 415 | /* PM PS SM SS MAP */ |
421 | { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ | 416 | { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ |
@@ -427,7 +422,6 @@ static const struct piix_map_db ich8_map_db = { | |||
427 | 422 | ||
428 | static const struct piix_map_db *piix_map_db_table[] = { | 423 | static const struct piix_map_db *piix_map_db_table[] = { |
429 | [ich5_sata] = &ich5_map_db, | 424 | [ich5_sata] = &ich5_map_db, |
430 | [esb_sata] = &ich5_map_db, | ||
431 | [ich6_sata] = &ich6_map_db, | 425 | [ich6_sata] = &ich6_map_db, |
432 | [ich6_sata_ahci] = &ich6_map_db, | 426 | [ich6_sata_ahci] = &ich6_map_db, |
433 | [ich6m_sata_ahci] = &ich6m_map_db, | 427 | [ich6m_sata_ahci] = &ich6m_map_db, |
@@ -438,7 +432,7 @@ static struct ata_port_info piix_port_info[] = { | |||
438 | /* piix_pata_33: 0: PIIX3 or 4 at 33MHz */ | 432 | /* piix_pata_33: 0: PIIX3 or 4 at 33MHz */ |
439 | { | 433 | { |
440 | .sht = &piix_sht, | 434 | .sht = &piix_sht, |
441 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, | 435 | .flags = PIIX_PATA_FLAGS, |
442 | .pio_mask = 0x1f, /* pio0-4 */ | 436 | .pio_mask = 0x1f, /* pio0-4 */ |
443 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ | 437 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ |
444 | .udma_mask = ATA_UDMA_MASK_40C, | 438 | .udma_mask = ATA_UDMA_MASK_40C, |
@@ -448,7 +442,7 @@ static struct ata_port_info piix_port_info[] = { | |||
448 | /* ich_pata_33: 1 ICH0 - ICH at 33Mhz*/ | 442 | /* ich_pata_33: 1 ICH0 - ICH at 33Mhz*/ |
449 | { | 443 | { |
450 | .sht = &piix_sht, | 444 | .sht = &piix_sht, |
451 | .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, | 445 | .flags = PIIX_PATA_FLAGS, |
452 | .pio_mask = 0x1f, /* pio 0-4 */ | 446 | .pio_mask = 0x1f, /* pio 0-4 */ |
453 | .mwdma_mask = 0x06, /* Check: maybe 0x07 */ | 447 | .mwdma_mask = 0x06, /* Check: maybe 0x07 */ |
454 | .udma_mask = ATA_UDMA2, /* UDMA33 */ | 448 | .udma_mask = ATA_UDMA2, /* UDMA33 */ |
@@ -457,7 +451,7 @@ static struct ata_port_info piix_port_info[] = { | |||
457 | /* ich_pata_66: 2 ICH controllers up to 66MHz */ | 451 | /* ich_pata_66: 2 ICH controllers up to 66MHz */ |
458 | { | 452 | { |
459 | .sht = &piix_sht, | 453 | .sht = &piix_sht, |
460 | .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, | 454 | .flags = PIIX_PATA_FLAGS, |
461 | .pio_mask = 0x1f, /* pio 0-4 */ | 455 | .pio_mask = 0x1f, /* pio 0-4 */ |
462 | .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ | 456 | .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ |
463 | .udma_mask = ATA_UDMA4, | 457 | .udma_mask = ATA_UDMA4, |
@@ -467,7 +461,7 @@ static struct ata_port_info piix_port_info[] = { | |||
467 | /* ich_pata_100: 3 */ | 461 | /* ich_pata_100: 3 */ |
468 | { | 462 | { |
469 | .sht = &piix_sht, | 463 | .sht = &piix_sht, |
470 | .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR, | 464 | .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, |
471 | .pio_mask = 0x1f, /* pio0-4 */ | 465 | .pio_mask = 0x1f, /* pio0-4 */ |
472 | .mwdma_mask = 0x06, /* mwdma1-2 */ | 466 | .mwdma_mask = 0x06, /* mwdma1-2 */ |
473 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 467 | .udma_mask = ATA_UDMA5, /* udma0-5 */ |
@@ -477,7 +471,7 @@ static struct ata_port_info piix_port_info[] = { | |||
477 | /* ich_pata_133: 4 ICH with full UDMA6 */ | 471 | /* ich_pata_133: 4 ICH with full UDMA6 */ |
478 | { | 472 | { |
479 | .sht = &piix_sht, | 473 | .sht = &piix_sht, |
480 | .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR, | 474 | .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, |
481 | .pio_mask = 0x1f, /* pio 0-4 */ | 475 | .pio_mask = 0x1f, /* pio 0-4 */ |
482 | .mwdma_mask = 0x06, /* Check: maybe 0x07 */ | 476 | .mwdma_mask = 0x06, /* Check: maybe 0x07 */ |
483 | .udma_mask = ATA_UDMA6, /* UDMA133 */ | 477 | .udma_mask = ATA_UDMA6, /* UDMA133 */ |
@@ -487,41 +481,27 @@ static struct ata_port_info piix_port_info[] = { | |||
487 | /* ich5_sata: 5 */ | 481 | /* ich5_sata: 5 */ |
488 | { | 482 | { |
489 | .sht = &piix_sht, | 483 | .sht = &piix_sht, |
490 | .flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR | | 484 | .flags = PIIX_SATA_FLAGS, |
491 | PIIX_FLAG_IGNORE_PCS, | ||
492 | .pio_mask = 0x1f, /* pio0-4 */ | ||
493 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
494 | .udma_mask = 0x7f, /* udma0-6 */ | ||
495 | .port_ops = &piix_sata_ops, | ||
496 | }, | ||
497 | |||
498 | /* i6300esb_sata: 6 */ | ||
499 | { | ||
500 | .sht = &piix_sht, | ||
501 | .flags = ATA_FLAG_SATA | | ||
502 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS, | ||
503 | .pio_mask = 0x1f, /* pio0-4 */ | 485 | .pio_mask = 0x1f, /* pio0-4 */ |
504 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 486 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
505 | .udma_mask = 0x7f, /* udma0-6 */ | 487 | .udma_mask = 0x7f, /* udma0-6 */ |
506 | .port_ops = &piix_sata_ops, | 488 | .port_ops = &piix_sata_ops, |
507 | }, | 489 | }, |
508 | 490 | ||
509 | /* ich6_sata: 7 */ | 491 | /* ich6_sata: 6 */ |
510 | { | 492 | { |
511 | .sht = &piix_sht, | 493 | .sht = &piix_sht, |
512 | .flags = ATA_FLAG_SATA | | 494 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR, |
513 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR, | ||
514 | .pio_mask = 0x1f, /* pio0-4 */ | 495 | .pio_mask = 0x1f, /* pio0-4 */ |
515 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 496 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
516 | .udma_mask = 0x7f, /* udma0-6 */ | 497 | .udma_mask = 0x7f, /* udma0-6 */ |
517 | .port_ops = &piix_sata_ops, | 498 | .port_ops = &piix_sata_ops, |
518 | }, | 499 | }, |
519 | 500 | ||
520 | /* ich6_sata_ahci: 8 */ | 501 | /* ich6_sata_ahci: 7 */ |
521 | { | 502 | { |
522 | .sht = &piix_sht, | 503 | .sht = &piix_sht, |
523 | .flags = ATA_FLAG_SATA | | 504 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | |
524 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | | ||
525 | PIIX_FLAG_AHCI, | 505 | PIIX_FLAG_AHCI, |
526 | .pio_mask = 0x1f, /* pio0-4 */ | 506 | .pio_mask = 0x1f, /* pio0-4 */ |
527 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 507 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
@@ -529,11 +509,10 @@ static struct ata_port_info piix_port_info[] = { | |||
529 | .port_ops = &piix_sata_ops, | 509 | .port_ops = &piix_sata_ops, |
530 | }, | 510 | }, |
531 | 511 | ||
532 | /* ich6m_sata_ahci: 9 */ | 512 | /* ich6m_sata_ahci: 8 */ |
533 | { | 513 | { |
534 | .sht = &piix_sht, | 514 | .sht = &piix_sht, |
535 | .flags = ATA_FLAG_SATA | | 515 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | |
536 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | | ||
537 | PIIX_FLAG_AHCI, | 516 | PIIX_FLAG_AHCI, |
538 | .pio_mask = 0x1f, /* pio0-4 */ | 517 | .pio_mask = 0x1f, /* pio0-4 */ |
539 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 518 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
@@ -541,11 +520,10 @@ static struct ata_port_info piix_port_info[] = { | |||
541 | .port_ops = &piix_sata_ops, | 520 | .port_ops = &piix_sata_ops, |
542 | }, | 521 | }, |
543 | 522 | ||
544 | /* ich8_sata_ahci: 10 */ | 523 | /* ich8_sata_ahci: 9 */ |
545 | { | 524 | { |
546 | .sht = &piix_sht, | 525 | .sht = &piix_sht, |
547 | .flags = ATA_FLAG_SATA | | 526 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | |
548 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | | ||
549 | PIIX_FLAG_AHCI, | 527 | PIIX_FLAG_AHCI, |
550 | .pio_mask = 0x1f, /* pio0-4 */ | 528 | .pio_mask = 0x1f, /* pio0-4 */ |
551 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 529 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
@@ -566,10 +544,22 @@ MODULE_LICENSE("GPL"); | |||
566 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); | 544 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); |
567 | MODULE_VERSION(DRV_VERSION); | 545 | MODULE_VERSION(DRV_VERSION); |
568 | 546 | ||
569 | static int force_pcs = 0; | 547 | struct ich_laptop { |
570 | module_param(force_pcs, int, 0444); | 548 | u16 device; |
571 | MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around " | 549 | u16 subvendor; |
572 | "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)"); | 550 | u16 subdevice; |
551 | }; | ||
552 | |||
553 | /* | ||
554 | * List of laptops that use short cables rather than 80 wire | ||
555 | */ | ||
556 | |||
557 | static const struct ich_laptop ich_laptop[] = { | ||
558 | /* devid, subvendor, subdev */ | ||
559 | { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */ | ||
560 | /* end marker */ | ||
561 | { 0, } | ||
562 | }; | ||
573 | 563 | ||
574 | /** | 564 | /** |
575 | * piix_pata_cbl_detect - Probe host controller cable detect info | 565 | * piix_pata_cbl_detect - Probe host controller cable detect info |
@@ -585,12 +575,24 @@ MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around " | |||
585 | static void ich_pata_cbl_detect(struct ata_port *ap) | 575 | static void ich_pata_cbl_detect(struct ata_port *ap) |
586 | { | 576 | { |
587 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 577 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
578 | const struct ich_laptop *lap = &ich_laptop[0]; | ||
588 | u8 tmp, mask; | 579 | u8 tmp, mask; |
589 | 580 | ||
590 | /* no 80c support in host controller? */ | 581 | /* no 80c support in host controller? */ |
591 | if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0) | 582 | if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0) |
592 | goto cbl40; | 583 | goto cbl40; |
593 | 584 | ||
585 | /* Check for specials - Acer Aspire 5602WLMi */ | ||
586 | while (lap->device) { | ||
587 | if (lap->device == pdev->device && | ||
588 | lap->subvendor == pdev->subsystem_vendor && | ||
589 | lap->subdevice == pdev->subsystem_device) { | ||
590 | ap->cbl = ATA_CBL_PATA40_SHORT; | ||
591 | return; | ||
592 | } | ||
593 | lap++; | ||
594 | } | ||
595 | |||
594 | /* check BIOS cable detect results */ | 596 | /* check BIOS cable detect results */ |
595 | mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; | 597 | mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; |
596 | pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); | 598 | pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); |
@@ -659,84 +661,9 @@ static void ich_pata_error_handler(struct ata_port *ap) | |||
659 | ata_std_postreset); | 661 | ata_std_postreset); |
660 | } | 662 | } |
661 | 663 | ||
662 | /** | ||
663 | * piix_sata_present_mask - determine present mask for SATA host controller | ||
664 | * @ap: Target port | ||
665 | * | ||
666 | * Reads SATA PCI device's PCI config register Port Configuration | ||
667 | * and Status (PCS) to determine port and device availability. | ||
668 | * | ||
669 | * LOCKING: | ||
670 | * None (inherited from caller). | ||
671 | * | ||
672 | * RETURNS: | ||
673 | * determined present_mask | ||
674 | */ | ||
675 | static unsigned int piix_sata_present_mask(struct ata_port *ap) | ||
676 | { | ||
677 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
678 | struct piix_host_priv *hpriv = ap->host->private_data; | ||
679 | const unsigned int *map = hpriv->map; | ||
680 | int base = 2 * ap->port_no; | ||
681 | unsigned int present_mask = 0; | ||
682 | int port, i; | ||
683 | u16 pcs; | ||
684 | |||
685 | pci_read_config_word(pdev, ICH5_PCS, &pcs); | ||
686 | DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base); | ||
687 | |||
688 | for (i = 0; i < 2; i++) { | ||
689 | port = map[base + i]; | ||
690 | if (port < 0) | ||
691 | continue; | ||
692 | if ((ap->flags & PIIX_FLAG_IGNORE_PCS) || | ||
693 | (pcs & 1 << (hpriv->map_db->present_shift + port))) | ||
694 | present_mask |= 1 << i; | ||
695 | } | ||
696 | |||
697 | DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", | ||
698 | ap->id, pcs, present_mask); | ||
699 | |||
700 | return present_mask; | ||
701 | } | ||
702 | |||
703 | /** | ||
704 | * piix_sata_softreset - reset SATA host port via ATA SRST | ||
705 | * @ap: port to reset | ||
706 | * @classes: resulting classes of attached devices | ||
707 | * | ||
708 | * Reset SATA host port via ATA SRST. On controllers with | ||
709 | * reliable PCS present bits, the bits are used to determine | ||
710 | * device presence. | ||
711 | * | ||
712 | * LOCKING: | ||
713 | * Kernel thread context (may sleep) | ||
714 | * | ||
715 | * RETURNS: | ||
716 | * 0 on success, -errno otherwise. | ||
717 | */ | ||
718 | static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes) | ||
719 | { | ||
720 | unsigned int present_mask; | ||
721 | int i, rc; | ||
722 | |||
723 | present_mask = piix_sata_present_mask(ap); | ||
724 | |||
725 | rc = ata_std_softreset(ap, classes); | ||
726 | if (rc) | ||
727 | return rc; | ||
728 | |||
729 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
730 | if (!(present_mask & (1 << i))) | ||
731 | classes[i] = ATA_DEV_NONE; | ||
732 | } | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static void piix_sata_error_handler(struct ata_port *ap) | 664 | static void piix_sata_error_handler(struct ata_port *ap) |
738 | { | 665 | { |
739 | ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL, | 666 | ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL, |
740 | ata_std_postreset); | 667 | ata_std_postreset); |
741 | } | 668 | } |
742 | 669 | ||
@@ -1051,18 +978,6 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev, | |||
1051 | pci_write_config_word(pdev, ICH5_PCS, new_pcs); | 978 | pci_write_config_word(pdev, ICH5_PCS, new_pcs); |
1052 | msleep(150); | 979 | msleep(150); |
1053 | } | 980 | } |
1054 | |||
1055 | if (force_pcs == 1) { | ||
1056 | dev_printk(KERN_INFO, &pdev->dev, | ||
1057 | "force ignoring PCS (0x%x)\n", new_pcs); | ||
1058 | pinfo[0].flags |= PIIX_FLAG_IGNORE_PCS; | ||
1059 | pinfo[1].flags |= PIIX_FLAG_IGNORE_PCS; | ||
1060 | } else if (force_pcs == 2) { | ||
1061 | dev_printk(KERN_INFO, &pdev->dev, | ||
1062 | "force honoring PCS (0x%x)\n", new_pcs); | ||
1063 | pinfo[0].flags &= ~PIIX_FLAG_IGNORE_PCS; | ||
1064 | pinfo[1].flags &= ~PIIX_FLAG_IGNORE_PCS; | ||
1065 | } | ||
1066 | } | 981 | } |
1067 | 982 | ||
1068 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, | 983 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, |
@@ -1112,7 +1027,6 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, | |||
1112 | "invalid MAP value %u\n", map_value); | 1027 | "invalid MAP value %u\n", map_value); |
1113 | 1028 | ||
1114 | hpriv->map = map; | 1029 | hpriv->map = map; |
1115 | hpriv->map_db = map_db; | ||
1116 | } | 1030 | } |
1117 | 1031 | ||
1118 | /** | 1032 | /** |