Skip to content

Commit 11fc33d

Browse files
htejunJeff Garzik
authored andcommitted
libata-eh: clear UNIT ATTENTION after reset
Resets make ATAPI devices raise UNIT ATTENTION which fails the next command. As resets can happen asynchronously for unrelated reasons, this sometimes disrupts innocent users. For example, reading DVD fails after the system wakes up from suspend or the other device sharing the channel went through bus error. Clearing UA has some problems as it might clear UA which the userland needs to know about. However, UA after resets can only be about the reset itself and benefits of clearing it overweights cons. Missing UA can only delay failure to one of the following commands anyway. For example, timeout while burning is in progress will trigger reset and reset the device state and probably corrupt the burning run. Although the userland application won't get the UA, its pending writes will fail. Signed-off-by: Tejun Heo <[email protected]> Signed-off-by: Jeff Garzik <[email protected]>
1 parent d09addf commit 11fc33d

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

drivers/ata/libata-eh.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ enum {
7979
*/
8080
ATA_EH_PRERESET_TIMEOUT = 10000,
8181
ATA_EH_FASTDRAIN_INTERVAL = 3000,
82+
83+
ATA_EH_UA_TRIES = 5,
8284
};
8385

8486
/* The following table determines how we sequence resets. Each entry
@@ -1356,6 +1358,37 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
13561358
return 0;
13571359
}
13581360

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+
*/
1374+
static 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+
13591392
/**
13601393
* atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
13611394
* @dev: device to perform REQUEST_SENSE to
@@ -2774,6 +2807,53 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
27742807
return rc;
27752808
}
27762809

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+
*/
2824+
static 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+
27772857
static int ata_link_nr_enabled(struct ata_link *link)
27782858
{
27792859
struct ata_device *dev;
@@ -3066,6 +3146,20 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
30663146
ehc->i.flags &= ~ATA_EHI_SETMODE;
30673147
}
30683148

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 */
30693163
if (ehc->i.action & ATA_EH_LPM)
30703164
ata_link_for_each_dev(dev, link)
30713165
ata_dev_enable_pm(dev, ap->pm_policy);

0 commit comments

Comments
 (0)