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);
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;
}
/**
num_pages++;
}
rbuf[3] = num_pages; /* number of supported VPD pages */
- return 0;
+
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
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;
}
/**
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;
}
/**
rbuf[56] = ATA_CMD_ID_ATA;
memcpy(&rbuf[60], &dev->id[0], 512);
- return 0;
+
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
put_unaligned_be32(1, &rbuf[28]);
}
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
if (zoned)
rbuf[8] = (zoned << 4);
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
rbuf[3] = 0x4;
rbuf[5] = 1 << 6; /* TPWS */
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
{
if (!(dev->flags & ATA_DFLAG_ZAC)) {
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
- return 1;
+ return 0;
}
/*
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;
}
/**
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 */
put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]);
}
- return 0;
+ return get_unaligned_be16(&rbuf[2]) + 4;
}
/**
/* is CmdDt set? */
if (scsicmd[1] & 2) {
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
- return 1;
+ return 0;
}
/* Is EVPD clear? */
return ata_scsiop_inq_b9(dev, cmd, rbuf);
default:
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
- return 1;
+ return 0;
}
}
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;
}
/**
rbuf[6] = sector_size >> (8 * 1);
rbuf[7] = sector_size;
- return 0;
+ return 8;
}
/*
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 */
}
}
- return 0;
+ return 16;
}
/**
{
rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */
- return 0;
+ return 16;
}
/*
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]) {
rbuf[0] = rwcdlp;
rbuf[1] = cdlp | supported;
- return 0;
+ return 4;
}
/**