[PATCH] libata CHS: calculate read/write commands and protocol on the fly (revise #6)

- merge ata_prot_to_cmd() and ata_dev_set_protocol() as
       ata_rwcmd_protocol()
     - pave road for read/write multiple support
     - remove usage of pre-cached command and protocol values and call
       ata_rwcmd_protocol() instead

Signed-off-by: Albert Lee <albertcc@tw.ibm.com>

==============
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
Albert Lee
2005-10-12 15:06:27 +08:00
committed by Jeff Garzik
parent 07506697d1
commit 8cbd6df1f0
5 changed files with 50 additions and 79 deletions

View File

@ -616,79 +616,53 @@ void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf)
tf->hob_nsect = fis[13];
}
/**
* ata_prot_to_cmd - determine which read/write opcodes to use
* @protocol: ATA_PROT_xxx taskfile protocol
* @lba48: true is lba48 is present
*
* Given necessary input, determine which read/write commands
* to use to transfer data.
*
* LOCKING:
* None.
*/
static int ata_prot_to_cmd(int protocol, int lba48)
{
int rcmd = 0, wcmd = 0;
switch (protocol) {
case ATA_PROT_PIO:
if (lba48) {
rcmd = ATA_CMD_PIO_READ_EXT;
wcmd = ATA_CMD_PIO_WRITE_EXT;
} else {
rcmd = ATA_CMD_PIO_READ;
wcmd = ATA_CMD_PIO_WRITE;
}
break;
case ATA_PROT_DMA:
if (lba48) {
rcmd = ATA_CMD_READ_EXT;
wcmd = ATA_CMD_WRITE_EXT;
} else {
rcmd = ATA_CMD_READ;
wcmd = ATA_CMD_WRITE;
}
break;
default:
return -1;
}
return rcmd | (wcmd << 8);
}
static const u8 ata_rw_cmds[] = {
/* pio multi */
ATA_CMD_READ_MULTI,
ATA_CMD_WRITE_MULTI,
ATA_CMD_READ_MULTI_EXT,
ATA_CMD_WRITE_MULTI_EXT,
/* pio */
ATA_CMD_PIO_READ,
ATA_CMD_PIO_WRITE,
ATA_CMD_PIO_READ_EXT,
ATA_CMD_PIO_WRITE_EXT,
/* dma */
ATA_CMD_READ,
ATA_CMD_WRITE,
ATA_CMD_READ_EXT,
ATA_CMD_WRITE_EXT
};
/**
* ata_dev_set_protocol - set taskfile protocol and r/w commands
* @dev: device to examine and configure
* ata_rwcmd_protocol - set taskfile r/w commands and protocol
* @qc: command to examine and configure
*
* Examine the device configuration, after we have
* read the identify-device page and configured the
* data transfer mode. Set internal state related to
* the ATA taskfile protocol (pio, pio mult, dma, etc.)
* and calculate the proper read/write commands to use.
* Examine the device configuration and tf->flags to calculate
* the proper read/write commands and protocol to use.
*
* LOCKING:
* caller.
*/
static void ata_dev_set_protocol(struct ata_device *dev)
void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
{
int pio = (dev->flags & ATA_DFLAG_PIO);
int lba48 = (dev->flags & ATA_DFLAG_LBA48);
int proto, cmd;
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
if (pio)
proto = dev->xfer_protocol = ATA_PROT_PIO;
else
proto = dev->xfer_protocol = ATA_PROT_DMA;
int index, lba48, write;
lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
cmd = ata_prot_to_cmd(proto, lba48);
if (cmd < 0)
BUG();
if (dev->flags & ATA_DFLAG_PIO) {
tf->protocol = ATA_PROT_PIO;
index = dev->multi_count ? 0 : 4;
} else {
tf->protocol = ATA_PROT_DMA;
index = 8;
}
dev->read_cmd = cmd & 0xff;
dev->write_cmd = (cmd >> 8) & 0xff;
tf->command = ata_rw_cmds[index + lba48 + write];
}
static const char * xfer_mode_str[] = {
@ -1641,7 +1615,7 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
*/
static void ata_set_mode(struct ata_port *ap)
{
unsigned int i, xfer_shift;
unsigned int xfer_shift;
u8 xfer_mode;
int rc;
@ -1670,11 +1644,6 @@ static void ata_set_mode(struct ata_port *ap)
if (ap->ops->post_set_mode)
ap->ops->post_set_mode(ap);
for (i = 0; i < 2; i++) {
struct ata_device *dev = &ap->device[i];
ata_dev_set_protocol(dev);
}
return;
err_out: