summaryrefslogtreecommitdiff
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.c69
1 files changed, 44 insertions, 25 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index f888babc8283..a34f32442edf 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -131,10 +131,11 @@ static const char *ata_scsi_lpm_get(enum link_pm policy)
return NULL;
}
-static ssize_t ata_scsi_lpm_put(struct class_device *class_dev,
- const char *buf, size_t count)
+static ssize_t ata_scsi_lpm_put(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct Scsi_Host *shost = class_to_shost(class_dev);
+ struct Scsi_Host *shost = class_to_shost(dev);
struct ata_port *ap = ata_shost_to_port(shost);
enum link_pm policy = 0;
int i;
@@ -162,9 +163,9 @@ static ssize_t ata_scsi_lpm_put(struct class_device *class_dev,
}
static ssize_t
-ata_scsi_lpm_show(struct class_device *class_dev, char *buf)
+ata_scsi_lpm_show(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct Scsi_Host *shost = class_to_shost(class_dev);
+ struct Scsi_Host *shost = class_to_shost(dev);
struct ata_port *ap = ata_shost_to_port(shost);
const char *policy =
ata_scsi_lpm_get(ap->pm_policy);
@@ -174,9 +175,9 @@ ata_scsi_lpm_show(struct class_device *class_dev, char *buf)
return snprintf(buf, 23, "%s\n", policy);
}
-CLASS_DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
+DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
ata_scsi_lpm_show, ata_scsi_lpm_put);
-EXPORT_SYMBOL_GPL(class_device_attr_link_power_management_policy);
+EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
@@ -527,6 +528,14 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
return qc;
}
+static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+
+ qc->extrabytes = scmd->request->extra_len;
+ qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes;
+}
+
/**
* ata_dump_status - user friendly display of error info
* @id: id of the port in question
@@ -862,9 +871,10 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
struct request_queue *q = sdev->request_queue;
void *buf;
- /* set the min alignment */
+ /* set the min alignment and padding */
blk_queue_update_dma_alignment(sdev->request_queue,
ATA_DMA_PAD_SZ - 1);
+ blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1);
/* configure draining */
buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL);
@@ -1694,12 +1704,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
u8 *rbuf;
unsigned int buflen, rc;
struct scsi_cmnd *cmd = args->cmd;
+ unsigned long flags;
+
+ local_irq_save(flags);
buflen = ata_scsi_rbuf_get(cmd, &rbuf);
memset(rbuf, 0, buflen);
rc = actor(args, rbuf, buflen);
ata_scsi_rbuf_put(cmd, rbuf);
+ local_irq_restore(flags);
+
if (rc == 0)
cmd->result = SAM_STAT_GOOD;
args->done(cmd);
@@ -2318,11 +2333,7 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
{
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
- cmd->sense_buffer[0] = 0x70; /* fixed format, current */
- cmd->sense_buffer[2] = sk;
- cmd->sense_buffer[7] = 18 - 8; /* additional sense length */
- cmd->sense_buffer[12] = asc;
- cmd->sense_buffer[13] = ascq;
+ scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
}
/**
@@ -2379,7 +2390,10 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
/* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
- ap->ops->tf_read(ap, &qc->tf);
+#ifdef CONFIG_ATA_SFF
+ if (ap->ops->sff_tf_read)
+ ap->ops->sff_tf_read(ap, &qc->tf);
+#endif
/* fill these in, for the case where they are -not- overwritten */
cmd->sense_buffer[0] = 0x70;
@@ -2473,6 +2487,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
u8 *buf = NULL;
unsigned int buflen;
+ unsigned long flags;
+
+ local_irq_save(flags);
buflen = ata_scsi_rbuf_get(cmd, &buf);
@@ -2490,6 +2507,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
}
ata_scsi_rbuf_put(cmd, buf);
+
+ local_irq_restore(flags);
}
cmd->result = SAM_STAT_GOOD;
@@ -2528,7 +2547,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
}
qc->tf.command = ATA_CMD_PACKET;
- qc->nbytes = scsi_bufflen(scmd);
+ ata_qc_set_pc_nbytes(qc);
/* check whether ATAPI DMA is safe */
if (!using_pio && ata_check_atapi_dma(qc))
@@ -2539,7 +2558,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
* want to set it properly, and for DMA where it is
* effectively meaningless.
*/
- nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024);
+ nbytes = min(ata_qc_raw_nbytes(qc), (unsigned int)63 * 1024);
/* Most ATAPI devices which honor transfer chunk size don't
* behave according to the spec when odd chunk size which
@@ -2582,7 +2601,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
qc->tf.protocol = ATAPI_PROT_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
- if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
+ if ((dev->flags & ATA_DFLAG_DMADIR) &&
+ (scmd->sc_data_direction != DMA_TO_DEVICE))
/* some SATA bridges need us to indicate data xfer direction */
qc->tf.feature |= ATAPI_DMADIR;
}
@@ -2595,7 +2615,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
{
- if (ap->nr_pmp_links == 0) {
+ if (!sata_pmp_attached(ap)) {
if (likely(devno < ata_link_max_devices(&ap->link)))
return &ap->link.device[devno];
} else {
@@ -2612,7 +2632,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
int devno;
/* skip commands not addressed to targets we simulate */
- if (ap->nr_pmp_links == 0) {
+ if (!sata_pmp_attached(ap)) {
if (unlikely(scsidev->channel || scsidev->lun))
return NULL;
devno = scsidev->id;
@@ -2864,7 +2884,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nbytes = scsi_bufflen(scmd);
+ ata_qc_set_pc_nbytes(qc);
/* request result TF and be quiet about device error */
qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
@@ -3470,7 +3490,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
if (lun != SCAN_WILD_CARD && lun)
return -EINVAL;
- if (ap->nr_pmp_links == 0) {
+ if (!sata_pmp_attached(ap)) {
if (channel != SCAN_WILD_CARD && channel)
return -EINVAL;
devno = id;
@@ -3487,8 +3507,8 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
ata_port_for_each_link(link, ap) {
struct ata_eh_info *ehi = &link->eh_info;
- ehi->probe_mask |= (1 << ata_link_max_devices(link)) - 1;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->probe_mask |= ATA_ALL_DEVICES;
+ ehi->action |= ATA_EH_RESET;
}
} else {
struct ata_device *dev = ata_find_dev(ap, devno);
@@ -3496,8 +3516,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
if (dev) {
struct ata_eh_info *ehi = &dev->link->eh_info;
ehi->probe_mask |= 1 << dev->devno;
- ehi->action |= ATA_EH_SOFTRESET;
- ehi->flags |= ATA_EHI_RESUME_LINK;
+ ehi->action |= ATA_EH_RESET;
} else
rc = -EINVAL;
}