Using low-level I/O calls, similar functions
(ex: ata_pio_devchk() and ata_mmio_devchk()) can be merged.
And some branches which check MMIO/PIO flag can be removed.
The idea comes from drivers/ide IN*/OUT* calls.

By default, depending on the flag, default_pio_ops or default_mmio_ops
are used as low-level I/O calls. If your device needs special I/O calls
(ex: 32bit access in Celleb), you must initialize .io_ops in ata_port_info
and pass it to appropriate initialization functions (ex: ata_pci_init_one()).

Signed-off-by: Kou Ishizaki <[EMAIL PROTECTED]>
Signed-off-by: Akira Iguchi <[EMAIL PROTECTED]>
---

--- linux-2.6.20-rc4/drivers/ata/libata-core.c.orig     2007-01-13 
01:01:50.000000000 +0900
+++ linux-2.6.20-rc4/drivers/ata/libata-core.c  2007-01-13 01:02:58.000000000 
+0900
@@ -598,51 +598,7 @@ void ata_dev_disable(struct ata_device *
 }
 
 /**
- *     ata_pio_devchk - PATA device presence detection
- *     @ap: ATA channel to examine
- *     @device: Device to examine (starting at zero)
- *
- *     This technique was originally described in
- *     Hale Landis's ATADRVR (www.ata-atapi.com), and
- *     later found its way into the ATA/ATAPI spec.
- *
- *     Write a pattern to the ATA shadow registers,
- *     and if a device is present, it will respond by
- *     correctly storing and echoing back the
- *     ATA shadow register contents.
- *
- *     LOCKING:
- *     caller.
- */
-
-static unsigned int ata_pio_devchk(struct ata_port *ap,
-                                  unsigned int device)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       u8 nsect, lbal;
-
-       ap->ops->dev_select(ap, device);
-
-       outb(0x55, ioaddr->nsect_addr);
-       outb(0xaa, ioaddr->lbal_addr);
-
-       outb(0xaa, ioaddr->nsect_addr);
-       outb(0x55, ioaddr->lbal_addr);
-
-       outb(0x55, ioaddr->nsect_addr);
-       outb(0xaa, ioaddr->lbal_addr);
-
-       nsect = inb(ioaddr->nsect_addr);
-       lbal = inb(ioaddr->lbal_addr);
-
-       if ((nsect == 0x55) && (lbal == 0xaa))
-               return 1;       /* we found a device */
-
-       return 0;               /* nothing found */
-}
-
-/**
- *     ata_mmio_devchk - PATA device presence detection
+ *     ata_devchk - PATA device presence detection
  *     @ap: ATA channel to examine
  *     @device: Device to examine (starting at zero)
  *
@@ -659,7 +615,7 @@ static unsigned int ata_pio_devchk(struc
  *     caller.
  */
 
