aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 7cc5a4a910a4..73902d335767 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -273,8 +273,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
273{ 273{
274 int rc = 0; 274 int rc = 0;
275 u8 scsi_cmd[MAX_COMMAND_SIZE]; 275 u8 scsi_cmd[MAX_COMMAND_SIZE];
276 u8 args[7]; 276 u8 args[7], *sensebuf = NULL;
277 struct scsi_sense_hdr sshdr; 277 int cmd_result;
278 278
279 if (arg == NULL) 279 if (arg == NULL)
280 return -EINVAL; 280 return -EINVAL;
@@ -282,10 +282,14 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
282 if (copy_from_user(args, arg, sizeof(args))) 282 if (copy_from_user(args, arg, sizeof(args)))
283 return -EFAULT; 283 return -EFAULT;
284 284
285 sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
286 if (!sensebuf)
287 return -ENOMEM;
288
285 memset(scsi_cmd, 0, sizeof(scsi_cmd)); 289 memset(scsi_cmd, 0, sizeof(scsi_cmd));
286 scsi_cmd[0] = ATA_16; 290 scsi_cmd[0] = ATA_16;
287 scsi_cmd[1] = (3 << 1); /* Non-data */ 291 scsi_cmd[1] = (3 << 1); /* Non-data */
288 /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ 292 scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */
289 scsi_cmd[4] = args[1]; 293 scsi_cmd[4] = args[1];
290 scsi_cmd[6] = args[2]; 294 scsi_cmd[6] = args[2];
291 scsi_cmd[8] = args[3]; 295 scsi_cmd[8] = args[3];
@@ -295,11 +299,46 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
295 299
296 /* Good values for timeout and retries? Values below 300 /* Good values for timeout and retries? Values below
297 from scsi_ioctl_send_command() for default case... */ 301 from scsi_ioctl_send_command() for default case... */
298 if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, 302 cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
299 (10*HZ), 5)) 303 sensebuf, (10*HZ), 5, 0);
304
305 if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
306 u8 *desc = sensebuf + 8;
307 cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
308
309 /* If we set cc then ATA pass-through will cause a
310 * check condition even if no error. Filter that. */
311 if (cmd_result & SAM_STAT_CHECK_CONDITION) {
312 struct scsi_sense_hdr sshdr;
313 scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
314 &sshdr);
315 if (sshdr.sense_key==0 &&
316 sshdr.asc==0 && sshdr.ascq==0)
317 cmd_result &= ~SAM_STAT_CHECK_CONDITION;
318 }
319
320 /* Send userspace ATA registers */
321 if (sensebuf[0] == 0x72 && /* format is "descriptor" */
322 desc[0] == 0x09) {/* code is "ATA Descriptor" */
323 args[0] = desc[13]; /* status */
324 args[1] = desc[3]; /* error */
325 args[2] = desc[5]; /* sector count (0:7) */
326 args[3] = desc[7]; /* lbal */
327 args[4] = desc[9]; /* lbam */
328 args[5] = desc[11]; /* lbah */
329 args[6] = desc[12]; /* select */
330 if (copy_to_user(arg, args, sizeof(args)))
331 rc = -EFAULT;
332 }
333 }
334
335 if (cmd_result) {
300 rc = -EIO; 336 rc = -EIO;
337 goto error;
338 }
301 339
302 /* Need code to retrieve data from check condition? */ 340 error:
341 kfree(sensebuf);
303 return rc; 342 return rc;
304} 343}
305 344
@@ -983,11 +1022,10 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
983 } 1022 }
984 1023
985 tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ 1024 tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
986 } else { 1025 } else
987 tf->nsect = 0; /* time period value (0 implies now) */ 1026 /* Issue ATA STANDBY IMMEDIATE command */
988 tf->command = ATA_CMD_STANDBY; 1027 tf->command = ATA_CMD_STANDBYNOW1;
989 /* Consider: ATA STANDBY IMMEDIATE command */ 1028
990 }
991 /* 1029 /*
992 * Standby and Idle condition timers could be implemented but that 1030 * Standby and Idle condition timers could be implemented but that
993 * would require libata to implement the Power condition mode page 1031 * would require libata to implement the Power condition mode page