aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ata_piix.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 4080b8be847b..72e38e6ea756 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -499,44 +499,59 @@ static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes)
499 * piix_sata_probe - Probe PCI device for present SATA devices 499 * piix_sata_probe - Probe PCI device for present SATA devices
500 * @ap: Port associated with the PCI device we wish to probe 500 * @ap: Port associated with the PCI device we wish to probe
501 * 501 *
502 * Reads SATA PCI device's PCI config register Port Configuration 502 * Reads and configures SATA PCI device's PCI config register
503 * and Status (PCS) to determine port and device availability. 503 * Port Configuration and Status (PCS) to determine port and
504 * device availability.
504 * 505 *
505 * LOCKING: 506 * LOCKING:
506 * None (inherited from caller). 507 * None (inherited from caller).
507 * 508 *
508 * RETURNS: 509 * RETURNS:
509 * Non-zero if port is enabled, it may or may not have a device 510 * Mask of avaliable devices on the port.
510 * attached in that case (PRESENT bit would only be set if BIOS probe
511 * was done). Zero is returned if port is disabled.
512 */ 511 */
513static int piix_sata_probe (struct ata_port *ap) 512static unsigned int piix_sata_probe (struct ata_port *ap)
514{ 513{
515 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); 514 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
516 int combined = (ap->flags & ATA_FLAG_SLAVE_POSS); 515 const unsigned int *map = ap->host_set->private_data;
517 int orig_mask, mask, i; 516 int base = 2 * ap->hard_port_no;
517 unsigned int present_mask = 0;
518 int port, i;
518 u8 pcs; 519 u8 pcs;
519 520
520 pci_read_config_byte(pdev, ICH5_PCS, &pcs); 521 pci_read_config_byte(pdev, ICH5_PCS, &pcs);
521 orig_mask = (int) pcs & 0xff; 522 DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
522
523 /* TODO: this is vaguely wrong for ICH6 combined mode,
524 * where only two of the four SATA ports are mapped
525 * onto a single ATA channel. It is also vaguely inaccurate
526 * for ICH5, which has only two ports. However, this is ok,
527 * as further device presence detection code will handle
528 * any false positives produced here.
529 */
530 523
531 for (i = 0; i < 4; i++) { 524 /* enable all ports on this ap and wait for them to settle */
532 mask = (PIIX_PORT_ENABLED << i); 525 for (i = 0; i < 2; i++) {
526 port = map[base + i];
527 if (port >= 0)
528 pcs |= 1 << port;
529 }
533 530
534 if ((orig_mask & mask) == mask) 531 pci_write_config_byte(pdev, ICH5_PCS, pcs);
535 if (combined || (i == ap->hard_port_no)) 532 msleep(100);
536 return 1; 533
534 /* let's see which devices are present */
535 pci_read_config_byte(pdev, ICH5_PCS, &pcs);
536
537 for (i = 0; i < 2; i++) {
538 port = map[base + i];
539 if (port < 0)
540 continue;
541 if (ap->flags & PIIX_FLAG_IGN_PRESENT || pcs & 1 << (4 + port))
542 present_mask |= 1 << i;
543 else
544 pcs &= ~(1 << port);
537 } 545 }
538 546
539 return 0; 547 /* disable offline ports on non-AHCI controllers */
548 if (!(ap->flags & PIIX_FLAG_AHCI))
549 pci_write_config_byte(pdev, ICH5_PCS, pcs);
550
551 DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
552 ap->id, pcs, present_mask);
553
554 return present_mask;
540} 555}
541 556
542/** 557/**