fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / isdn / act2000 / act2000_isa.c
index e84aa5f..09ea50d 100644 (file)
 #include "act2000_isa.h"
 #include "capi.h"
 
-static act2000_card *irq2card_map[16];
-
-static void
-act2000_isa_delay(long t)
-{
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(t);
-}
-
 /*
  * Reset Controller, then try to read the Card's signature.
  + Return:
@@ -70,16 +61,11 @@ act2000_isa_detect(unsigned short portbase)
 }
 
 static irqreturn_t
-act2000_isa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+act2000_isa_interrupt(int irq, void *dev_id)
 {
-        act2000_card *card = irq2card_map[irq];
+        act2000_card *card = dev_id;
         u_char istatus;
 
-        if (!card) {
-                printk(KERN_WARNING
-                       "act2000: Spurious interrupt!\n");
-                return IRQ_NONE;
-        }
         istatus = (inb(ISA_PORT_ISR) & 0x07);
         if (istatus & ISA_ISR_OUT) {
                 /* RX fifo has data */
@@ -146,17 +132,15 @@ int
 act2000_isa_config_irq(act2000_card * card, short irq)
 {
         if (card->flags & ACT2000_FLAGS_IVALID) {
-                free_irq(card->irq, NULL);
-                irq2card_map[card->irq] = NULL;
+                free_irq(card->irq, card);
         }
         card->flags &= ~ACT2000_FLAGS_IVALID;
         outb(ISA_COR_IRQOFF, ISA_PORT_COR);
         if (!irq)
                 return 0;
 
-       if (!request_irq(irq, &act2000_isa_interrupt, 0, card->regname, NULL)) {
+       if (!request_irq(irq, &act2000_isa_interrupt, 0, card->regname, card)) {
                card->irq = irq;
-               irq2card_map[card->irq] = card;
                card->flags |= ACT2000_FLAGS_IVALID;
                 printk(KERN_WARNING
                        "act2000: Could not request irq %d\n",irq);
@@ -195,10 +179,9 @@ act2000_isa_release(act2000_card * card)
         unsigned long flags;
 
         spin_lock_irqsave(&card->lock, flags);
-        if (card->flags & ACT2000_FLAGS_IVALID) {
-                free_irq(card->irq, NULL);
-                irq2card_map[card->irq] = NULL;
-        }
+        if (card->flags & ACT2000_FLAGS_IVALID)
+                free_irq(card->irq, card);
+
         card->flags &= ~ACT2000_FLAGS_IVALID;
         if (card->flags & ACT2000_FLAGS_PVALID)
                 release_region(card->port, ISA_REGION);
@@ -408,7 +391,6 @@ int
 act2000_isa_download(act2000_card * card, act2000_ddef __user * cb)
 {
         unsigned int length;
-        int ret;
         int l;
         int c;
         long timeout;
@@ -419,14 +401,14 @@ act2000_isa_download(act2000_card * card, act2000_ddef __user * cb)
 
         if (!act2000_isa_reset(card->port))
                 return -ENXIO;
-        act2000_isa_delay(HZ / 2);
-        if(copy_from_user(&cblock, cb, sizeof(cblock)))
+        msleep_interruptible(500);
+        if (copy_from_user(&cblock, cb, sizeof(cblock)))
                return -EFAULT;
         length = cblock.length;
         p = cblock.buffer;
-        if ((ret = verify_area(VERIFY_READ, p, length)))
-                return ret;
-        buf = (u_char *) kmalloc(1024, GFP_KERNEL);
+        if (!access_ok(VERIFY_READ, p, length))
+                return -EFAULT;
+        buf = kmalloc(1024, GFP_KERNEL);
         if (!buf)
                 return -ENOMEM;
         timeout = 0;
@@ -434,7 +416,10 @@ act2000_isa_download(act2000_card * card, act2000_ddef __user * cb)
                 l = (length > 1024) ? 1024 : length;
                 c = 0;
                 b = buf;
-                copy_from_user(buf, p, l);
+                if (copy_from_user(buf, p, l)) {
+                        kfree(buf);
+                        return -EFAULT;
+                }
                 while (c < l) {
                         if (act2000_isa_writeb(card, *b++)) {
                                 printk(KERN_WARNING
@@ -449,6 +434,6 @@ act2000_isa_download(act2000_card * card, act2000_ddef __user * cb)
                 p += l;
         }
         kfree(buf);
-        act2000_isa_delay(HZ / 2);
+        msleep_interruptible(500);
         return (act2000_isa_getid(card));
 }