aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2005-10-12 03:06:27 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-18 17:16:13 -0400
commit8cbd6df1f0ce977ab7b61feffa59879bb5e0ed8f (patch)
treec460778581293ad479ec4983690ccc46bcb4df56 /drivers/scsi/libata-core.c
parent07506697d1c615924298406f2357810709c09bcd (diff)
[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>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c105
1 files changed, 37 insertions, 68 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 55d4dee133af..19d3d717faf6 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -616,79 +616,53 @@ void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf)
616 tf->hob_nsect = fis[13]; 616 tf->hob_nsect = fis[13];
617} 617}
618 618
619/** 619static const u8 ata_rw_cmds[] = {
620 * ata_prot_to_cmd - determine which read/write opcodes to use 620 /* pio multi */
621 * @protocol: ATA_PROT_xxx taskfile protocol 621 ATA_CMD_READ_MULTI,
622 * @lba48: true is lba48 is present 622 ATA_CMD_WRITE_MULTI,
623 * 623 ATA_CMD_READ_MULTI_EXT,
624 * Given necessary input, determine which read/write commands 624 ATA_CMD_WRITE_MULTI_EXT,
625 * to use to transfer data. 625 /* pio */
626 * 626 ATA_CMD_PIO_READ,
627 * LOCKING: 627 ATA_CMD_PIO_WRITE,
628 * None. 628 ATA_CMD_PIO_READ_EXT,
629 */ 629 ATA_CMD_PIO_WRITE_EXT,
630static int ata_prot_to_cmd(int protocol, int lba48) 630 /* dma */
631{ 631 ATA_CMD_READ,
632 int rcmd = 0, wcmd = 0; 632 ATA_CMD_WRITE,
633 633 ATA_CMD_READ_EXT,
634 switch (protocol) { 634 ATA_CMD_WRITE_EXT
635 case ATA_PROT_PIO: 635};
636 if (lba48) {
637 rcmd = ATA_CMD_PIO_READ_EXT;
638 wcmd = ATA_CMD_PIO_WRITE_EXT;
639 } else {
640 rcmd = ATA_CMD_PIO_READ;
641 wcmd = ATA_CMD_PIO_WRITE;
642 }
643 break;
644
645 case ATA_PROT_DMA:
646 if (lba48) {
647 rcmd = ATA_CMD_READ_EXT;
648 wcmd = ATA_CMD_WRITE_EXT;
649 } else {
650 rcmd = ATA_CMD_READ;
651 wcmd = ATA_CMD_WRITE;
652 }
653 break;
654
655 default:
656 return -1;
657 }
658
659 return rcmd | (wcmd << 8);
660}
661 636
662/** 637/**
663 * ata_dev_set_protocol - set taskfile protocol and r/w commands 638 * ata_rwcmd_protocol - set taskfile r/w commands and protocol
664 * @dev: device to examine and configure 639 * @qc: command to examine and configure
665 * 640 *
666 * Examine the device configuration, after we have 641 * Examine the device configuration and tf->flags to calculate
667 * read the identify-device page and configured the 642 * the proper read/write commands and protocol to use.
668 * data transfer mode. Set internal state related to
669 * the ATA taskfile protocol (pio, pio mult, dma, etc.)
670 * and calculate the proper read/write commands to use.
671 * 643 *
672 * LOCKING: 644 * LOCKING:
673 * caller. 645 * caller.
674 */ 646 */
675static void ata_dev_set_protocol(struct ata_device *dev) 647void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
676{ 648{
677 int pio = (dev->flags & ATA_DFLAG_PIO); 649 struct ata_taskfile *tf = &qc->tf;
678 int lba48 = (dev->flags & ATA_DFLAG_LBA48); 650 struct ata_device *dev = qc->dev;
679 int proto, cmd;
680 651
681 if (pio) 652 int index, lba48, write;
682 proto = dev->xfer_protocol = ATA_PROT_PIO; 653
683 else 654 lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
684 proto = dev->xfer_protocol = ATA_PROT_DMA; 655 write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
685 656
686 cmd = ata_prot_to_cmd(proto, lba48); 657 if (dev->flags & ATA_DFLAG_PIO) {
687 if (cmd < 0) 658 tf->protocol = ATA_PROT_PIO;
688 BUG(); 659 index = dev->multi_count ? 0 : 4;
660 } else {
661 tf->protocol = ATA_PROT_DMA;
662 index = 8;
663 }
689 664
690 dev->read_cmd = cmd & 0xff; 665 tf->command = ata_rw_cmds[index + lba48 + write];
691 dev->write_cmd = (cmd >> 8) & 0xff;
692} 666}
693 667
694static const char * xfer_mode_str[] = { 668static const char * xfer_mode_str[] = {
@@ -1641,7 +1615,7 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
1641 */ 1615 */
1642static void ata_set_mode(struct ata_port *ap) 1616static void ata_set_mode(struct ata_port *ap)
1643{ 1617{
1644 unsigned int i, xfer_shift; 1618 unsigned int xfer_shift;
1645 u8 xfer_mode; 1619 u8 xfer_mode;
1646 int rc; 1620 int rc;
1647 1621
@@ -1670,11 +1644,6 @@ static void ata_set_mode(struct ata_port *ap)
1670 if (ap->ops->post_set_mode) 1644 if (ap->ops->post_set_mode)
1671 ap->ops->post_set_mode(ap); 1645 ap->ops->post_set_mode(ap);
1672 1646
1673 for (i = 0; i < 2; i++) {
1674 struct ata_device *dev = &ap->device[i];
1675 ata_dev_set_protocol(dev);
1676 }
1677
1678 return; 1647 return;
1679 1648
1680err_out: 1649err_out: