aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-eh.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 33ac5ea4f531..f2dd99122bd6 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -79,6 +79,8 @@ enum {
79 */ 79 */
80 ATA_EH_PRERESET_TIMEOUT = 10000, 80 ATA_EH_PRERESET_TIMEOUT = 10000,
81 ATA_EH_FASTDRAIN_INTERVAL = 3000, 81 ATA_EH_FASTDRAIN_INTERVAL = 3000,
82
83 ATA_EH_UA_TRIES = 5,
82}; 84};
83 85
84/* The following table determines how we sequence resets. Each entry 86/* The following table determines how we sequence resets. Each entry
@@ -1357,6 +1359,37 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
1357} 1359}
1358 1360
1359/** 1361/**
1362 * atapi_eh_tur - perform ATAPI TEST_UNIT_READY
1363 * @dev: target ATAPI device
1364 * @r_sense_key: out parameter for sense_key
1365 *
1366 * Perform ATAPI TEST_UNIT_READY.
1367 *
1368 * LOCKING:
1369 * EH context (may sleep).
1370 *
1371 * RETURNS:
1372 * 0 on success, AC_ERR_* mask on failure.
1373 */
1374static unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
1375{
1376 u8 cdb[ATAPI_CDB_LEN] = { TEST_UNIT_READY, 0, 0, 0, 0, 0 };
1377 struct ata_taskfile tf;
1378 unsigned int err_mask;
1379
1380 ata_tf_init(dev, &tf);
1381
1382 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
1383 tf.command = ATA_CMD_PACKET;
1384 tf.protocol = ATAPI_PROT_NODATA;
1385
1386 err_mask = ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0);
1387 if (err_mask == AC_ERR_DEV)
1388 *r_sense_key = tf.feature >> 4;
1389 return err_mask;
1390}
1391
1392/**
1360 * atapi_eh_request_sense - perform ATAPI REQUEST_SENSE 1393 * atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
1361 * @dev: device to perform REQUEST_SENSE to 1394 * @dev: device to perform REQUEST_SENSE to
1362 * @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long) 1395 * @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long)
@@ -2774,6 +2807,53 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
2774 return rc; 2807 return rc;
2775} 2808}
2776 2809
2810/**
2811 * atapi_eh_clear_ua - Clear ATAPI UNIT ATTENTION after reset
2812 * @dev: ATAPI device to clear UA for
2813 *
2814 * Resets and other operations can make an ATAPI device raise
2815 * UNIT ATTENTION which causes the next operation to fail. This
2816 * function clears UA.
2817 *
2818 * LOCKING:
2819 * EH context (may sleep).
2820 *
2821 * RETURNS:
2822 * 0 on success, -errno on failure.
2823 */
2824static int atapi_eh_clear_ua(struct ata_device *dev)
2825{
2826 int i;
2827
2828 for (i = 0; i < ATA_EH_UA_TRIES; i++) {
2829 u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
2830 u8 sense_key = 0;
2831 unsigned int err_mask;
2832
2833 err_mask = atapi_eh_tur(dev, &sense_key);
2834 if (err_mask != 0 && err_mask != AC_ERR_DEV) {
2835 ata_dev_printk(dev, KERN_WARNING, "TEST_UNIT_READY "
2836 "failed (err_mask=0x%x)\n", err_mask);
2837 return -EIO;
2838 }
2839
2840 if (!err_mask || sense_key != UNIT_ATTENTION)
2841 return 0;
2842
2843 err_mask = atapi_eh_request_sense(dev, sense_buffer, sense_key);
2844 if (err_mask) {
2845 ata_dev_printk(dev, KERN_WARNING, "failed to clear "
2846 "UNIT ATTENTION (err_mask=0x%x)\n", err_mask);
2847 return -EIO;
2848 }
2849 }
2850
2851 ata_dev_printk(dev, KERN_WARNING,
2852 "UNIT ATTENTION persists after %d tries\n", ATA_EH_UA_TRIES);
2853
2854 return 0;
2855}
2856
2777static int ata_link_nr_enabled(struct ata_link *link) 2857static int ata_link_nr_enabled(struct ata_link *link)
2778{ 2858{
2779 struct ata_device *dev; 2859 struct ata_device *dev;
@@ -3066,6 +3146,20 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3066 ehc->i.flags &= ~ATA_EHI_SETMODE; 3146 ehc->i.flags &= ~ATA_EHI_SETMODE;
3067 } 3147 }
3068 3148
3149 /* If reset has been issued, clear UA to avoid
3150 * disrupting the current users of the device.
3151 */
3152 if (ehc->i.flags & ATA_EHI_DID_RESET) {
3153 ata_link_for_each_dev(dev, link) {
3154 if (dev->class != ATA_DEV_ATAPI)
3155 continue;
3156 rc = atapi_eh_clear_ua(dev);
3157 if (rc)
3158 goto dev_fail;
3159 }
3160 }
3161
3162 /* configure link power saving */
3069 if (ehc->i.action & ATA_EH_LPM) 3163 if (ehc->i.action & ATA_EH_LPM)
3070 ata_link_for_each_dev(dev, link) 3164 ata_link_for_each_dev(dev, link)
3071 ata_dev_enable_pm(dev, ap->pm_policy); 3165 ata_dev_enable_pm(dev, ap->pm_policy);