Re: [RFC] Read/Write Buffer support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Matthew Wilcox wrote:
This patch adds partial support for the SCSI commands READ_BUFFER and
WRITE_BUFFER.  Because ATA only supports a single 512-byte buffer per
drive, this isn't as useful as it could be, but it might prove interesting
when extended to handle the DOWNLOAD MICROCODE operations.

General concept:  ACK

Minor nits below...


diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 8f0e8f2..f12403f 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1711,6 +1711,117 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
 	args->done(cmd);
 }
+/*
+ * This helper is used for three subcommands of READ_BUFFER.  Subcommand 0
+ * wants a header prefixing the data.  Subcommand 3 returns a descriptor
+ * and subcommand 0xb returns a descriptor for the echo buffer.  While these
+ * all have slightly different formats, in practise they all look sufficiently
+ * similar that this common function can be used.
+ */
+static void ata_scsi_fill_buffer_descriptor(struct scsi_cmnd *cmd, int desc)
+{
+	u8 *rbuf;
+	unsigned int buflen;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	buflen = ata_scsi_rbuf_get(cmd, &rbuf);
+
+	memset(rbuf, 0, buflen);
+	rbuf[0] = desc ? 0xff : 0x0;
+	rbuf[1] = 0x0;
+	rbuf[2] = 0x2;
+	rbuf[3] = 0x0;
+
+	ata_scsi_rbuf_put(cmd, rbuf);
+
+	local_irq_restore(flags);
+}

use ata_scsi_rbuf_fill() rather than recreating it manually


+static int ata_scsi_read_buffer_descriptor(struct scsi_cmnd *cmd)
+{
+	ata_scsi_fill_buffer_descriptor(cmd, cmd->cmnd[1] == 0x3);
+
+	cmd->result = SAM_STAT_GOOD;
+	return 1;
+}
+
+static void ata_scsi_rwbuf_header(struct scsi_cmnd *cmd)
+{
+	struct scatterlist *sg = scsi_sglist(cmd);
+	ata_scsi_fill_buffer_descriptor(cmd, 0);
+
+	/* XXX: fewer than 4 bytes in the page?  Doomed. */
+	sg->offset += 4;
+	sg->length -= 4;

I'm quite uncomfortable skipping any amount of validation.


+/**
+ * ata_scsi_rwbuf_xlat - Translate READ_BUFFER and WRITE_BUFFER
+ *
+ * SCSI has a very flexible READ_BUFFER and WRITE_BUFFER system.
+ * ATA's READ BUFFER only supports an offset of 0 and length 512.
+ * SCSI also uses WRITE_BUFFER for DOWNLOAD MICROCODE, which is not
+ * yet supported by this function.
+ */
+static unsigned int ata_scsi_rwbuf_xlat(struct ata_queued_cmd *qc)
+{
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	const u8 *cdb = scmd->cmnd;
+	struct ata_taskfile *tf = &qc->tf;
+	int offset = 0;
+
+	if (cdb[0] == WRITE_BUFFER) {
+		tf->flags |= ATA_TFLAG_WRITE;
+		tf->command = ATA_CMD_WRITE_BUFFER;
+	} else {
+		tf->command = ATA_CMD_READ_BUFFER;
+	}
+
+	switch (cdb[1]) {
+	case 0x0:	/* Read/write data with header */
+		ata_scsi_rwbuf_header(scmd);
+		offset = 4;
+	case 0x2:	/* Read/write data */
+	case 0xa:	/* Read/write echo buffer */
+		break;
+	case 0x3:	/* Read descriptor */
+	case 0xb:	/* Read echo buffer descriptor */
+		if (cdb[0] == READ_BUFFER)
+			return ata_scsi_read_buffer_descriptor(scmd);
+	case 0x4:
+	case 0x5:
+	case 0x6:
+	case 0x7:
+		/* XXX: We can translate to DOWNLOAD_MICROCODE here */

Style in libata is "FIXME" or "TODO" not "XXX". Please help with consistency, it makes grepping easier.

Plus, I dunno about you, but I'm not a porn star :)

	Jeff




--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux