mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 07:50:04 +00: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;
|
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;
|
||||||
|
@ -108,6 +108,8 @@ enum {
|
|||||||
|
|
||||||
/* ATA device commands */
|
/* ATA device commands */
|
||||||
ATA_CMD_CHK_POWER = 0xE5, /* check power mode */
|
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_EDD = 0x90, /* execute device diagnostic */
|
||||||
ATA_CMD_FLUSH = 0xE7,
|
ATA_CMD_FLUSH = 0xE7,
|
||||||
ATA_CMD_FLUSH_EXT = 0xEA,
|
ATA_CMD_FLUSH_EXT = 0xEA,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user