]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/pata_legacy.c
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-omap-h63xx.git] / drivers / ata / pata_legacy.c
index 9532b9bb6d2f0f0270f2de3fed88a60b4fc36b64..98c1fee4b305a92f3d92f08506010d861ee027c4 100644 (file)
@@ -89,9 +89,10 @@ static int probe_all;                        /* Set to check all ISA port ranges */
 static int ht6560a;                    /* HT 6560A on primary 1, secondary 2, both 3 */
 static int ht6560b;                    /* HT 6560A on primary 1, secondary 2, both 3 */
 static int opti82c611a;                        /* Opti82c611A on primary 1, secondary 2, both 3 */
-static int opti82c46x;         /* Opti 82c465MV present (pri/sec autodetect) */
+static int opti82c46x;                 /* Opti 82c465MV present (pri/sec autodetect) */
 static int autospeed;                  /* Chip present which snoops speed changes */
 static int pio_mask = 0x1F;            /* PIO range for autospeed devices */
+static int iordy_mask = 0xFFFFFFFF;    /* Use iordy if available */
 
 /**
  *     legacy_set_mode         -       mode setting
@@ -113,6 +114,7 @@ static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused)
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
                if (ata_dev_enabled(dev)) {
+                       ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
                        dev->pio_mode = XFER_PIO_0;
                        dev->xfer_mode = XFER_PIO_0;
                        dev->xfer_shift = ATA_SHIFT_PIO;
@@ -164,10 +166,12 @@ static struct ata_port_operations simple_port_ops = {
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
-       .data_xfer      = ata_pio_data_xfer_noirq,
+       .data_xfer      = ata_data_xfer_noirq,
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
 
        .port_start     = ata_port_start,
 };
@@ -187,10 +191,12 @@ static struct ata_port_operations legacy_port_ops = {
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
-       .data_xfer      = ata_pio_data_xfer_noirq,
+       .data_xfer      = ata_data_xfer_noirq,
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
 
        .port_start     = ata_port_start,
 };
@@ -253,31 +259,33 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig
                local_irq_save(flags);
 
                /* Perform the 32bit I/O synchronization sequence */
-               inb(ap->ioaddr.nsect_addr);
-               inb(ap->ioaddr.nsect_addr);
-               inb(ap->ioaddr.nsect_addr);
+               ioread8(ap->ioaddr.nsect_addr);
+               ioread8(ap->ioaddr.nsect_addr);
+               ioread8(ap->ioaddr.nsect_addr);
 
                /* Now the data */
 
                if (write_data)
-                       outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+                       iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
                else
-                       insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+                       ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
 
                if (unlikely(slop)) {
                        u32 pad;
                        if (write_data) {
                                memcpy(&pad, buf + buflen - slop, slop);
-                               outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+                               pad = le32_to_cpu(pad);
+                               iowrite32(pad, ap->ioaddr.data_addr);
                        } else {
-                               pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+                               pad = ioread32(ap->ioaddr.data_addr);
+                               pad = cpu_to_le16(pad);
                                memcpy(buf + buflen - slop, &pad, slop);
                        }
                }
                local_irq_restore(flags);
        }
        else
-               ata_pio_data_xfer_noirq(adev, buf, buflen, write_data);
+               ata_data_xfer_noirq(adev, buf, buflen, write_data);
 }
 
 static struct ata_port_operations pdc20230_port_ops = {
@@ -299,6 +307,8 @@ static struct ata_port_operations pdc20230_port_ops = {
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
 
        .port_start     = ata_port_start,
 };
@@ -326,8 +336,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev)
        inb(0x3E6);
        inb(0x3E6);
 
-       outb(recover << 4 | active, ap->ioaddr.device_addr);
-       inb(ap->ioaddr.status_addr);
+       iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
+       ioread8(ap->ioaddr.status_addr);
 }
 
 static struct ata_port_operations ht6560a_port_ops = {
@@ -345,10 +355,12 @@ static struct ata_port_operations ht6560a_port_ops = {
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
-       .data_xfer      = ata_pio_data_xfer,    /* Check vlb/noirq */
+       .data_xfer      = ata_data_xfer,        /* Check vlb/noirq */
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
 
        .port_start     = ata_port_start,
 };
@@ -379,7 +391,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
        inb(0x3E6);
        inb(0x3E6);
 
-       outb(recover << 4 | active, ap->ioaddr.device_addr);
+       iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
 
        if (adev->class != ATA_DEV_ATA) {
                u8 rconf = inb(0x3E6);
@@ -388,7 +400,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
                        outb(rconf, 0x3E6);
                }
        }
