|
@@ -391,6 +391,60 @@ int ata_scsi_error(struct Scsi_Host *host)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
|
|
|
|
+ * @qc: Storage for translated ATA taskfile
|
|
|
|
+ * @scsicmd: SCSI command to translate
|
|
|
|
+ *
|
|
|
|
+ * Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY
|
|
|
|
+ * (to start). Perhaps these commands should be preceded by
|
|
|
|
+ * CHECK POWER MODE to see what power mode the device is already in.
|
|
|
|
+ * [See SAT revision 5 at www.t10.org]
|
|
|
|
+ *
|
|
|
|
+ * LOCKING:
|
|
|
|
+ * spin_lock_irqsave(host_set lock)
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * Zero on success, non-zero on error.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
|
|
|
|
+ u8 *scsicmd)
|
|
|
|
+{
|
|
|
|
+ struct ata_taskfile *tf = &qc->tf;
|
|
|
|
+
|
|
|
|
+ tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
|
|
|
|
+ tf->protocol = ATA_PROT_NODATA;
|
|
|
|
+ if (scsicmd[1] & 0x1) {
|
|
|
|
+ ; /* ignore IMMED bit, violates sat-r05 */
|
|
|
|
+ }
|
|
|
|
+ if (scsicmd[4] & 0x2)
|
|
|
|
+ return 1; /* LOEJ bit set not supported */
|
|
|
|
+ if (((scsicmd[4] >> 4) & 0xf) != 0)
|
|
|
|
+ return 1; /* power conditions not supported */
|
|
|
|
+ if (scsicmd[4] & 0x1) {
|
|
|
|
+ tf->nsect = 1; /* 1 sector, lba=0 */
|
|
|
|
+ tf->lbah = 0x0;
|
|
|
|
+ tf->lbam = 0x0;
|
|
|
|
+ tf->lbal = 0x0;
|
|
|
|
+ tf->device |= ATA_LBA;
|
|
|
|
+ tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
|
|
|
|
+ } else {
|
|
|
|
+ tf->nsect = 0; /* time period value (0 implies now) */
|
|
|
|
+ tf->command = ATA_CMD_STANDBY;
|
|
|
|
+ /* Consider: ATA STANDBY IMMEDIATE command */
|
|
|
|
+ }
|
|
|
|
+ /*
|
|
|
|
+ * Standby and Idle condition timers could be implemented but that
|
|
|
|
+ * would require libata to implement the Power condition mode page
|
|
|
|
+ * and allow the user to change it. Changing mode pages requires
|
|
|
|
+ * MODE SELECT to be implemented.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
|
|
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
|
|
* @qc: Storage for translated ATA taskfile
|
|
* @qc: Storage for translated ATA taskfile
|
|
@@ -1435,6 +1489,8 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
|
|
case VERIFY:
|
|
case VERIFY:
|
|
case VERIFY_16:
|
|
case VERIFY_16:
|
|
return ata_scsi_verify_xlat;
|
|
return ata_scsi_verify_xlat;
|
|
|
|
+ case START_STOP:
|
|
|
|
+ return ata_scsi_start_stop_xlat;
|
|
}
|
|
}
|
|
|
|
|
|
return NULL;
|
|
return NULL;
|