From: Mark Lord <liml@rtr.ca>
To: Jeff Garzik <jgarzik@pobox.com>, Tejun Heo <htejun@gmail.com>,
IDE/ATA development list <linux-ide@vger.kernel.org>
Subject: [PATCH] libata: add support for READ/WRITE LONG commands
Date: Mon, 12 Feb 2007 19:58:22 -0500 [thread overview]
Message-ID: <45D10D2E.70408@rtr.ca> (raw)
The READ/WRITE LONG commands are theoretically obsolete,
but most (all?) drives to date still implement them.
Of these, WRITE_LONG and WRITE_LONG_ONCE are of particular
interest for fault injection testing -- eg. creating "media errors"
at specific locations on a disk.
The fussy bit is that these commands require a non-standard
sector size, usually 520 bytes instead of 512.
This patch adds support to libata for READ/WRITE LONG commands
issued via SG_IO/ATA_16.
Signed-off-by: Mark Lord <mlord@pobox.com>
---
diff -u --recursive --new-file --exclude='.*' --exclude='*.[osa]' --exclude='*.ko' --exclude='*.mod.c' linux-2.6.20/drivers/ata/libata-core.c new/drivers/ata/libata-core.c
--- linux-2.6.20/drivers/ata/libata-core.c 2007-02-04 13:44:54.000000000 -0500
+++ new/drivers/ata/libata-core.c 2007-02-12 19:41:55.000000000 -0500
@@ -1249,7 +1249,7 @@
buflen += sg[i].length;
ata_sg_init(qc, sg, n_elem);
- qc->nsect = buflen / ATA_SECT_SIZE;
+ qc->nsect = buflen / qc->sect_size;
qc->nbytes = buflen;
}
@@ -4004,7 +4004,7 @@
/**
- * ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data.
+ * ata_pio_sector - Transfer a "sector" of data.
* @qc: Command on going
*
* Transfer ATA_SECT_SIZE of data from/to the ATA device.
@@ -4021,12 +4021,13 @@
struct page *page;
unsigned int offset;
unsigned char *buf;
+ unsigned int sect_size = qc->sect_size;
if (qc->cursect == (qc->nsect - 1))
ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page;
- offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
+ offset = sg[qc->cursg].offset + qc->cursg_ofs * sect_size;
/* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4042,30 +4043,30 @@
buf = kmap_atomic(page, KM_IRQ0);
/* do the actual data transfer */
- ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
+ ap->ops->data_xfer(qc->dev, buf + offset, sect_size, do_write);
kunmap_atomic(buf, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = page_address(page);
- ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
+ ap->ops->data_xfer(qc->dev, buf + offset, sect_size, do_write);
}
qc->cursect++;
qc->cursg_ofs++;
- if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
+ if ((qc->cursg_ofs * sect_size) == (&sg[qc->cursg])->length) {
qc->cursg++;
qc->cursg_ofs = 0;
}
}
/**
- * ata_pio_sectors - Transfer one or many 512-byte sectors.
+ * ata_pio_sectors - Transfer one or many sectors.
* @qc: Command on going
*
- * Transfer one or many ATA_SECT_SIZE of data from/to the
- * ATA device for the DRQ request.
+ * Transfer one or many qc->sect_size chunks of data
+ * from/to the ATA device for the DRQ request.
*
* LOCKING:
* Inherited from caller.
diff -u --recursive --new-file --exclude='.*' --exclude='*.[osa]' --exclude='*.ko' --exclude='*.mod.c' linux-2.6.20/drivers/ata/libata-scsi.c new/drivers/ata/libata-scsi.c
--- linux-2.6.20/drivers/ata/libata-scsi.c 2007-02-04 13:44:54.000000000 -0500
+++ new/drivers/ata/libata-scsi.c 2007-02-12 19:38:55.000000000 -0500
@@ -2634,6 +2634,19 @@
tf->device = qc->dev->devno ?
tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+ /* READ/WRITE LONG use a non-standard sect_size */
+ qc->sect_size = ATA_SECT_SIZE;
+ switch (tf->command) {
+ case ATA_CMD_READ_LONG:
+ case ATA_CMD_READ_LONG_ONCE:
+ case ATA_CMD_WRITE_LONG:
+ case ATA_CMD_WRITE_LONG_ONCE:
+ if (tf->protocol != ATA_PROT_PIO
+ || tf->nsect != 1)
+ goto invalid_fld;
+ qc->sect_size = cmd->request_bufflen;
+ }
+
/*
* Filter SET_FEATURES - XFER MODE command -- otherwise,
* SET_FEATURES - XFER MODE must be preceded/succeeded
@@ -2661,7 +2674,7 @@
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE;
+ qc->nsect = scmd->request_bufflen / qc->sect_size;
/* request result TF */
qc->flags |= ATA_QCFLAG_RESULT_TF;
diff -u --recursive --new-file --exclude='.*' --exclude='*.[osa]' --exclude='*.ko' --exclude='*.mod.c' linux-2.6.20/include/linux/ata.h new/include/linux/ata.h
--- linux-2.6.20/include/linux/ata.h 2007-02-04 13:44:54.000000000 -0500
+++ new/include/linux/ata.h 2007-02-12 19:34:30.000000000 -0500
@@ -160,6 +160,12 @@
/* READ_LOG_EXT pages */
ATA_LOG_SATA_NCQ = 0x10,
+ /* READ/WRITE LONG (obsolete) */
+ ATA_CMD_READ_LONG = 0x22,
+ ATA_CMD_READ_LONG_ONCE = 0x23,
+ ATA_CMD_WRITE_LONG = 0x32,
+ ATA_CMD_WRITE_LONG_ONCE = 0x33,
+
/* SETFEATURES stuff */
SETFEATURES_XFER = 0x03,
XFER_UDMA_7 = 0x47,
diff -u --recursive --new-file --exclude='.*' --exclude='*.[osa]' --exclude='*.ko' --exclude='*.mod.c' linux-2.6.20/include/linux/libata.h new/include/linux/libata.h
--- linux-2.6.20/include/linux/libata.h 2007-02-04 13:44:54.000000000 -0500
+++ new/include/linux/libata.h 2007-02-12 19:32:57.000000000 -0500
@@ -430,6 +430,7 @@
int dma_dir;
unsigned int pad_len;
+ unsigned int sect_size;
unsigned int nsect;
unsigned int cursect;
@@ -1155,6 +1156,7 @@
qc->n_elem = 0;
qc->err_mask = 0;
qc->pad_len = 0;
+ qc->sect_size = 512;
ata_tf_init(qc->dev, &qc->tf);
next reply other threads:[~2007-02-13 0:58 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-13 0:58 Mark Lord [this message]
2007-02-13 18:30 ` [PATCH] libata: [take 2] add support for READ/WRITE LONG commands Mark Lord
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45D10D2E.70408@rtr.ca \
--to=liml@rtr.ca \
--cc=htejun@gmail.com \
--cc=jgarzik@pobox.com \
--cc=linux-ide@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).