summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-scsi.c81
1 files changed, 47 insertions, 34 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4593258d2b6a..556f7b417f3b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1792,17 +1792,19 @@ static void ata_scsi_rbuf_fill(struct ata_device *dev, struct scsi_cmnd *cmd,
unsigned int (*actor)(struct ata_device *dev,
struct scsi_cmnd *cmd, u8 *rbuf))
{
- unsigned int rc;
unsigned long flags;
+ unsigned int len;
spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
- rc = actor(dev, cmd, ata_scsi_rbuf);
- if (rc == 0) {
+ len = actor(dev, cmd, ata_scsi_rbuf);
+ if (len) {
sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
cmd->result = SAM_STAT_GOOD;
+ if (scsi_bufflen(cmd) > len)
+ scsi_set_resid(cmd, scsi_bufflen(cmd) - len);
}
spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
@@ -1890,7 +1892,11 @@ static unsigned int ata_scsiop_inq_std(struct ata_device *dev,
else
memcpy(rbuf + 58, versions, sizeof(versions));
- return 0;
+ /*
+ * Include all 8 possible version descriptors, even if not all of
+ * them are popoulated.
+ */
+ return 96;
}
/**
@@ -1928,7 +1934,8 @@ static unsigned int ata_scsiop_inq_00(struct ata_device *dev,
num_pages++;
}
rbuf[3] = num_pages; /* number of supported VPD pages */
- return 0;
+
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -1955,7 +1962,8 @@ static unsigned int ata_scsiop_inq_80(struct ata_device *dev,
memcpy(rbuf, hdr, sizeof(hdr));
ata_id_string(dev->id, (unsigned char *) &rbuf[4],
ATA_ID_SERNO, ATA_ID_SERNO_LEN);
- return 0;
+
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2016,7 +2024,8 @@ static unsigned int ata_scsiop_inq_83(struct ata_device *dev,
num += ATA_ID_WWN_LEN;
}
rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */
- return 0;
+
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2053,7 +2062,8 @@ static unsigned int ata_scsiop_inq_89(struct ata_device *dev,
rbuf[56] = ATA_CMD_ID_ATA;
memcpy(&rbuf[60], &dev->id[0], 512);
- return 0;
+
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2104,7 +2114,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_device *dev,
put_unaligned_be32(1, &rbuf[28]);
}
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2134,7 +2144,7 @@ static unsigned int ata_scsiop_inq_b1(struct ata_device *dev,
if (zoned)
rbuf[8] = (zoned << 4);
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2157,7 +2167,7 @@ static unsigned int ata_scsiop_inq_b2(struct ata_device *dev,
rbuf[3] = 0x4;
rbuf[5] = 1 << 6; /* TPWS */
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2177,7 +2187,7 @@ static unsigned int ata_scsiop_inq_b6(struct ata_device *dev,
{
if (!(dev->flags & ATA_DFLAG_ZAC)) {
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
- return 1;
+ return 0;
}
/*
@@ -2195,7 +2205,7 @@ static unsigned int ata_scsiop_inq_b6(struct ata_device *dev,
put_unaligned_be32(dev->zac_zones_optimal_nonseq, &rbuf[12]);
put_unaligned_be32(dev->zac_zones_max_open, &rbuf[16]);
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2219,7 +2229,7 @@ static unsigned int ata_scsiop_inq_b9(struct ata_device *dev,
if (!cpr_log) {
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
- return 1;
+ return 0;
}
/* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */
@@ -2233,7 +2243,7 @@ static unsigned int ata_scsiop_inq_b9(struct ata_device *dev,
put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]);
}
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
@@ -2255,7 +2265,7 @@ static unsigned int ata_scsiop_inquiry(struct ata_device *dev,
/* is CmdDt set? */
if (scsicmd[1] & 2) {
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
- return 1;
+ return 0;
}
/* Is EVPD clear? */
@@ -2283,7 +2293,7 @@ static unsigned int ata_scsiop_inquiry(struct ata_device *dev,
return ata_scsiop_inq_b9(dev, cmd, rbuf);
default:
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
- return 1;
+ return 0;
}
}
@@ -2614,24 +2624,27 @@ static unsigned int ata_scsiop_mode_sense(struct ata_device *dev,
rbuf[3] = sizeof(sat_blk_desc);
memcpy(rbuf + 4, sat_blk_desc, sizeof(sat_blk_desc));
}
- } else {
- put_unaligned_be16(p - rbuf - 2, &rbuf[0]);
- rbuf[3] |= dpofua;
- if (ebd) {
- rbuf[7] = sizeof(sat_blk_desc);
- memcpy(rbuf + 8, sat_blk_desc, sizeof(sat_blk_desc));
- }
+
+ return rbuf[0] + 1;
+ }
+
+ put_unaligned_be16(p - rbuf - 2, &rbuf[0]);
+ rbuf[3] |= dpofua;
+ if (ebd) {
+ rbuf[7] = sizeof(sat_blk_desc);
+ memcpy(rbuf + 8, sat_blk_desc, sizeof(sat_blk_desc));
}
- return 0;
+
+ return get_unaligned_be16(&rbuf[0]) + 2;
invalid_fld:
ata_scsi_set_invalid_field(dev, cmd, fp, bp);
- return 1;
+ return 0;
saving_not_supp:
ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x39, 0x0);
/* "Saving parameters not supported" */
- return 1;
+ return 0;
}
/**
@@ -2674,7 +2687,7 @@ static unsigned int ata_scsiop_read_cap(struct ata_device *dev,
rbuf[6] = sector_size >> (8 * 1);
rbuf[7] = sector_size;
- return 0;
+ return 8;
}
/*
@@ -2684,7 +2697,7 @@ static unsigned int ata_scsiop_read_cap(struct ata_device *dev,
if (scsicmd[0] != SERVICE_ACTION_IN_16 ||
(scsicmd[1] & 0x1f) != SAI_READ_CAPACITY_16) {
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
- return 1;
+ return 0;
}
/* sector count, 64-bit */
@@ -2719,7 +2732,7 @@ static unsigned int ata_scsiop_read_cap(struct ata_device *dev,
}
}
- return 0;
+ return 16;
}
/**
@@ -2738,7 +2751,7 @@ static unsigned int ata_scsiop_report_luns(struct ata_device *dev,
{
rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */
- return 0;
+ return 16;
}
/*
@@ -3463,13 +3476,13 @@ static unsigned int ata_scsiop_maint_in(struct ata_device *dev,
if ((cdb[1] & 0x1f) != MI_REPORT_SUPPORTED_OPERATION_CODES) {
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
- return 1;
+ return 0;
}
if (cdb[2] != 1 && cdb[2] != 3) {
ata_dev_warn(dev, "invalid command format %d\n", cdb[2]);
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
- return 1;
+ return 0;
}
switch (cdb[3]) {
@@ -3542,7 +3555,7 @@ static unsigned int ata_scsiop_maint_in(struct ata_device *dev,
rbuf[0] = rwcdlp;
rbuf[1] = cdlp | supported;
- return 0;
+ return 4;
}
/**