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