-static unsigned int ata_mmio_devchk(struct ata_port *ap,
+static unsigned int ata_devchk(struct ata_port *ap,
                                    unsigned int device)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -667,17 +623,17 @@ static unsigned int ata_mmio_devchk(stru
 
        ap->ops->dev_select(ap, device);
 
-       writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
-       writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+       ap->io_ops->OUTB(0x55, ioaddr->nsect_addr);
+       ap->io_ops->OUTB(0xaa, ioaddr->lbal_addr);
 
-       writeb(0xaa, (void __iomem *) ioaddr->nsect_addr);
-       writeb(0x55, (void __iomem *) ioaddr->lbal_addr);
+       ap->io_ops->OUTB(0xaa, ioaddr->nsect_addr);
+       ap->io_ops->OUTB(0x55, ioaddr->lbal_addr);
 
-       writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
-       writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+       ap->io_ops->OUTB(0x55, ioaddr->nsect_addr);
+       ap->io_ops->OUTB(0xaa, ioaddr->lbal_addr);
 
-       nsect = readb((void __iomem *) ioaddr->nsect_addr);
-       lbal = readb((void __iomem *) ioaddr->lbal_addr);
+       nsect = ap->io_ops->INB(ioaddr->nsect_addr);
+       lbal = ap->io_ops->INB(ioaddr->lbal_addr);
 
        if ((nsect == 0x55) && (lbal == 0xaa))
                return 1;       /* we found a device */
@@ -686,27 +642,6 @@ static unsigned int ata_mmio_devchk(stru
 }
 
 /**
- *     ata_devchk - PATA device presence detection
- *     @ap: ATA channel to examine
- *     @device: Device to examine (starting at zero)
- *
- *     Dispatch ATA device presence detection, depending
- *     on whether we are using PIO or MMIO to talk to the
- *     ATA shadow registers.
- *
- *     LOCKING:
- *     caller.
- */
-
-static unsigned int ata_devchk(struct ata_port *ap,
-                                   unsigned int device)
-{
-       if (ap->flags & ATA_FLAG_MMIO)
-               return ata_mmio_devchk(ap, device);
-       return ata_pio_devchk(ap, device);
-}
-
-/**
  *     ata_dev_classify - determine device type based on ATA-spec signature
  *     @tf: ATA taskfile register set for device to be identified
  *
@@ -923,11 +858,7 @@ void ata_std_dev_select (struct ata_port
        else
                tmp = ATA_DEVICE_OBS | ATA_DEV1;
 
-       if (ap->flags & ATA_FLAG_MMIO) {
-               writeb(tmp, (void __iomem *) ap->ioaddr.device_addr);
-       } else {
-               outb(tmp, ap->ioaddr.device_addr);
-       }
+       ap->io_ops->OUTB(tmp, ap->ioaddr.device_addr);
        ata_pause(ap);          /* needed; also flushes, for mmio */
 }
 
@@ -2623,13 +2554,8 @@ static void ata_bus_post_reset(struct at
                u8 nsect, lbal;
 
                ap->ops->dev_select(ap, 1);
-               if (ap->flags & ATA_FLAG_MMIO) {
-                       nsect = readb((void __iomem *) ioaddr->nsect_addr);
-                       lbal = readb((void __iomem *) ioaddr->lbal_addr);
-               } else {
-                       nsect = inb(ioaddr->nsect_addr);
-                       lbal = inb(ioaddr->lbal_addr);
-               }
+               nsect = ap->io_ops->INB(ioaddr->nsect_addr);
+               lbal = ap->io_ops->INB(ioaddr->lbal_addr);
                if ((nsect == 1) && (lbal == 1))
                        break;
                if (time_after(jiffies, timeout)) {
@@ -2657,19 +2583,11 @@ static unsigned int ata_bus_softreset(st
        DPRINTK("ata%u: bus reset via SRST\n", ap->id);
 
        /* software reset.  causes dev0 to be selected */
-       if (ap->flags & ATA_FLAG_MMIO) {
-               writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-               udelay(20);     /* FIXME: flush */
-               writeb(ap->ctl | ATA_SRST, (void __iomem *) ioaddr->ctl_addr);
-               udelay(20);     /* FIXME: flush */
-               writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-       } else {
-               outb(ap->ctl, ioaddr->ctl_addr);
-               udelay(10);
-               outb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
-               udelay(10);
-               outb(ap->ctl, ioaddr->ctl_addr);
-       }
+       ap->io_ops->OUTB(ap->ctl, ioaddr->ctl_addr);
+       udelay(20);
+       ap->io_ops->OUTB(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+       udelay(20);
+       ap->io_ops->OUTB(ap->ctl, ioaddr->ctl_addr);
 
        /* spec mandates ">= 2ms" before checking status.
         * We wait 150ms, because that was the magic delay used for
@@ -2770,10 +2688,7 @@ void ata_bus_reset(struct ata_port *ap)
 
        if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
                /* set up device control for ATA_FLAG_SATA_RESET */
-               if (ap->flags & ATA_FLAG_MMIO)
-                       writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-               else
-                       outb(ap->ctl, ioaddr->ctl_addr);
+               ap->io_ops->OUTB(ap->ctl, ioaddr->ctl_addr);
        }
 
        DPRINTK("EXIT\n");
@@ -3167,10 +3082,7 @@ void ata_std_postreset(struct ata_port *
 
        /* set up device control */
        if (ap->ioaddr.ctl_addr) {
-               if (ap->flags & ATA_FLAG_MMIO)
-                       writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
-               else
-                       outb(ap->ctl, ap->ioaddr.ctl_addr);
+               ap->io_ops->OUTB(ap->ctl, ap->ioaddr.ctl_addr);
        }
 
        DPRINTK("EXIT\n");
@@ -3919,19 +3831,13 @@ void ata_mmio_data_xfer(struct ata_devic
                        unsigned int buflen, int write_data)
 {
        struct ata_port *ap = adev->ap;
-       unsigned int i;
        unsigned int words = buflen >> 1;
-       u16 *buf16 = (u16 *) buf;
-       void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
 
        /* Transfer multiple of 2 bytes */
-       if (write_data) {
-               for (i = 0; i < words; i++)
-                       writew(le16_to_cpu(buf16[i]), mmio);
-       } else {
-               for (i = 0; i < words; i++)
-                       buf16[i] = cpu_to_le16(readw(mmio));
-       }
+       if (write_data)
+               ap->io_ops->OUTSW(ap->ioaddr.data_addr, buf, words);
+       else
+               ap->io_ops->INSW(ap->ioaddr.data_addr, buf, words);
 
        /* Transfer trailing 1 byte, if any. */
        if (unlikely(buflen & 0x01)) {
@@ -3940,9 +3846,9 @@ void ata_mmio_data_xfer(struct ata_devic
 
                if (write_data) {
                        memcpy(align_buf, trailing_buf, 1);
-                       writew(le16_to_cpu(align_buf[0]), mmio);
+                       ap->io_ops->OUTW(le16_to_cpu(align_buf[0]), 
ap->ioaddr.data_addr);
                } else {
-                       align_buf[0] = cpu_to_le16(readw(mmio));
+                       align_buf[0] = 
cpu_to_le16(ap->io_ops->INW(ap->ioaddr.data_addr));
                        memcpy(trailing_buf, align_buf, 1);
                }
        }
@@ -3969,9 +3875,9 @@ void ata_pio_data_xfer(struct ata_device
 
        /* Transfer multiple of 2 bytes */
        if (write_data)
-               outsw(ap->ioaddr.data_addr, buf, words);
+               ap->io_ops->OUTSW(ap->ioaddr.data_addr, buf, words);
        else
-               insw(ap->ioaddr.data_addr, buf, words);
+               ap->io_ops->INSW(ap->ioaddr.data_addr, buf, words);
 
        /* Transfer trailing 1 byte, if any. */
        if (unlikely(buflen & 0x01)) {
@@ -3980,9 +3886,9 @@ void ata_pio_data_xfer(struct ata_device
 
                if (write_data) {
                        memcpy(align_buf, trailing_buf, 1);
-                       outw(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
+                       ap->io_ops->OUTW(le16_to_cpu(align_buf[0]), 
ap->ioaddr.data_addr);
                } else {
-                       align_buf[0] = cpu_to_le16(inw(ap->ioaddr.data_addr));
+                       align_buf[0] = 
cpu_to_le16(ap->io_ops->INW(ap->ioaddr.data_addr));
                        memcpy(trailing_buf, align_buf, 1);
                }
        }
@@ -5621,12 +5527,14 @@ void ata_port_init(struct ata_port *ap, 
                ap->udma_mask = ent->pinfo2->udma_mask;
                ap->flags |= ent->pinfo2->flags;
                ap->ops = ent->pinfo2->port_ops;
+               ap->io_ops = ent->pinfo2->io_ops;
        } else {
                ap->pio_mask = ent->pio_mask;
                ap->mwdma_mask = ent->mwdma_mask;
                ap->udma_mask = ent->udma_mask;
                ap->flags |= ent->port_flags;
                ap->ops = ent->port_ops;
+               ap->io_ops = ent->io_ops;
        }
        ap->hw_sata_spd_limit = UINT_MAX;
        ap->active_tag = ATA_TAG_POISON;
@@ -5732,6 +5640,126 @@ static struct ata_port * ata_port_add(co
        return ap;
 }
 
+/*
+ *     Conventional PIO operations for ATA devices
+ */
+
+static u8 ata_inb (unsigned long port)
+{
+       return (u8) inb(port);
+}
+
+static u16 ata_inw (unsigned long port)
+{
+       return (u16) inw(port);
+}
+
+static void ata_insw (unsigned long port, void *addr, u32 count)
+{
+       insw(port, addr, count);
+}
+
+static u32 ata_inl (unsigned long port)
+{
+       return (u32) inl(port);
+}
+
+static void ata_outb (u8 val, unsigned long port)
+{
+       outb(val, port);
+}
+
+static void ata_outw (u16 val, unsigned long port)
+{
+       outw(val, port);
+}
+
+static void ata_outsw (unsigned long port, void *addr, u32 count)
+{
+       outsw(port, addr, count);
+}
+
+static void ata_outl (u32 val, unsigned long port)
+{
+       outl(val, port);
+}
+
+/*
+ *     Conventional MMIO operations for ATA devices
+ */
+
+static u8 ata_mm_inb (unsigned long port)
+{
+       return (u8) readb((void __iomem *) port);
+}
+
+static u16 ata_mm_inw (unsigned long port)
+{
+       return (u16) readw((void __iomem *) port);
+}
+
+static void ata_mm_insw (unsigned long port, void *addr, u32 count)
+{
+       unsigned int i;
+       u16 *buf16 = (u16 *) addr;
+       void __iomem *mmio = (void __iomem *) port;
+
+       for (i = 0; i < count; i++)
+               buf16[i] = cpu_to_le16(readw(mmio));
+}
+
+static u32 ata_mm_inl (unsigned long port)
+{
+       return (u32) readl((void __iomem *) port);
+}
+
+static void ata_mm_outb (u8 value, unsigned long port)
+{
+       writeb(value, (void __iomem *) port);
+}
+
+static void ata_mm_outw (u16 value, unsigned long port)
+{
+       writew(value, (void __iomem *) port);
+}
+
+static void ata_mm_outsw (unsigned long port, void *addr, u32 count)
+{
+       unsigned int i;
+       u16 *buf16 = (u16 *) addr;
+       void __iomem *mmio = (void __iomem *) port;
+
+       for (i = 0; i < count; i++)
+               writew(le16_to_cpu(buf16[i]), mmio);
+}
+
+static void ata_mm_outl (u32 value, unsigned long port)
+{
+       writel(value, (void __iomem *) port);
+}
+
+static struct ata_io_operations default_pio_ops = {
+       .OUTB                   = ata_outb,
+       .OUTW                   = ata_outw,
+       .OUTL                   = ata_outl,
+       .OUTSW                  = ata_outsw,
+       .INB                    = ata_inb,
+       .INW                    = ata_inw,
+       .INL                    = ata_inl,
+       .INSW                   = ata_insw,
+};
+
+static struct ata_io_operations default_mmio_ops = {
+       .OUTB                   = ata_mm_outb,
+       .OUTW                   = ata_mm_outw,
+       .OUTL                   = ata_mm_outl,
+       .OUTSW                  = ata_mm_outsw,
+       .INB                    = ata_mm_inb,
+       .INW                    = ata_mm_inw,
+       .INL                    = ata_mm_inl,
+       .INSW                   = ata_mm_insw,
+};
+
 /**
  *     ata_sas_host_init - Initialize a host struct
  *     @host:  host to initialize
@@ -5745,12 +5773,16 @@ static struct ata_port * ata_port_add(co
  */
 
 void ata_host_init(struct ata_host *host, struct device *dev,
-                  unsigned long flags, const struct ata_port_operations *ops)
+                  unsigned long flags, const struct ata_port_operations *ops,
+                  struct ata_io_operations *io_ops)
 {
        spin_lock_init(&host->lock);
        host->dev = dev;
        host->flags = flags;
        host->ops = ops;
+
+       if (!io_ops)
+               host->io_ops = flags & ATA_FLAG_MMIO ? &default_mmio_ops : 
&default_pio_ops;
 }
 
 /**
@@ -5790,7 +5822,7 @@ int ata_device_add(const struct ata_prob
        if (!host)
                return 0;
 
-       ata_host_init(host, dev, ent->_host_flags, ent->port_ops);
+       ata_host_init(host, dev, ent->_host_flags, ent->port_ops, ent->io_ops);
        host->n_ports = ent->n_ports;
        host->irq = ent->irq;
        host->irq2 = ent->irq2;
@@ -6110,6 +6142,7 @@ ata_probe_ent_alloc(struct device *dev, 
        probe_ent->mwdma_mask = port->mwdma_mask;
        probe_ent->udma_mask = port->udma_mask;
        probe_ent->port_ops = port->port_ops;
+       probe_ent->io_ops = port->io_ops;
        probe_ent->private_data = port->private_data;
 
        return probe_ent;
@@ -6500,3 +6533,5 @@ EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
 EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
 EXPORT_SYMBOL_GPL(ata_do_eh);
+
+EXPORT_SYMBOL_GPL(ata_probe_ent_alloc);

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

Reply via email to