vserver 1.9.3
[linux-2.6.git] / drivers / parport / parport_pc.c
index 831d678..5b550ab 100644 (file)
@@ -1194,7 +1194,7 @@ struct parport_operations parport_pc_ops =
 
 #ifdef CONFIG_PARPORT_PC_SUPERIO
 /* Super-IO chipset detection, Winbond, SMSC */
-static void __devinit show_parconfig_smsc37c669(int io, int key)
+static int __devinit show_parconfig_smsc37c669(int io, int key)
 {
        int cr1,cr4,cra,cr23,cr26,cr27,i=0;
        static const char *modes[]={ "SPP and Bidirectional (PS/2)",    
@@ -1261,17 +1261,26 @@ static void __devinit show_parconfig_smsc37c669(int io, int key)
                                        superios[i].io = 0x278;
                                        superios[i].irq = 5;
                        }
+                       if (io != superios[i].io) {
+                               /* how many bytes? */
+                               if (!request_region(superios[i].io, 3, "smsc parport")) {
+                                       superios[i].io = 0;
+                                       return 0;
+                               }
+                       }
                        d=(cr26 &0x0f);
                        if((d==1) || (d==3)) 
                                superios[i].dma= d;
                        else
                                superios[i].dma= PARPORT_DMA_NONE;
+                       return 1;
                }
        }
+       return 0;
 }
 
 
-static void __devinit show_parconfig_winbond(int io, int key)
+static int __devinit show_parconfig_winbond(int io, int key)
 {
        int cr30,cr60,cr61,cr70,cr74,crf0,i=0;
        static const char *modes[] = {
@@ -1327,14 +1336,23 @@ static void __devinit show_parconfig_winbond(int io, int key)
                        printk(KERN_INFO "Super-IO: too many chips!\n");
                else {
                        superios[i].io = (cr60<<8)|cr61;
+                       if (io != superios[i].io) {
+                               /* how many bytes? */
+                               if (!request_region(superios[i].io, 3, "winbond parport")) {
+                                       superios[i].io = 0;
+                                       return 0;
+                               }
+                       }
                        superios[i].irq = cr70&0x0f;
                        superios[i].dma = (((cr74 & 0x07) > 3) ?
                                           PARPORT_DMA_NONE : (cr74 & 0x07));
+                       return 1;
                }
        }
+       return 0;
 }
 
-static void __devinit decode_winbond(int efer, int key, int devid, int devrev, int oldid)
+static int __devinit decode_winbond(int efer, int key, int devid, int devrev, int oldid)
 {
        const char *type = "unknown";
        int id,progif=2;
@@ -1342,7 +1360,7 @@ static void __devinit decode_winbond(int efer, int key, int devid, int devrev, i
        if (devid == devrev)
                /* simple heuristics, we happened to read some
                    non-winbond register */
-               return;
+               return 0;
 
        id=(devid<<8) | devrev;
 
@@ -1367,19 +1385,20 @@ static void __devinit decode_winbond(int efer, int key, int devid, int devrev, i
                       efer, key, devid, devrev, oldid, type);
 
        if (progif == 2)
-               show_parconfig_winbond(efer,key);
+               return show_parconfig_winbond(efer,key);
+       return 0;
 }
 
-static void __devinit decode_smsc(int efer, int key, int devid, int devrev)
+static int __devinit decode_smsc(int efer, int key, int devid, int devrev)
 {
         const char *type = "unknown";
-       void (*func)(int io, int key);
+       int (*func)(int io, int key);
         int id;
 
         if (devid == devrev)
                /* simple heuristics, we happened to read some
                    non-smsc register */
-               return;
+               return 0;
 
        func=NULL;
         id=(devid<<8) | devrev;
@@ -1395,7 +1414,8 @@ static void __devinit decode_smsc(int efer, int key, int devid, int devrev)
                       efer, key, devid, devrev, type);
 
        if (func)
-               func(efer,key);
+               return func(efer,key);
+       return 0;
 }
 
 
