diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
| -rw-r--r-- | drivers/ata/libata-eh.c | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 7349c3dbf774..39f556c02992 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -982,26 +982,27 @@ static int ata_eh_read_log_10h(struct ata_device *dev, | |||
| 982 | * RETURNS: | 982 | * RETURNS: |
| 983 | * 0 on success, AC_ERR_* mask on failure | 983 | * 0 on success, AC_ERR_* mask on failure |
| 984 | */ | 984 | */ |
| 985 | static unsigned int atapi_eh_request_sense(struct ata_device *dev, | 985 | static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc) |
| 986 | unsigned char *sense_buf) | ||
| 987 | { | 986 | { |
| 987 | struct ata_device *dev = qc->dev; | ||
| 988 | unsigned char *sense_buf = qc->scsicmd->sense_buffer; | ||
| 988 | struct ata_port *ap = dev->ap; | 989 | struct ata_port *ap = dev->ap; |
| 989 | struct ata_taskfile tf; | 990 | struct ata_taskfile tf; |
| 990 | u8 cdb[ATAPI_CDB_LEN]; | 991 | u8 cdb[ATAPI_CDB_LEN]; |
| 991 | 992 | ||
| 992 | DPRINTK("ATAPI request sense\n"); | 993 | DPRINTK("ATAPI request sense\n"); |
| 993 | 994 | ||
| 994 | ata_tf_init(dev, &tf); | ||
| 995 | |||
| 996 | /* FIXME: is this needed? */ | 995 | /* FIXME: is this needed? */ |
| 997 | memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); | 996 | memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); |
| 998 | 997 | ||
| 999 | /* XXX: why tf_read here? */ | 998 | /* initialize sense_buf with the error register, |
| 1000 | ap->ops->tf_read(ap, &tf); | 999 | * for the case where they are -not- overwritten |
| 1001 | 1000 | */ | |
| 1002 | /* fill these in, for the case where they are -not- overwritten */ | ||
| 1003 | sense_buf[0] = 0x70; | 1001 | sense_buf[0] = 0x70; |
| 1004 | sense_buf[2] = tf.feature >> 4; | 1002 | sense_buf[2] = qc->result_tf.feature >> 4; |
| 1003 | |||
| 1004 | /* some devices time out if garbage left in tf */ | ||
| 1005 | ata_tf_init(dev, &tf); | ||
| 1005 | 1006 | ||
| 1006 | memset(cdb, 0, ATAPI_CDB_LEN); | 1007 | memset(cdb, 0, ATAPI_CDB_LEN); |
| 1007 | cdb[0] = REQUEST_SENSE; | 1008 | cdb[0] = REQUEST_SENSE; |
| @@ -1165,8 +1166,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, | |||
| 1165 | 1166 | ||
| 1166 | case ATA_DEV_ATAPI: | 1167 | case ATA_DEV_ATAPI: |
| 1167 | if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) { | 1168 | if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) { |
| 1168 | tmp = atapi_eh_request_sense(qc->dev, | 1169 | tmp = atapi_eh_request_sense(qc); |
| 1169 | qc->scsicmd->sense_buffer); | ||
| 1170 | if (!tmp) { | 1170 | if (!tmp) { |
| 1171 | /* ATA_QCFLAG_SENSE_VALID is used to | 1171 | /* ATA_QCFLAG_SENSE_VALID is used to |
| 1172 | * tell atapi_qc_complete() that sense | 1172 | * tell atapi_qc_complete() that sense |
| @@ -1625,8 +1625,14 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
| 1625 | rc = prereset(ap); | 1625 | rc = prereset(ap); |
| 1626 | if (rc) { | 1626 | if (rc) { |
| 1627 | if (rc == -ENOENT) { | 1627 | if (rc == -ENOENT) { |
| 1628 | ata_port_printk(ap, KERN_DEBUG, "port disabled. ignoring.\n"); | 1628 | ata_port_printk(ap, KERN_DEBUG, |
| 1629 | "port disabled. ignoring.\n"); | ||
| 1629 | ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; | 1630 | ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; |
| 1631 | |||
| 1632 | for (i = 0; i < ATA_MAX_DEVICES; i++) | ||
| 1633 | classes[i] = ATA_DEV_NONE; | ||
| 1634 | |||
| 1635 | rc = 0; | ||
| 1630 | } else | 1636 | } else |
| 1631 | ata_port_printk(ap, KERN_ERR, | 1637 | ata_port_printk(ap, KERN_ERR, |
| 1632 | "prereset failed (errno=%d)\n", rc); | 1638 | "prereset failed (errno=%d)\n", rc); |
| @@ -1737,12 +1743,17 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
| 1737 | { | 1743 | { |
| 1738 | struct ata_eh_context *ehc = &ap->eh_context; | 1744 | struct ata_eh_context *ehc = &ap->eh_context; |
| 1739 | struct ata_device *dev; | 1745 | struct ata_device *dev; |
| 1746 | unsigned int new_mask = 0; | ||
| 1740 | unsigned long flags; | 1747 | unsigned long flags; |
| 1741 | int i, rc = 0; | 1748 | int i, rc = 0; |
| 1742 | 1749 | ||
| 1743 | DPRINTK("ENTER\n"); | 1750 | DPRINTK("ENTER\n"); |
| 1744 | 1751 | ||
| 1745 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 1752 | /* For PATA drive side cable detection to work, IDENTIFY must |
| 1753 | * be done backwards such that PDIAG- is released by the slave | ||
| 1754 | * device before the master device is identified. | ||
| 1755 | */ | ||
| 1756 | for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) { | ||
| 1746 | unsigned int action, readid_flags = 0; | 1757 | unsigned int action, readid_flags = 0; |
| 1747 | 1758 | ||
| 1748 | dev = &ap->device[i]; | 1759 | dev = &ap->device[i]; |
| @@ -1754,13 +1765,13 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
| 1754 | if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { | 1765 | if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { |
| 1755 | if (ata_port_offline(ap)) { | 1766 | if (ata_port_offline(ap)) { |
| 1756 | rc = -EIO; | 1767 | rc = -EIO; |
| 1757 | break; | 1768 | goto err; |
| 1758 | } | 1769 | } |
| 1759 | 1770 | ||
| 1760 | ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE); | 1771 | ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE); |
| 1761 | rc = ata_dev_revalidate(dev, readid_flags); | 1772 | rc = ata_dev_revalidate(dev, readid_flags); |
| 1762 | if (rc) | 1773 | if (rc) |
| 1763 | break; | 1774 | goto err; |
| 1764 | 1775 | ||
| 1765 | ata_eh_done(ap, dev, ATA_EH_REVALIDATE); | 1776 | ata_eh_done(ap, dev, ATA_EH_REVALIDATE); |
| 1766 | 1777 | ||
| @@ -1778,40 +1789,53 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
| 1778 | 1789 | ||
| 1779 | rc = ata_dev_read_id(dev, &dev->class, readid_flags, | 1790 | rc = ata_dev_read_id(dev, &dev->class, readid_flags, |
| 1780 | dev->id); | 1791 | dev->id); |
| 1781 | if (rc == 0) { | 1792 | switch (rc) { |
| 1782 | ehc->i.flags |= ATA_EHI_PRINTINFO; | 1793 | case 0: |
| 1783 | rc = ata_dev_configure(dev); | 1794 | new_mask |= 1 << i; |
| 1784 | ehc->i.flags &= ~ATA_EHI_PRINTINFO; | 1795 | break; |
| 1785 | } else if (rc == -ENOENT) { | 1796 | case -ENOENT: |
| 1786 | /* IDENTIFY was issued to non-existent | 1797 | /* IDENTIFY was issued to non-existent |
| 1787 | * device. No need to reset. Just | 1798 | * device. No need to reset. Just |
| 1788 | * thaw and kill the device. | 1799 | * thaw and kill the device. |
| 1789 | */ | 1800 | */ |
| 1790 | ata_eh_thaw_port(ap); | 1801 | ata_eh_thaw_port(ap); |
| 1791 | dev->class = ATA_DEV_UNKNOWN; | 1802 | dev->class = ATA_DEV_UNKNOWN; |
| 1792 | rc = 0; | ||
| 1793 | } | ||
| 1794 | |||
| 1795 | if (rc) { | ||
| 1796 | dev->class = ATA_DEV_UNKNOWN; | ||
| 1797 | break; | 1803 | break; |
| 1804 | default: | ||
| 1805 | dev->class = ATA_DEV_UNKNOWN; | ||
| 1806 | goto err; | ||
| 1798 | } | 1807 | } |
| 1808 | } | ||
| 1809 | } | ||
| 1799 | 1810 | ||
| 1800 | if (ata_dev_enabled(dev)) { | 1811 | /* Configure new devices forward such that user doesn't see |
| 1801 | spin_lock_irqsave(ap->lock, flags); | 1812 | * device detection messages backwards. |
| 1802 | ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; | 1813 | */ |
| 1803 | spin_unlock_irqrestore(ap->lock, flags); | 1814 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
| 1815 | dev = &ap->device[i]; | ||
| 1804 | 1816 | ||
| 1805 | /* new device discovered, configure xfermode */ | 1817 | if (!(new_mask & (1 << i))) |
| 1806 | ehc->i.flags |= ATA_EHI_SETMODE; | 1818 | continue; |
| 1807 | } | 1819 | |
| 1808 | } | 1820 | ehc->i.flags |= ATA_EHI_PRINTINFO; |
| 1821 | rc = ata_dev_configure(dev); | ||
| 1822 | ehc->i.flags &= ~ATA_EHI_PRINTINFO; | ||
| 1823 | if (rc) | ||
| 1824 | goto err; | ||
| 1825 | |||
| 1826 | spin_lock_irqsave(ap->lock, flags); | ||
| 1827 | ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; | ||
| 1828 | spin_unlock_irqrestore(ap->lock, flags); | ||
| 1829 | |||
| 1830 | /* new device discovered, configure xfermode */ | ||
| 1831 | ehc->i.flags |= ATA_EHI_SETMODE; | ||
| 1809 | } | 1832 | } |
| 1810 | 1833 | ||
| 1811 | if (rc) | 1834 | return 0; |
| 1812 | *r_failed_dev = dev; | ||
| 1813 | 1835 | ||
| 1814 | DPRINTK("EXIT\n"); | 1836 | err: |
| 1837 | *r_failed_dev = dev; | ||
| 1838 | DPRINTK("EXIT rc=%d\n", rc); | ||
| 1815 | return rc; | 1839 | return rc; |
| 1816 | } | 1840 | } |
| 1817 | 1841 | ||
