mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 10:04:12 +08:00
[libata scsi] add START STOP UNIT translation
This commit is contained in:
parent
4c71812261
commit
972dcafb6d
@ -391,6 +391,60 @@ int ata_scsi_error(struct Scsi_Host *host)
|
||||
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
|
||||
* @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_16:
|
||||
return ata_scsi_verify_xlat;
|
||||
case START_STOP:
|
||||
return ata_scsi_start_stop_xlat;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -108,6 +108,8 @@ enum {
|
||||
|
||||
/* ATA device commands */
|
||||
ATA_CMD_CHK_POWER = 0xE5, /* check power mode */
|
||||
ATA_CMD_STANDBY = 0xE2, /* place in standby power mode */
|
||||
ATA_CMD_IDLE = 0xE3, /* place in idle power mode */
|
||||
ATA_CMD_EDD = 0x90, /* execute device diagnostic */
|
||||
ATA_CMD_FLUSH = 0xE7,
|
||||
ATA_CMD_FLUSH_EXT = 0xEA,
|
||||
|
Loading…
Reference in New Issue
Block a user