@@ -1403,6 +1423,9 @@ static void __devinit winbond_check(int io, int key)
 {
        int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
 
+       if (!request_region(io, 3, __FUNCTION__))
+               return;
+
        /* First probe without key */
        outb(0x20,io);
        x_devid=inb(io+1);
@@ -1423,15 +1446,21 @@ static void __devinit winbond_check(int io, int key)
        outb(0xaa,io);    /* Magic Seal */
 
        if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
-               return; /* protection against false positives */
+               goto out; /* protection against false positives */
 
-       decode_winbond(io,key,devid,devrev,oldid);
+       if (decode_winbond(io,key,devid,devrev,oldid));
+               return;
+out:
+       release_region(io, 3);
 }
 
 static void __devinit winbond_check2(int io,int key)
 {
         int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
 
+       if (!request_region(io, 3, __FUNCTION__))
+               return;
+
        /* First probe without the key */
        outb(0x20,io+2);
        x_devid=inb(io+2);
@@ -1451,15 +1480,21 @@ static void __devinit winbond_check2(int io,int key)
         outb(0xaa,io);    /* Magic Seal */
 
        if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
-               return; /* protection against false positives */
+               goto out; /* protection against false positives */
 
-        decode_winbond(io,key,devid,devrev,oldid);
+        if (decode_winbond(io,key,devid,devrev,oldid))
+               return;
+out:
+       release_region(io, 3);
 }
 
 static void __devinit smsc_check(int io, int key)
 {
         int id,rev,oldid,oldrev,x_id,x_rev,x_oldid,x_oldrev;
 
+       if (!request_region(io, 3, __FUNCTION__))
+               return;
+
        /* First probe without the key */
        outb(0x0d,io);
        x_oldid=inb(io+1);
@@ -1485,9 +1520,12 @@ static void __devinit smsc_check(int io, int key)
 
        if ((x_id == id) && (x_oldrev == oldrev) &&
            (x_oldid == oldid) && (x_rev == rev))
-               return; /* protection against false positives */
+               goto out; /* protection against false positives */
 
-        decode_smsc(io,key,oldid,oldrev);
+        if (decode_smsc(io,key,oldid,oldrev))
+               return;
+out:
+       release_region(io, 3);
 }
 
 
@@ -2147,7 +2185,7 @@ struct parport *parport_pc_probe_port (unsigned long int base,
        priv->ctr_writable = ~0x10;
        priv->ecr = 0;
        priv->fifo_depth = 0;
-       priv->dma_buf = 0;
+       priv->dma_buf = NULL;
        priv->dma_handle = 0;
        priv->dev = dev;
        INIT_LIST_HEAD(&priv->list);
@@ -2632,6 +2670,14 @@ enum parport_pc_pci_cards {
        oxsemi_840,
        aks_0100,
        mobility_pp,
+       netmos_9705,
+       netmos_9805,
+       netmos_9815,
+       netmos_9855,
+       netmos_9735,
+       netmos_9835,
+       netmos_9755,
+       netmos_9715
 };
 
 
@@ -2699,8 +2745,16 @@ static struct parport_pc_pci {
         * and 840 locks up if you write 1 to bit 2! */
        /* oxsemi_954 */                { 1, { { 0, -1 }, } },
        /* oxsemi_840 */                { 1, { { 0, -1 }, } },
-       /* aks_0100 */                  { 1, { { 0, 1 }, } },
+       /* aks_0100 */                  { 1, { { 0, -1 }, } },
        /* mobility_pp */               { 1, { { 0, 1 }, } },
+       /* netmos_9705 */               { 1, { { 0, -1 }, } }, /* untested */
+       /* netmos_9805 */               { 1, { { 0, -1 }, } }, /* untested */
+       /* netmos_9815 */               { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
+       /* netmos_9855 */               { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
+       /* netmos_9735 */               { 1, { { 2, 3 }, } },  /* untested */
+       /* netmos_9835 */               { 1, { { 2, 3 }, } },  /* untested */
+        /* netmos_9755 */               { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
+        /* netmos_9715 */               { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
 };
 
 static struct pci_device_id parport_pc_pci_tbl[] = {
@@ -2769,6 +2823,23 @@ static struct pci_device_id parport_pc_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_840 },
        { PCI_VENDOR_ID_AKS, PCI_DEVICE_ID_AKS_ALADDINCARD,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 },
+       /* NetMos communication controllers */
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9705,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9705 },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9805,
+         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_9855,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9735 },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9835 },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9755,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9755 },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9715,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9715 },
        { 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);