aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-04-02 04:54:46 -0400
committerJeff Garzik <jeff@garzik.org>2006-04-02 10:02:57 -0400
commit14d2bac1877ed4e2cc940d1680db1a4f29225811 (patch)
tree60b478485e7453dd5a41aea34699a305dd3c8d2c /drivers
parentcf176e1aa92eb2a3faea8409e841396a66413937 (diff)
[PATCH] libata: improve ata_bus_probe()
Improve ata_bus_probe() such that configuration failures are handled better. Each device is given ATA_PROBE_MAX_TRIES chances, but any non-transient error (revalidation failure with -ENODEV, configuration failure with -EINVAL...) disables the device directly. Any IO error results in SATA PHY speed down and ata_set_mode() failure lowers transfer mode. The last try always puts a device into PIO-0. After each failure, the whole port is reset to make sure that the controller and all the devices are in a known and stable state. The reset also applies SATA SPD configuration if necessary. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/libata-core.c65
1 files changed, 49 insertions, 16 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 68fa64d2472..33b5bff58cc 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1370,11 +1370,18 @@ err_out_nosup:
1370static int ata_bus_probe(struct ata_port *ap) 1370static int ata_bus_probe(struct ata_port *ap)
1371{ 1371{
1372 unsigned int classes[ATA_MAX_DEVICES]; 1372 unsigned int classes[ATA_MAX_DEVICES];
1373 int i, rc, found = 0; 1373 int tries[ATA_MAX_DEVICES];
1374 int i, rc, down_xfermask;
1374 struct ata_device *dev; 1375 struct ata_device *dev;
1375 1376
1376 ata_port_probe(ap); 1377 ata_port_probe(ap);
1377 1378
1379 for (i = 0; i < ATA_MAX_DEVICES; i++)
1380 tries[i] = ATA_PROBE_MAX_TRIES;
1381
1382 retry:
1383 down_xfermask = 0;
1384
1378 /* reset and determine device classes */ 1385 /* reset and determine device classes */
1379 for (i = 0; i < ATA_MAX_DEVICES; i++) 1386 for (i = 0; i < ATA_MAX_DEVICES; i++)
1380 classes[i] = ATA_DEV_UNKNOWN; 1387 classes[i] = ATA_DEV_UNKNOWN;
@@ -1404,21 +1411,23 @@ static int ata_bus_probe(struct ata_port *ap)
1404 dev = &ap->device[i]; 1411 dev = &ap->device[i];
1405 dev->class = classes[i]; 1412 dev->class = classes[i];
1406 1413
1407 if (!ata_dev_enabled(dev)) 1414 if (!tries[i]) {
1408 continue; 1415 ata_down_xfermask_limit(ap, dev, 1);
1409 1416 ata_dev_disable(ap, dev);
1410 WARN_ON(dev->id != NULL);
1411 if (ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id)) {
1412 dev->class = ATA_DEV_NONE;
1413 continue;
1414 } 1417 }
1415 1418
1416 if (ata_dev_configure(ap, dev, 1)) { 1419 if (!ata_dev_enabled(dev))
1417 ata_dev_disable(ap, dev);
1418 continue; 1420 continue;
1419 }
1420 1421
1421 found = 1; 1422 kfree(dev->id);
1423 dev->id = NULL;
1424 rc = ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id);
1425 if (rc)
1426 goto fail;
1427
1428 rc = ata_dev_configure(ap, dev, 1);
1429 if (rc)
1430 goto fail;
1422 } 1431 }
1423 1432
1424 /* configure transfer mode */ 1433 /* configure transfer mode */
@@ -1427,12 +1436,18 @@ static int ata_bus_probe(struct ata_port *ap)
1427 * return error code and failing device on failure as 1436 * return error code and failing device on failure as
1428 * ata_set_mode() does. 1437 * ata_set_mode() does.
1429 */ 1438 */
1430 if (found) 1439 for (i = 0; i < ATA_MAX_DEVICES; i++)
1431 ap->ops->set_mode(ap); 1440 if (ata_dev_enabled(&ap->device[i])) {
1441 ap->ops->set_mode(ap);
1442 break;
1443 }
1432 rc = 0; 1444 rc = 0;
1433 } else { 1445 } else {
1434 while (ata_set_mode(ap, &dev)) 1446 rc = ata_set_mode(ap, &dev);
1435 ata_dev_disable(ap, dev); 1447 if (rc) {
1448 down_xfermask = 1;
1449 goto fail;
1450 }
1436 } 1451 }
1437 1452
1438 for (i = 0; i < ATA_MAX_DEVICES; i++) 1453 for (i = 0; i < ATA_MAX_DEVICES; i++)
@@ -1443,6 +1458,24 @@ static int ata_bus_probe(struct ata_port *ap)
1443 ata_port_disable(ap); 1458 ata_port_disable(ap);
1444 ap->ops->port_disable(ap); 1459 ap->ops->port_disable(ap);
1445 return -ENODEV; 1460 return -ENODEV;
1461
1462 fail:
1463 switch (rc) {
1464 case -EINVAL:
1465 case -ENODEV:
1466 tries[dev->devno] = 0;
1467 break;
1468 case -EIO:
1469 ata_down_sata_spd_limit(ap);
1470 /* fall through */
1471 default:
1472 tries[dev->devno]--;
1473 if (down_xfermask &&
1474 ata_down_xfermask_limit(ap, dev, tries[dev->devno] == 1))
1475 tries[dev->devno] = 0;
1476 }
1477
1478 goto retry;
1446} 1479}
1447 1480
1448/** 1481/**