Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[safe/jmp/linux-2.6] / drivers / parport / parport_pc.c
index edf83e9..2597145 100644 (file)
@@ -626,7 +626,7 @@ static size_t parport_pc_fifo_write_block_dma(struct parport *port,
        unsigned long start = (unsigned long) buf;
        unsigned long end = (unsigned long) buf + length - 1;
 
-dump_parport_state("enter fifo_write_block_dma", port);
+       dump_parport_state("enter fifo_write_block_dma", port);
        if (end < MAX_DMA_ADDRESS) {
                /* If it would cross a 64k boundary, cap it at the end. */
                if ((start ^ end) & ~0xffffUL)
@@ -737,7 +737,7 @@ false_alarm:
        if (dma_handle)
                dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE);
 
-dump_parport_state("leave fifo_write_block_dma", port);
+       dump_parport_state("leave fifo_write_block_dma", port);
        return length - left;
 }
 #endif
@@ -955,8 +955,8 @@ static size_t parport_pc_ecp_read_block_pio(struct parport *port,
        char *bufp = buf;
 
        port = port->physport;
-DPRINTK(KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n");
-dump_parport_state("enter fcn", port);
+       DPRINTK(KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n");
+       dump_parport_state("enter fcn", port);
 
        /* Special case: a timeout of zero means we cannot call schedule().
         * Also if O_NONBLOCK is set then use the default implementation. */
@@ -1112,14 +1112,15 @@ false_alarm:
 
                if (ecrval & 0x02) {
                        /* FIFO is full. */
-dump_parport_state("FIFO full", port);
+                       dump_parport_state("FIFO full", port);
                        insb(fifo, bufp, fifo_depth);
                        bufp += fifo_depth;
                        left -= fifo_depth;
                        continue;
                }
 
-DPRINTK(KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n");
+               DPRINTK(KERN_DEBUG
+                 "*** ecp_read_block_pio: reading one byte from the FIFO\n");
 
                /* FIFO not filled.  We will cycle this loop for a while
                 * and either the peripheral will fill it faster,
@@ -1135,7 +1136,7 @@ DPRINTK(KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n");
        }
 
        port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
-dump_parport_state("rev idle2", port);
+       dump_parport_state("rev idle2", port);
 
 out_no_data:
 
@@ -1163,7 +1164,7 @@ out_no_data:
                                port->name, lost);
        }
 
-dump_parport_state("fwd idle", port);
+       dump_parport_state("fwd idle", port);
        return length - left;
 }
 #endif  /*  0  */
@@ -1216,10 +1217,23 @@ static const struct parport_operations parport_pc_ops = {
 };
 
 #ifdef CONFIG_PARPORT_PC_SUPERIO
+
+static struct superio_struct *find_free_superio(void)
+{
+       int i;
+       for (i = 0; i < NR_SUPERIOS; i++)
+               if (superios[i].io == 0)
+                       return &superios[i];
+       return NULL;
+}
+
+
 /* Super-IO chipset detection, Winbond, SMSC */
 static void __devinit show_parconfig_smsc37c669(int io, int key)
 {
-       int cr1, cr4, cra, cr23, cr26, cr27, i = 0;
+       int cr1, cr4, cra, cr23, cr26, cr27;
+       struct superio_struct *s;
+
        static const char *const modes[] = {
                "SPP and Bidirectional (PS/2)",
                "EPP and SPP",
@@ -1272,30 +1286,29 @@ static void __devinit show_parconfig_smsc37c669(int io, int key)
           are related, however DMA can be 1 or 3, assume DMA_A=DMA1,
           DMA_C=DMA3 (this is true e.g. for TYAN 1564D Tomcat IV) */
        if (cr23 * 4 >= 0x100) { /* if active */
-               while ((i < NR_SUPERIOS) && (superios[i].io != 0))
-                       i++;
-               if (i == NR_SUPERIOS) {
+               s = find_free_superio();
+               if (s == NULL)
                        printk(KERN_INFO "Super-IO: too many chips!\n");
-               else {
+               else {
                        int d;
                        switch (cr23 * 4) {
                        case 0x3bc:
-                               superios[i].io = 0x3bc;
-                               superios[i].irq = 7;
+                               s->io = 0x3bc;
+                               s->irq = 7;
                                break;
                        case 0x378:
-                               superios[i].io = 0x378;
-                               superios[i].irq = 7;
+                               s->io = 0x378;
+                               s->irq = 7;
                                break;
                        case 0x278:
-                               superios[i].io = 0x278;
-                               superios[i].irq = 5;
+                               s->io = 0x278;
+                               s->irq = 5;
                        }
                        d = (cr26 & 0x0f);
                        if (d == 1 || d == 3)
-                               superios[i].dma = d;
+                               s->dma = d;
                        else
-                               superios[i].dma = PARPORT_DMA_NONE;
+                               s->dma = PARPORT_DMA_NONE;
                }
        }
 }
@@ -1303,7 +1316,8 @@ static void __devinit show_parconfig_smsc37c669(int io, int key)
 
 static void __devinit show_parconfig_winbond(int io, int key)
 {
-       int cr30, cr60, cr61, cr70, cr74, crf0, i = 0;
+       int cr30, cr60, cr61, cr70, cr74, crf0;
+       struct superio_struct *s;
        static const char *const modes[] = {
                "Standard (SPP) and Bidirectional(PS/2)", /* 0 */
                "EPP-1.9 and SPP",
@@ -1356,14 +1370,13 @@ static void __devinit show_parconfig_winbond(int io, int key)
        }
 
        if (cr30 & 0x01) { /* the settings can be interrogated later ... */
-               while ((i < NR_SUPERIOS) && (superios[i].io != 0))
-                       i++;
-               if (i == NR_SUPERIOS) {
+               s = find_free_superio();
+               if (s == NULL)
                        printk(KERN_INFO "Super-IO: too many chips!\n");
-               else {
-                       superios[i].io = (cr60<<8)|cr61;
-                       superios[i].irq = cr70&0x0f;
-                       superios[i].dma = (((cr74 & 0x07) > 3) ?
+               else {
+                       s->io = (cr60 << 8) | cr61;
+                       s->irq = cr70 & 0x0f;
+                       s->dma = (((cr74 & 0x07) > 3) ?
                                           PARPORT_DMA_NONE : (cr74 & 0x07));
                }
        }
@@ -1458,11 +1471,13 @@ static void __devinit decode_smsc(int efer, int key, int devid, int devrev)
 
 static void __devinit winbond_check(int io, int key)
 {
-       int devid, devrev, oldid, x_devid, x_devrev, x_oldid;
+       int origval, devid, devrev, oldid, x_devid, x_devrev, x_oldid;
 
        if (!request_region(io, 3, __func__))
                return;
 
+       origval = inb(io); /* Save original value */
+
        /* First probe without key */
        outb(0x20, io);
        x_devid = inb(io + 1);
@@ -1482,6 +1497,8 @@ static void __devinit winbond_check(int io, int key)
        oldid = inb(io + 1);
        outb(0xaa, io);    /* Magic Seal */
 
+       outb(origval, io); /* in case we poked some entirely different hardware */
+
        if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
                goto out; /* protection against false positives */
 
@@ -1492,11 +1509,15 @@ out:
 
 static void __devinit winbond_check2(int io, int key)
 {
-       int devid, devrev, oldid, x_devid, x_devrev, x_oldid;
+       int origval[3], devid, devrev, oldid, x_devid, x_devrev, x_oldid;
 
        if (!request_region(io, 3, __func__))
                return;
 
+       origval[0] = inb(io); /* Save original values */
+       origval[1] = inb(io + 1);
+       origval[2] = inb(io + 2);
+
        /* First probe without the key */
        outb(0x20, io + 2);
        x_devid = inb(io + 2);
@@ -1515,6 +1536,10 @@ static void __devinit winbond_check2(int io, int key)
        oldid = inb(io + 2);
        outb(0xaa, io);    /* Magic Seal */
 
+       outb(origval[0], io); /* in case we poked some entirely different hardware */
+       outb(origval[1], io + 1);
+       outb(origval[2], io + 2);
+
        if (x_devid == devid && x_devrev == devrev && x_oldid == oldid)
                goto out; /* protection against false positives */
 
@@ -1525,11 +1550,13 @@ out:
 
 static void __devinit smsc_check(int io, int key)
 {
-       int id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;
+       int origval, id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;
 
        if (!request_region(io, 3, __func__))
                return;
 
+       origval = inb(io); /* Save original value */
+
        /* First probe without the key */
        outb(0x0d, io);
        x_oldid = inb(io + 1);
@@ -1553,6 +1580,8 @@ static void __devinit smsc_check(int io, int key)
        rev = inb(io + 1);
        outb(0xaa, io);    /* Magic Seal */
 
+       outb(origval, io); /* in case we poked some entirely different hardware */
+
        if (x_id == id && x_oldrev == oldrev &&
            x_oldid == oldid && x_rev == rev)
                goto out; /* protection against false positives */
@@ -1589,11 +1618,12 @@ static void __devinit detect_and_report_smsc(void)
 static void __devinit detect_and_report_it87(void)
 {
        u16 dev;
-       u8 r;
+       u8 origval, r;
        if (verbose_probing)
                printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
-       if (!request_region(0x2e, 1, __func__))
+       if (!request_region(0x2e, 2, __func__))
                return;
+       origval = inb(0x2e);            /* Save original value */
        outb(0x87, 0x2e);
        outb(0x01, 0x2e);
        outb(0x55, 0x2e);
@@ -1613,30 +1643,35 @@ static void __devinit detect_and_report_it87(void)
                outb(r | 8, 0x2F);
                outb(0x02, 0x2E);       /* Lock */
                outb(0x02, 0x2F);
+       } else {
+               outb(origval, 0x2e);    /* Oops, sorry to disturb */
        }
-       release_region(0x2e, 1);
+       release_region(0x2e, 2);
 }
 #endif /* CONFIG_PARPORT_PC_SUPERIO */
 
-static int get_superio_dma(struct parport *p)
+static struct superio_struct *find_superio(struct parport *p)
 {
-       int i = 0;
+       int i;
+       for (i = 0; i < NR_SUPERIOS; i++)
+               if (superios[i].io != p->base)
+                       return &superios[i];
+       return NULL;
+}
 
-       while ((i < NR_SUPERIOS) && (superios[i].io != p->base))
-               i++;
-       if (i != NR_SUPERIOS)
-               return superios[i].dma;
+static int get_superio_dma(struct parport *p)
+{
+       struct superio_struct *s = find_superio(p);
+       if (s)
+               return s->dma;
        return PARPORT_DMA_NONE;
 }
 
 static int get_superio_irq(struct parport *p)
 {
-       int i = 0;
-
-       while ((i < NR_SUPERIOS) && (superios[i].io != p->base))
-               i++;
-       if (i != NR_SUPERIOS)
-               return superios[i].irq;
+       struct superio_struct *s = find_superio(p);
+       if (s)
+               return s->irq;
        return PARPORT_IRQ_NONE;
 }
 
@@ -2255,6 +2290,9 @@ struct parport *parport_pc_probe_port(unsigned long int base,
                if (IS_ERR(pdev))
                        return NULL;
                dev = &pdev->dev;
+
+               dev->coherent_dma_mask = DMA_BIT_MASK(24);
+               dev->dma_mask = &dev->coherent_dma_mask;
        }
 
        ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
@@ -2869,6 +2907,7 @@ enum parport_pc_pci_cards {
        netmos_9755,
        netmos_9805,
        netmos_9815,
+       netmos_9901,
        quatech_sppxp100,
 };
 
@@ -2949,7 +2988,7 @@ static struct parport_pc_pci {
        /* netmos_9755 */               { 2, { { 0, 1 }, { 2, 3 },} },
        /* netmos_9805 */               { 1, { { 0, -1 }, } },
        /* netmos_9815 */               { 2, { { 0, -1 }, { 2, -1 }, } },
-
+       /* netmos_9901 */               { 1, { { 0, -1 }, } },
        /* quatech_sppxp100 */          { 1, { { 0, 1 }, } },
 };
 
@@ -3051,6 +3090,8 @@ static const struct pci_device_id parport_pc_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 },
        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
+         0xA000, 0x2000, 0, 0, netmos_9901 },
        /* Quatech SPPXP-100 Parallel port PCI ExpressCard */
        { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 },