-       inb(ap->ioaddr.status_addr);
+       ioread8(ap->ioaddr.status_addr);
 }
 
 static struct ata_port_operations ht6560b_port_ops = {
@@ -406,10 +418,12 @@ static struct ata_port_operations ht6560b_port_ops = {
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
-       .data_xfer      = ata_pio_data_xfer,    /* FIXME: Check 32bit and noirq */
+       .data_xfer      = ata_data_xfer,        /* FIXME: Check 32bit and noirq */
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
 
        .port_start     = ata_port_start,
 };
@@ -454,12 +468,12 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev
        u8 rc;
 
        /* Enter configuration mode */
-       inw(ap->ioaddr.error_addr);
-       inw(ap->ioaddr.error_addr);
-       outb(3, ap->ioaddr.nsect_addr);
+       ioread16(ap->ioaddr.error_addr);
+       ioread16(ap->ioaddr.error_addr);
+       iowrite8(3, ap->ioaddr.nsect_addr);
 
        /* Read VLB clock strapping */
-       clock = 1000000000 / khz[inb(ap->ioaddr.lbah_addr) & 0x03];
+       clock = 1000000000 / khz[ioread8(ap->ioaddr.lbah_addr) & 0x03];
 
        /* Get the timing data in cycles */
        ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
@@ -477,33 +491,33 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev
        setup = FIT(t.setup, 1, 4) - 1;
 
        /* Select the right timing bank for write timing */
-       rc = inb(ap->ioaddr.lbal_addr);
+       rc = ioread8(ap->ioaddr.lbal_addr);
        rc &= 0x7F;
        rc |= (adev->devno << 7);
-       outb(rc, ap->ioaddr.lbal_addr);
+       iowrite8(rc, ap->ioaddr.lbal_addr);
 
        /* Write the timings */
-       outb(active << 4 | recover, ap->ioaddr.error_addr);
+       iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
 
        /* Select the right bank for read timings, also
           load the shared timings for address */
-       rc = inb(ap->ioaddr.device_addr);
+       rc = ioread8(ap->ioaddr.device_addr);
        rc &= 0xC0;
        rc |= adev->devno;      /* Index select */
        rc |= (setup << 4) | 0x04;
-       outb(rc, ap->ioaddr.device_addr);
+       iowrite8(rc, ap->ioaddr.device_addr);
 
        /* Load the read timings */
-       outb(active << 4 | recover, ap->ioaddr.data_addr);
+       iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
 
        /* Ensure the timing register mode is right */
-       rc = inb (ap->ioaddr.lbal_addr);
+       rc = ioread8(ap->ioaddr.lbal_addr);
        rc &= 0x73;
        rc |= 0x84;
-       outb(rc, ap->ioaddr.lbal_addr);
+       iowrite8(rc, ap->ioaddr.lbal_addr);
 
        /* Exit command mode */
-       outb(0x83,  ap->ioaddr.nsect_addr);
+       iowrite8(0x83,  ap->ioaddr.nsect_addr);
 }
 
 
@@ -522,10 +536,12 @@ static struct ata_port_operations opti82c611a_port_ops = {
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
-       .data_xfer      = ata_pio_data_xfer,
+       .data_xfer      = ata_data_xfer,
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
 
        .port_start     = ata_port_start,
 };
@@ -551,9 +567,9 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
        sysclk = opti_syscfg(0xAC) & 0xC0;      /* BIOS set */
 
        /* Enter configuration mode */
-       inw(ap->ioaddr.error_addr);
-       inw(ap->ioaddr.error_addr);
-       outb(3, ap->ioaddr.nsect_addr);
+       ioread16(ap->ioaddr.error_addr);
+       ioread16(ap->ioaddr.error_addr);
+       iowrite8(3, ap->ioaddr.nsect_addr);
 
        /* Read VLB clock strapping */
        clock = 1000000000 / khz[sysclk];
@@ -574,33 +590,33 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
        setup = FIT(t.setup, 1, 4) - 1;
 
        /* Select the right timing bank for write timing */
-       rc = inb(ap->ioaddr.lbal_addr);
+       rc = ioread8(ap->ioaddr.lbal_addr);
        rc &= 0x7F;
        rc |= (adev->devno << 7);
