aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-31 05:28:03 -0400
committerTejun Heo <htejun@gmail.com>2006-05-31 05:28:03 -0400
commit084fe639b81c4d418a2cf714acb0475e3713cb73 (patch)
tree55afc26dbb866488b69e49b1742863d1293f6612 /drivers
parent0ea035a3d1ad948096e205f08f350c03d5cea453 (diff)
[PATCH] libata-hp: implement hotplug
Implement ATA part of hotplug. To avoid probing broken devices over and over again, disabled devices are not automatically detached. They are detached only if probing is requested for the device or the associated port is offline. Also, to avoid infinite probing loop, Each device is probed only once per EH run. As SATA PHY status is fragile, devices are detached only after it has used up its recovery chances unless explicitly requested by LLDD or user (LLDD may request direct detach if, for example, it supports cold presence detection). Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/libata-eh.c123
1 files changed, 102 insertions, 21 deletions
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index a049bffdf770..b53e2e7db498 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -932,10 +932,8 @@ static void ata_eh_analyze_serror(struct ata_port *ap)
932 err_mask |= AC_ERR_SYSTEM; 932 err_mask |= AC_ERR_SYSTEM;
933 action |= ATA_EH_SOFTRESET; 933 action |= ATA_EH_SOFTRESET;
934 } 934 }
935 if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG)) { 935 if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG))
936 err_mask |= AC_ERR_ATA_BUS; 936 ata_ehi_hotplugged(&ehc->i);
937 action |= ATA_EH_HARDRESET;
938 }
939 937
940 ehc->i.err_mask |= err_mask; 938 ehc->i.err_mask |= err_mask;
941 ehc->i.action |= action; 939 ehc->i.action |= action;
@@ -1487,11 +1485,12 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
1487 return rc; 1485 return rc;
1488} 1486}
1489 1487
1490static int ata_eh_revalidate(struct ata_port *ap, 1488static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1491 struct ata_device **r_failed_dev) 1489 struct ata_device **r_failed_dev)
1492{ 1490{
1493 struct ata_eh_context *ehc = &ap->eh_context; 1491 struct ata_eh_context *ehc = &ap->eh_context;
1494 struct ata_device *dev; 1492 struct ata_device *dev;
1493 unsigned long flags;
1495 int i, rc = 0; 1494 int i, rc = 0;
1496 1495
1497 DPRINTK("ENTER\n"); 1496 DPRINTK("ENTER\n");
@@ -1513,6 +1512,23 @@ static int ata_eh_revalidate(struct ata_port *ap,
1513 break; 1512 break;
1514 1513
1515 ehc->i.action &= ~ATA_EH_REVALIDATE; 1514 ehc->i.action &= ~ATA_EH_REVALIDATE;
1515 } else if (dev->class == ATA_DEV_UNKNOWN &&
1516 ehc->tries[dev->devno] &&
1517 ata_class_enabled(ehc->classes[dev->devno])) {
1518 dev->class = ehc->classes[dev->devno];
1519
1520 rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
1521 if (rc == 0)
1522 rc = ata_dev_configure(dev, 1);
1523
1524 if (rc) {
1525 dev->class = ATA_DEV_UNKNOWN;
1526 break;
1527 }
1528
1529 spin_lock_irqsave(&ap->host_set->lock, flags);
1530 ap->flags |= ATA_FLAG_SCSI_HOTPLUG;
1531 spin_unlock_irqrestore(&ap->host_set->lock, flags);
1516 } 1532 }
1517 } 1533 }
1518 1534
@@ -1533,6 +1549,36 @@ static int ata_port_nr_enabled(struct ata_port *ap)
1533 return cnt; 1549 return cnt;
1534} 1550}
1535 1551
1552static int ata_port_nr_vacant(struct ata_port *ap)
1553{
1554 int i, cnt = 0;
1555
1556 for (i = 0; i < ATA_MAX_DEVICES; i++)
1557 if (ap->device[i].class == ATA_DEV_UNKNOWN)
1558 cnt++;
1559 return cnt;
1560}
1561
1562static int ata_eh_skip_recovery(struct ata_port *ap)
1563{
1564 struct ata_eh_context *ehc = &ap->eh_context;
1565 int i;
1566
1567 if (ap->flags & ATA_FLAG_FROZEN || ata_port_nr_enabled(ap))
1568 return 0;
1569
1570 /* skip if class codes for all vacant slots are ATA_DEV_NONE */
1571 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1572 struct ata_device *dev = &ap->device[i];
1573
1574 if (dev->class == ATA_DEV_UNKNOWN &&
1575 ehc->classes[dev->devno] != ATA_DEV_NONE)
1576 return 0;
1577 }
1578
1579 return 1;
1580}
1581
1536/** 1582/**
1537 * ata_eh_recover - recover host port after error 1583 * ata_eh_recover - recover host port after error
1538 * @ap: host port to recover 1584 * @ap: host port to recover
@@ -1543,9 +1589,10 @@ static int ata_port_nr_enabled(struct ata_port *ap)
1543 * 1589 *
1544 * This is the alpha and omega, eum and yang, heart and soul of 1590 * This is the alpha and omega, eum and yang, heart and soul of
1545 * libata exception handling. On entry, actions required to 1591 * libata exception handling. On entry, actions required to
1546 * recover each devices are recorded in eh_context. This 1592 * recover the port and hotplug requests are recorded in
1547 * function executes all the operations with appropriate retrials 1593 * eh_context. This function executes all the operations with
1548 * and fallbacks to resurrect failed devices. 1594 * appropriate retrials and fallbacks to resurrect failed
1595 * devices, detach goners and greet newcomers.
1549 * 1596 *
1550 * LOCKING: 1597 * LOCKING:
1551 * Kernel thread context (may sleep). 1598 * Kernel thread context (may sleep).
@@ -1568,6 +1615,19 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1568 dev = &ap->device[i]; 1615 dev = &ap->device[i];
1569 1616
1570 ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; 1617 ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
1618
1619 /* process hotplug request */
1620 if (dev->flags & ATA_DFLAG_DETACH)
1621 ata_eh_detach_dev(dev);
1622
1623 if (!ata_dev_enabled(dev) &&
1624 ((ehc->i.probe_mask & (1 << dev->devno)) &&
1625 !(ehc->did_probe_mask & (1 << dev->devno)))) {
1626 ata_eh_detach_dev(dev);
1627 ata_dev_init(dev);
1628 ehc->did_probe_mask |= (1 << dev->devno);
1629 ehc->i.action |= ATA_EH_SOFTRESET;
1630 }
1571 } 1631 }
1572 1632
1573 retry: 1633 retry:
@@ -1575,15 +1635,18 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1575 rc = 0; 1635 rc = 0;
1576 1636
1577 /* skip EH if possible. */ 1637 /* skip EH if possible. */
1578 if (!ata_port_nr_enabled(ap) && !(ap->flags & ATA_FLAG_FROZEN)) 1638 if (ata_eh_skip_recovery(ap))
1579 ehc->i.action = 0; 1639 ehc->i.action = 0;
1580 1640
1641 for (i = 0; i < ATA_MAX_DEVICES; i++)
1642 ehc->classes[i] = ATA_DEV_UNKNOWN;
1643
1581 /* reset */ 1644 /* reset */
1582 if (ehc->i.action & ATA_EH_RESET_MASK) { 1645 if (ehc->i.action & ATA_EH_RESET_MASK) {
1583 ata_eh_freeze_port(ap); 1646 ata_eh_freeze_port(ap);
1584 1647
1585 rc = ata_eh_reset(ap, 0, prereset, softreset, hardreset, 1648 rc = ata_eh_reset(ap, ata_port_nr_vacant(ap), prereset,
1586 postreset); 1649 softreset, hardreset, postreset);
1587 if (rc) { 1650 if (rc) {
1588 ata_port_printk(ap, KERN_ERR, 1651 ata_port_printk(ap, KERN_ERR,
1589 "reset failed, giving up\n"); 1652 "reset failed, giving up\n");
@@ -1593,8 +1656,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1593 ata_eh_thaw_port(ap); 1656 ata_eh_thaw_port(ap);
1594 } 1657 }
1595 1658
1596 /* revalidate existing devices */ 1659 /* revalidate existing devices and attach new ones */
1597 rc = ata_eh_revalidate(ap, &dev); 1660 rc = ata_eh_revalidate_and_attach(ap, &dev);
1598 if (rc) 1661 if (rc)
1599 goto dev_fail; 1662 goto dev_fail;
1600 1663
@@ -1612,6 +1675,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1612 dev_fail: 1675 dev_fail:
1613 switch (rc) { 1676 switch (rc) {
1614 case -ENODEV: 1677 case -ENODEV:
1678 /* device missing, schedule probing */
1679 ehc->i.probe_mask |= (1 << dev->devno);
1615 case -EINVAL: 1680 case -EINVAL:
1616 ehc->tries[dev->devno] = 0; 1681 ehc->tries[dev->devno] = 0;
1617 break; 1682 break;
@@ -1624,15 +1689,31 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1624 ehc->tries[dev->devno] = 0; 1689 ehc->tries[dev->devno] = 0;
1625 } 1690 }
1626 1691
1627 /* disable device if it has used up all its chances */ 1692 if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
1628 if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) 1693 /* disable device if it has used up all its chances */
1629 ata_dev_disable(dev); 1694 ata_dev_disable(dev);
1630 1695
1631 /* soft didn't work? be haaaaard */ 1696 /* detach if offline */
1632 if (ehc->i.flags & ATA_EHI_DID_RESET) 1697 if (ata_port_offline(ap))
1633 ehc->i.action |= ATA_EH_HARDRESET; 1698 ata_eh_detach_dev(dev);
1634 else 1699
1635 ehc->i.action |= ATA_EH_SOFTRESET; 1700 /* probe if requested */
1701 if ((ehc->i.probe_mask & (1 << dev->devno)) &&
1702 !(ehc->did_probe_mask & (1 << dev->devno))) {
1703 ata_eh_detach_dev(dev);
1704 ata_dev_init(dev);
1705
1706 ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
1707 ehc->did_probe_mask |= (1 << dev->devno);
1708 ehc->i.action |= ATA_EH_SOFTRESET;
1709 }
1710 } else {
1711 /* soft didn't work? be haaaaard */
1712 if (ehc->i.flags & ATA_EHI_DID_RESET)
1713 ehc->i.action |= ATA_EH_HARDRESET;
1714 else
1715 ehc->i.action |= ATA_EH_SOFTRESET;
1716 }
1636 1717
1637 if (ata_port_nr_enabled(ap)) { 1718 if (ata_port_nr_enabled(ap)) {
1638 ata_port_printk(ap, KERN_WARNING, "failed to recover some " 1719 ata_port_printk(ap, KERN_WARNING, "failed to recover some "