Loading drivers/scsi/libata-scsi.c +56 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading include/linux/ata.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/scsi/libata-scsi.c +56 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading
include/linux/ata.h +2 −0 Original line number Diff line number Diff line Loading @@ -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