diff options
| -rw-r--r-- | drivers/scsi/ata_piix.c | 60 | 
1 files changed, 43 insertions, 17 deletions
| diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 5e8afc876980..01b3530cf6df 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
| @@ -531,27 +531,25 @@ static void piix_pata_error_handler(struct ata_port *ap) | |||
| 531 | } | 531 | } | 
| 532 | 532 | ||
| 533 | /** | 533 | /** | 
| 534 | * piix_sata_prereset - prereset for SATA host controller | 534 | * piix_sata_present_mask - determine present mask for SATA host controller | 
| 535 | * @ap: Target port | 535 | * @ap: Target port | 
| 536 | * | 536 | * | 
| 537 | * Reads and configures SATA PCI device's PCI config register | 537 | * Reads SATA PCI device's PCI config register Port Configuration | 
| 538 | * Port Configuration and Status (PCS) to determine port and | 538 | * and Status (PCS) to determine port and device availability. | 
| 539 | * device availability. Return -ENODEV to skip reset if no | ||
| 540 | * device is present. | ||
| 541 | * | 539 | * | 
| 542 | * LOCKING: | 540 | * LOCKING: | 
| 543 | * None (inherited from caller). | 541 | * None (inherited from caller). | 
| 544 | * | 542 | * | 
| 545 | * RETURNS: | 543 | * RETURNS: | 
| 546 | * 0 if device is present, -ENODEV otherwise. | 544 | * determined present_mask | 
| 547 | */ | 545 | */ | 
| 548 | static int piix_sata_prereset(struct ata_port *ap) | 546 | static unsigned int piix_sata_present_mask(struct ata_port *ap) | 
| 549 | { | 547 | { | 
| 550 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); | 548 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); | 
| 551 | struct piix_host_priv *hpriv = ap->host_set->private_data; | 549 | struct piix_host_priv *hpriv = ap->host_set->private_data; | 
| 552 | const unsigned int *map = hpriv->map; | 550 | const unsigned int *map = hpriv->map; | 
| 553 | int base = 2 * ap->hard_port_no; | 551 | int base = 2 * ap->hard_port_no; | 
| 554 | unsigned int present = 0; | 552 | unsigned int present_mask = 0; | 
| 555 | int port, i; | 553 | int port, i; | 
| 556 | u16 pcs; | 554 | u16 pcs; | 
| 557 | 555 | ||
| @@ -564,24 +562,52 @@ static int piix_sata_prereset(struct ata_port *ap) | |||
| 564 | continue; | 562 | continue; | 
| 565 | if ((ap->flags & PIIX_FLAG_IGNORE_PCS) || | 563 | if ((ap->flags & PIIX_FLAG_IGNORE_PCS) || | 
| 566 | (pcs & 1 << (hpriv->map_db->present_shift + port))) | 564 | (pcs & 1 << (hpriv->map_db->present_shift + port))) | 
| 567 | present = 1; | 565 | present_mask |= 1 << i; | 
| 568 | } | 566 | } | 
| 569 | 567 | ||
| 570 | DPRINTK("ata%u: LEAVE, pcs=0x%x present=0x%x\n", | 568 | DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", | 
| 571 | ap->id, pcs, present); | 569 | ap->id, pcs, present_mask); | 
| 572 | 570 | ||
| 573 | if (!present) { | 571 | return present_mask; | 
| 574 | ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); | 572 | } | 
| 575 | ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; | 573 | |
| 576 | return 0; | 574 | /** | 
| 575 | * piix_sata_softreset - reset SATA host port via ATA SRST | ||
| 576 | * @ap: port to reset | ||
| 577 | * @classes: resulting classes of attached devices | ||
| 578 | * | ||
| 579 | * Reset SATA host port via ATA SRST. On controllers with | ||
| 580 | * reliable PCS present bits, the bits are used to determine | ||
| 581 | * device presence. | ||
| 582 | * | ||
| 583 | * LOCKING: | ||
| 584 | * Kernel thread context (may sleep) | ||
| 585 | * | ||
| 586 | * RETURNS: | ||
| 587 | * 0 on success, -errno otherwise. | ||
| 588 | */ | ||
| 589 | static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes) | ||
| 590 | { | ||
| 591 | unsigned int present_mask; | ||
| 592 | int i, rc; | ||
| 593 | |||
| 594 | present_mask = piix_sata_present_mask(ap); | ||
| 595 | |||
| 596 | rc = ata_std_softreset(ap, classes); | ||
| 597 | if (rc) | ||
| 598 | return rc; | ||
| 599 | |||
| 600 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
| 601 | if (!(present_mask & (1 << i))) | ||
| 602 | classes[i] = ATA_DEV_NONE; | ||
| 577 | } | 603 | } | 
| 578 | 604 | ||
| 579 | return ata_std_prereset(ap); | 605 | return 0; | 
| 580 | } | 606 | } | 
| 581 | 607 | ||
| 582 | static void piix_sata_error_handler(struct ata_port *ap) | 608 | static void piix_sata_error_handler(struct ata_port *ap) | 
| 583 | { | 609 | { | 
| 584 | ata_bmdma_drive_eh(ap, piix_sata_prereset, ata_std_softreset, NULL, | 610 | ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL, | 
| 585 | ata_std_postreset); | 611 | ata_std_postreset); | 
| 586 | } | 612 | } | 
| 587 | 613 | ||
