{
        int rc = 0;
        u8 scsi_cmd[MAX_COMMAND_SIZE];
-       u8 args[4], *argbuf = NULL;
+       u8 args[4], *argbuf = NULL, *sensebuf = NULL;
        int argsize = 0;
-       struct scsi_sense_hdr sshdr;
        enum dma_data_direction data_dir;
+       int cmd_result;
 
        if (arg == NULL)
                return -EINVAL;
        if (copy_from_user(args, arg, sizeof(args)))
                return -EFAULT;
 
+       sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
+       if (!sensebuf)
+               return -ENOMEM;
+
        memset(scsi_cmd, 0, sizeof(scsi_cmd));
 
        if (args[3]) {
                data_dir = DMA_FROM_DEVICE;
        } else {
                scsi_cmd[1]  = (3 << 1); /* Non-data */
-               /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+               scsi_cmd[2]  = 0x20;     /* cc but no off.line or data xfer */
                data_dir = DMA_NONE;
        }
 
 
        /* Good values for timeout and retries?  Values below
           from scsi_ioctl_send_command() for default case... */
-       if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize,
-                            &sshdr, (10*HZ), 5)) {
+       cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
+                                 sensebuf, (10*HZ), 5, 0);
+
+       if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
+               u8 *desc = sensebuf + 8;
+               cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
+
+               /* If we set cc then ATA pass-through will cause a
+                * check condition even if no error. Filter that. */
+               if (cmd_result & SAM_STAT_CHECK_CONDITION) {
+                       struct scsi_sense_hdr sshdr;
+                       scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
+                                             &sshdr);
+                       if (sshdr.sense_key==0 &&
+                           sshdr.asc==0 && sshdr.ascq==0)
+                               cmd_result &= ~SAM_STAT_CHECK_CONDITION;
+               }
+
+               /* Send userspace a few ATA registers (same as drivers/ide) */
+               if (sensebuf[0] == 0x72 &&     /* format is "descriptor" */
+                   desc[0] == 0x09 ) {        /* code is "ATA Descriptor" */
+                       args[0] = desc[13];    /* status */
+                       args[1] = desc[3];     /* error */
+                       args[2] = desc[5];     /* sector count (0:7) */
+                       if (copy_to_user(arg, args, sizeof(args)))
+                               rc = -EFAULT;
+               }
+       }
+
+
+       if (cmd_result) {
                rc = -EIO;
                goto error;
        }
 
-       /* Need code to retrieve data from check condition? */
-
        if ((argbuf)
         && copy_to_user(arg + sizeof(args), argbuf, argsize))
                rc = -EFAULT;
 error:
+       kfree(sensebuf);
        kfree(argbuf);
        return rc;
 }