aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index ab6b53349d6f..b007bb409382 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -151,7 +151,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
151 struct scsi_sense_hdr sshdr; 151 struct scsi_sense_hdr sshdr;
152 enum dma_data_direction data_dir; 152 enum dma_data_direction data_dir;
153 153
154 if (NULL == (void *)arg) 154 if (arg == NULL)
155 return -EINVAL; 155 return -EINVAL;
156 156
157 if (copy_from_user(args, arg, sizeof(args))) 157 if (copy_from_user(args, arg, sizeof(args)))
@@ -201,7 +201,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
201 /* Need code to retrieve data from check condition? */ 201 /* Need code to retrieve data from check condition? */
202 202
203 if ((argbuf) 203 if ((argbuf)
204 && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize)) 204 && copy_to_user(arg + sizeof(args), argbuf, argsize))
205 rc = -EFAULT; 205 rc = -EFAULT;
206error: 206error:
207 if (argbuf) 207 if (argbuf)
@@ -228,7 +228,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
228 u8 args[7]; 228 u8 args[7];
229 struct scsi_sense_hdr sshdr; 229 struct scsi_sense_hdr sshdr;
230 230
231 if (NULL == (void *)arg) 231 if (arg == NULL)
232 return -EINVAL; 232 return -EINVAL;
233 233
234 if (copy_from_user(args, arg, sizeof(args))) 234 if (copy_from_user(args, arg, sizeof(args)))
@@ -732,16 +732,27 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
732int ata_scsi_error(struct Scsi_Host *host) 732int ata_scsi_error(struct Scsi_Host *host)
733{ 733{
734 struct ata_port *ap; 734 struct ata_port *ap;
735 unsigned long flags;
735 736
736 DPRINTK("ENTER\n"); 737 DPRINTK("ENTER\n");
737 738
738 ap = (struct ata_port *) &host->hostdata[0]; 739 ap = (struct ata_port *) &host->hostdata[0];
740
741 spin_lock_irqsave(&ap->host_set->lock, flags);
742 assert(!(ap->flags & ATA_FLAG_IN_EH));
743 ap->flags |= ATA_FLAG_IN_EH;
744 spin_unlock_irqrestore(&ap->host_set->lock, flags);
745
739 ap->ops->eng_timeout(ap); 746 ap->ops->eng_timeout(ap);
740 747
741 assert(host->host_failed == 0 && list_empty(&host->eh_cmd_q)); 748 assert(host->host_failed == 0 && list_empty(&host->eh_cmd_q));
742 749
743 scsi_eh_flush_done_q(&ap->eh_done_q); 750 scsi_eh_flush_done_q(&ap->eh_done_q);
744 751
752 spin_lock_irqsave(&ap->host_set->lock, flags);
753 ap->flags &= ~ATA_FLAG_IN_EH;
754 spin_unlock_irqrestore(&ap->host_set->lock, flags);
755
745 DPRINTK("EXIT\n"); 756 DPRINTK("EXIT\n");
746 return 0; 757 return 0;
747} 758}
@@ -1742,6 +1753,31 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
1742 return sizeof(def_rw_recovery_mpage); 1753 return sizeof(def_rw_recovery_mpage);
1743} 1754}
1744 1755
1756/*
1757 * We can turn this into a real blacklist if it's needed, for now just
1758 * blacklist any Maxtor BANC1G10 revision firmware
1759 */
1760static int ata_dev_supports_fua(u16 *id)
1761{
1762 unsigned char model[41], fw[9];
1763
1764 if (!ata_id_has_fua(id))
1765 return 0;
1766
1767 model[40] = '\0';
1768 fw[8] = '\0';
1769
1770 ata_dev_id_string(id, model, ATA_ID_PROD_OFS, sizeof(model) - 1);
1771 ata_dev_id_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw) - 1);
1772
1773 if (strncmp(model, "Maxtor", 6))
1774 return 1;
1775 if (strncmp(fw, "BANC1G10", 8))
1776 return 1;
1777
1778 return 0; /* blacklisted */
1779}
1780
1745/** 1781/**
1746 * ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands 1782 * ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
1747 * @args: device IDENTIFY data / SCSI command of interest. 1783 * @args: device IDENTIFY data / SCSI command of interest.
@@ -1839,7 +1875,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
1839 return 0; 1875 return 0;
1840 1876
1841 dpofua = 0; 1877 dpofua = 0;
1842 if (ata_id_has_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 && 1878 if (ata_dev_supports_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 &&
1843 (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count)) 1879 (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count))
1844 dpofua = 1 << 4; 1880 dpofua = 1 << 4;
1845 1881
@@ -2533,7 +2569,8 @@ out_unlock:
2533 2569
2534/** 2570/**
2535 * ata_scsi_simulate - simulate SCSI command on ATA device 2571 * ata_scsi_simulate - simulate SCSI command on ATA device
2536 * @id: current IDENTIFY data for target device. 2572 * @ap: port the device is connected to
2573 * @dev: the target device
2537 * @cmd: SCSI command being sent to device. 2574 * @cmd: SCSI command being sent to device.
2538 * @done: SCSI command completion function. 2575 * @done: SCSI command completion function.
2539 * 2576 *