-       outb(rc, ap->ioaddr.lbal_addr);
+       iowrite8(rc, ap->ioaddr.lbal_addr);
 
        /* Write the timings */
-       outb(active << 4 | recover, ap->ioaddr.error_addr);
+       iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
 
        /* Select the right bank for read timings, also
           load the shared timings for address */
-       rc = inb(ap->ioaddr.device_addr);
+       rc = ioread8(ap->ioaddr.device_addr);
        rc &= 0xC0;
        rc |= adev->devno;      /* Index select */
        rc |= (setup << 4) | 0x04;
-       outb(rc, ap->ioaddr.device_addr);
+       iowrite8(rc, ap->ioaddr.device_addr);
 
        /* Load the read timings */
-       outb(active << 4 | recover, ap->ioaddr.data_addr);
+       iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
 
        /* Ensure the timing register mode is right */
-       rc = inb (ap->ioaddr.lbal_addr);
+       rc = ioread8(ap->ioaddr.lbal_addr);
        rc &= 0x73;
        rc |= 0x84;
-       outb(rc, ap->ioaddr.lbal_addr);
+       iowrite8(rc, ap->ioaddr.lbal_addr);
 
        /* Exit command mode */
-       outb(0x83,  ap->ioaddr.nsect_addr);
+       iowrite8(0x83,  ap->ioaddr.nsect_addr);
 
        /* We need to know this for quad device on the MVB */
        ap->host->private_data = ap;
@@ -650,10 +666,12 @@ static struct ata_port_operations opti82c46x_port_ops = {
        .qc_prep        = ata_qc_prep,
        .qc_issue       = opti82c46x_qc_issue_prot,
 
-       .data_xfer      = ata_pio_data_xfer,
+       .data_xfer      = ata_data_xfer,
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
 
        .port_start     = ata_port_start,
 };
@@ -676,8 +694,10 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
        struct ata_probe_ent ae;
        struct platform_device *pdev;
        struct ata_port_operations *ops = &legacy_port_ops;
+       void __iomem *io_addr, *ctrl_addr;
        int pio_modes = pio_mask;
        u32 mask = (1 << port);
+       u32 iordy = (iordy_mask & mask) ? 0: ATA_FLAG_NO_IORDY;
        int ret;
 
        pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0);
@@ -689,9 +709,16 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
            devm_request_region(&pdev->dev, ctrl, 1, "pata_legacy") == NULL)
                goto fail;
 
+       ret = -ENOMEM;
+       io_addr = devm_ioport_map(&pdev->dev, io, 8);
+       ctrl_addr = devm_ioport_map(&pdev->dev, ctrl, 1);
+       if (!io_addr || !ctrl_addr)
+               goto fail;
+
        if (ht6560a & mask) {
                ops = &ht6560a_port_ops;
                pio_modes = 0x07;
+               iordy = ATA_FLAG_NO_IORDY;
        }
        if (ht6560b & mask) {
                ops = &ht6560b_port_ops;
@@ -727,6 +754,7 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
                        printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller detected.\n");
                                pio_modes = 0x07;
                        ops = &pdc20230_port_ops;
+                       iordy = ATA_FLAG_NO_IORDY;
                        udelay(100);
                        inb(0x1F5);
                } else {
@@ -744,6 +772,7 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
        /* Chip does mode setting by command snooping */
        if (ops == &legacy_port_ops && (autospeed & mask))
                ops = &simple_port_ops;
+
        memset(&ae, 0, sizeof(struct ata_probe_ent));
        INIT_LIST_HEAD(&ae.node);
        ae.dev = &pdev->dev;
@@ -753,10 +782,10 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
        ae.pio_mask = pio_modes;
        ae.irq = irq;
        ae.irq_flags = 0;
-       ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
-       ae.port[0].cmd_addr = io;
-       ae.port[0].altstatus_addr = ctrl;
-       ae.port[0].ctl_addr =   ctrl;
+       ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy;
+       ae.port[0].cmd_addr = io_addr;
+       ae.port[0].altstatus_addr = ctrl_addr;
+       ae.port[0].ctl_addr = ctrl_addr;
        ata_std_ports(&ae.port[0]);
        ae.private_data = ld;
 
@@ -922,6 +951,7 @@ module_param(ht6560b, int, 0);
 module_param(opti82c611a, int, 0);
 module_param(opti82c46x, int, 0);
 module_param(pio_mask, int, 0);
+module_param(iordy_mask, int, 0);
 
 module_init(legacy_init);
 module_exit(legacy_exit);