As per SAT (sans removable devices)... commit 09d9637c413406cf63f0e1efb364411ac8a9243c Author: Jeff Garzik <jeff@xxxxxxxxxx> Date: Fri Sep 21 07:09:36 2007 -0400 [libata] SCSI: simple TEST UNIT READY simulation It's trivial to ping the device, and that's a much more sane behavior than no-op. Signed-off-by: Jeff Garzik <jeff@xxxxxxxxxx> drivers/ata/libata-scsi.c | 62 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 16 deletions(-) 09d9637c413406cf63f0e1efb364411ac8a9243c diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index dbe8ac3..456b75f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -906,6 +906,29 @@ static void ata_delayed_done(struct scsi_cmnd *scmd) } /** + * ata_scsi_tur_xlat - Translate SCSI TEST UNIT READY command + * @qc: Storage for translated ATA taskfile + * + * Simulates a TEST UNIT READY command. + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + * RETURNS: + * Zero on success, non-zero on error. + */ +static unsigned int ata_scsi_tur_xlat(struct ata_queued_cmd *qc) +{ + struct ata_taskfile *tf = &qc->tf; + + tf->flags |= ATA_TFLAG_DEVICE; + tf->protocol = ATA_PROT_NODATA; + tf->command = ATA_CMD_CHK_POWER; + + return 0; +} + +/** * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command * @qc: Storage for translated ATA taskfile * @@ -1376,6 +1399,12 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) } } + /* For TEST UNIT READY failures, we are told to respond with + * NOT READY / LOGICAL UNIT DOES NOT RESPOND TO SELECTION + */ + if ((cdb[0] == TEST_UNIT_READY) && need_sense) + ata_scsi_set_sense(cmd, NOT_READY, 0x05, 0x00); + /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we * generate because the user forced us to, a check condition @@ -1383,22 +1412,21 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) * whether the command completed successfully or not. If there * was no error, SK, ASC and ASCQ will all be zero. */ - if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && - ((cdb[2] & 0x20) || need_sense)) { + else if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && + ((cdb[2] & 0x20) || need_sense)) ata_gen_passthru_sense(qc); - } else { - if (!need_sense) { - cmd->result = SAM_STAT_GOOD; - } else { - /* TODO: decide which descriptor format to use - * for 48b LBA devices and call that here - * instead of the fixed desc, which is only - * good for smaller LBA (and maybe CHS?) - * devices. - */ - ata_gen_ata_sense(qc); - } - } + + else if (need_sense) + /* TODO: decide which descriptor format to use + * for 48b LBA devices and call that here + * instead of the fixed desc, which is only + * good for smaller LBA (and maybe CHS?) + * devices. + */ + ata_gen_ata_sense(qc); + + else + cmd->result = SAM_STAT_GOOD; /* XXX: track spindown state for spindown skipping and warning */ if (unlikely(qc->tf.command == ATA_CMD_STANDBY || @@ -2780,6 +2808,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) case START_STOP: return ata_scsi_start_stop_xlat; + + case TEST_UNIT_READY: + return ata_scsi_tur_xlat; } return NULL; @@ -2935,7 +2966,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, case REZERO_UNIT: case SEEK_6: case SEEK_10: - case TEST_UNIT_READY: case FORMAT_UNIT: /* FIXME: correct? */ ata_scsi_rbuf_fill(&args, ata_scsiop_noop); break; - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html