PATCH: port ltpc to 2.5

From: Alan Cox (alan@lxorguk.ukuu.org.uk)
Date: Mon Apr 07 2003 - 19:23:43 EST


diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.67/drivers/net/appletalk/ltpc.c linux-2.5.67-ac1/drivers/net/appletalk/ltpc.c
--- linux-2.5.67/drivers/net/appletalk/ltpc.c 2003-02-10 18:38:15.000000000 +0000
+++ linux-2.5.67-ac1/drivers/net/appletalk/ltpc.c 2003-04-04 18:31:37.000000000 +0100
@@ -213,6 +213,7 @@
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
+#include <linux/spinlock.h>
 #include <linux/in.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -235,6 +236,9 @@
 /* our stuff */
 #include "ltpc.h"
 
+static spinlock_t txqueue_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t mbox_lock = SPIN_LOCK_UNLOCKED;
+
 /* function prototypes */
 static int do_read(struct net_device *dev, void *cbuf, int cbuflen,
         void *dbuf, int dbuflen);
@@ -283,17 +287,17 @@
 {
         unsigned long flags;
         qel->next = NULL;
- save_flags(flags);
- cli();
+
+ spin_lock_irqsave(&txqueue_lock, flags);
         if (xmQtl) {
                 xmQtl->next = qel;
         } else {
                 xmQhd = qel;
         }
         xmQtl = qel;
- restore_flags(flags);
+ spin_unlock_irqrestore(&txqueue_lock, flags);
 
- if (debug&DEBUG_LOWER)
+ if (debug & DEBUG_LOWER)
                 printk("enqueued a 0x%02x command\n",qel->cbuf[0]);
 }
 
@@ -302,18 +306,18 @@
         unsigned long flags;
         int i;
         struct xmitQel *qel=NULL;
- save_flags(flags);
- cli();
+
+ spin_lock_irqsave(&txqueue_lock, flags);
         if (xmQhd) {
                 qel = xmQhd;
                 xmQhd = qel->next;
                 if(!xmQhd) xmQtl = NULL;
         }
- restore_flags(flags);
+ spin_unlock_irqrestore(&txqueue_lock, flags);
 
- if ((debug&DEBUG_LOWER) && qel) {
+ if ((debug & DEBUG_LOWER) && qel) {
                 int n;
- printk("ltpc: dequeued command ");
+ printk(KERN_DEBUG "ltpc: dequeued command ");
                 n = qel->cbuflen;
                 if (n>100) n=100;
                 for(i=0;i<n;i++) printk("%02x ",qel->cbuf[i]);
@@ -352,14 +356,13 @@
         unsigned long flags;
         int i;
 
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&mbox_lock, flags);
         for(i=1;i<16;i++) if(!mboxinuse[i]) {
                 mboxinuse[i]=1;
- restore_flags(flags);
+ spin_unlock_irqrestore(&mbox_lock, flags);
                 return i;
         }
- restore_flags(flags);
+ spin_unlock_irqrestore(&mbox_lock, flags);
         return 0;
 }
 
@@ -503,16 +506,13 @@
         int i;
         int base = dev->base_addr;
 
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&txqueue_lock, flags);
         if(QInIdle) {
- restore_flags(flags);
+ spin_unlock_irqrestore(&txqueue_lock, flags);
                 return;
         }
         QInIdle = 1;
-
-
- restore_flags(flags);
+ spin_unlock_irqrestore(&txqueue_lock, flags);
 
         /* this tri-states the IRQ line */
         (void) inb_p(base+6);
@@ -531,17 +531,17 @@
         switch(state) {
                 case 0xfc:
                         /* incoming command */
- if (debug&DEBUG_LOWER) printk("idle: fc\n");
+ if (debug & DEBUG_LOWER) printk("idle: fc\n");
                         handlefc(dev);
                         break;
                 case 0xfd:
                         /* incoming data */
- if(debug&DEBUG_LOWER) printk("idle: fd\n");
+ if(debug & DEBUG_LOWER) printk("idle: fd\n");
                         handlefd(dev);
                         break;
                 case 0xf9:
                         /* result ready */
- if (debug&DEBUG_LOWER) printk("idle: f9\n");
+ if (debug & DEBUG_LOWER) printk("idle: f9\n");
                         if(!mboxinuse[0]) {
                                 mboxinuse[0] = 1;
                                 qels[0].cbuf = rescbuf;
@@ -570,7 +570,7 @@
                         break;
                 case 0xfa:
                         /* waiting for command */
- if(debug&DEBUG_LOWER) printk("idle: fa\n");
+ if(debug & DEBUG_LOWER) printk("idle: fa\n");
                         if (xmQhd) {
                                 q=deQ();
                                 memcpy(ltdmacbuf,q->cbuf,q->cbuflen);
@@ -608,7 +608,7 @@
                         break;
                 case 0Xfb:
                         /* data transfer ready */
- if(debug&DEBUG_LOWER) printk("idle: fb\n");
+ if(debug & DEBUG_LOWER) printk("idle: fb\n");
                         if(q->QWrite) {
                                 memcpy(ltdmabuf,q->dbuf,q->dbuflen);
                                 handlewrite(dev);
@@ -826,7 +826,7 @@
         struct lt_init c;
         int ltflags;
 
- if(debug&DEBUG_VERBOSE) printk("ltpc_ioctl called\n");
+ if(debug & DEBUG_VERBOSE) printk("ltpc_ioctl called\n");
 
         switch(cmd) {
                 case SIOCSIFADDR:
@@ -872,7 +872,7 @@
 static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev,
         unsigned short type, void *daddr, void *saddr, unsigned len)
 {
- if(debug&DEBUG_VERBOSE)
+ if(debug & DEBUG_VERBOSE)
                 printk("ltpc_hard_header called for device %s\n",
                         dev->name);
         return 0;
@@ -914,7 +914,7 @@
 
         del_timer(&ltpc_timer);
 
- if(debug&DEBUG_VERBOSE) {
+ if(debug & DEBUG_VERBOSE) {
                 if (!ltpc_poll_counter) {
                         ltpc_poll_counter = 50;
                         printk("ltpc poll is alive\n");
@@ -951,7 +951,7 @@
         cbuf.length = skb->len; /* this is host order */
         skb->h.raw=skb->data;
 
- if(debug&DEBUG_UPPER) {
+ if(debug & DEBUG_UPPER) {
                 printk("command ");
                 for(i=0;i<6;i++)
                         printk("%02x ",((unsigned char *)&cbuf)[i]);
@@ -960,7 +960,7 @@
 
         do_write(dev,&cbuf,sizeof(cbuf),skb->h.raw,skb->len);
 
- if(debug&DEBUG_UPPER) {
+ if(debug & DEBUG_UPPER) {
                 printk("sent %d ddp bytes\n",skb->len);
                 for(i=0;i<skb->len;i++) printk("%02x ",skb->h.raw[i]);
                 printk("\n");
@@ -984,7 +984,7 @@
 static int __init ltpc_probe_dma(int base)
 {
         int dma = 0;
- int timeout;
+ unsigned long timeout;
           unsigned long f;
   
           if (!request_dma(1,"ltpc")) {
@@ -1055,16 +1055,13 @@
 {
         int err;
         int x=0,y=0;
- int timeout;
         int autoirq;
- unsigned long flags;
         unsigned long f;
         int portfound=0;
+ unsigned long timeout;
 
         SET_MODULE_OWNER(dev);
 
- save_flags(flags);
-
         /* probe for the I/O port address */
         if (io != 0x240 && request_region(0x220,8,"ltpc")) {
                 x = inb_p(0x220+6);
@@ -1093,15 +1090,13 @@
         }
         if(!portfound) {
                 /* give up in despair */
- printk ("LocalTalk card not found; 220 = %02x, 240 = %02x.\n",
- x,y);
- restore_flags(flags);
+ printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y);
                 return -1;
         }
 
         /* probe for the IRQ line */
         if (irq < 2) {
- unsigned long irq_mask, delay;
+ unsigned long irq_mask;
 
                 irq_mask = probe_irq_on();
                 /* reset the interrupt line */
@@ -1109,14 +1104,11 @@
                 inb_p(io+7);
                 /* trigger an interrupt (I hope) */
                 inb_p(io+6);
-
- delay = jiffies + HZ/50;
- while (time_before(jiffies, delay)) ;
+ mdelay(2);
                 autoirq = probe_irq_off(irq_mask);
 
                 if (autoirq == 0) {
- printk("ltpc: probe at %#x failed to detect IRQ line.\n",
- io);
+ printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io);
                 }
                 else {
                         irq = autoirq;
@@ -1129,12 +1121,11 @@
         if (ltdmabuf) ltdmacbuf = &ltdmabuf[800];
 
         if (!ltdmabuf) {
- printk("ltpc: mem alloc failed\n");
- restore_flags(flags);
- return(-1);
+ printk(KERN_ERR "ltpc: mem alloc failed\n");
+ return -1;
         }
 
- if(debug&DEBUG_VERBOSE) {
+ if(debug & DEBUG_VERBOSE) {
                 printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf);
         }
 
@@ -1142,8 +1133,10 @@
 
         inb_p(io+1);
         inb_p(io+3);
- timeout = jiffies+2*HZ/100;
- while(time_before(jiffies, timeout)) ; /* hold it in reset for a coupla jiffies */
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(2*HZ/100);
+
         inb_p(io+0);
         inb_p(io+2);
         inb_p(io+7); /* clear reset */
@@ -1152,12 +1145,9 @@
         inb_p(io+5); /* enable dma */
         inb_p(io+6); /* tri-state interrupt line */
 
- timeout = jiffies+100*HZ/100;
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ);
         
- while(time_before(jiffies, timeout)) {
- /* wait for the card to complete initialization */
- }
-
         /* now, figure out which dma channel we're using, unless it's
            already been specified */
         /* well, 0 is a legal DMA channel, but the LTPC card doesn't
@@ -1165,8 +1155,7 @@
         if (dma == 0) {
                 dma = ltpc_probe_dma(io);
                 if (!dma) { /* no dma channel */
- printk("No DMA channel found on ltpc card.\n");
- restore_flags(flags);
+ printk(KERN_ERR "No DMA channel found on ltpc card.\n");
                         return -1;
                 }
         }
@@ -1174,9 +1163,9 @@
         /* print out friendly message */
 
         if(irq)
- printk("Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma);
+ printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma);
         else
- printk("Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma);
+ printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma);
 
         /* seems more logical to do this *after* probing the card... */
         err = ltpc_init(dev);
@@ -1202,20 +1191,25 @@
         (void) inb_p(io+3);
         (void) inb_p(io+2);
         timeout = jiffies+100*HZ/100;
+
         while(time_before(jiffies, timeout)) {
- if( 0xf9 == inb_p(io+6)) break;
+ if( 0xf9 == inb_p(io+6))
+ break;
+ schedule();
         }
 
- if(debug&DEBUG_VERBOSE) {
+ if(debug & DEBUG_VERBOSE) {
                 printk("setting up timer and irq\n");
         }
 
- if (irq) {
- /* grab it and don't let go :-) */
- (void) request_irq( irq, &ltpc_interrupt, 0, "ltpc", dev);
+ /* grab it and don't let go :-) */
+ if (irq && request_irq( irq, &ltpc_interrupt, 0, "ltpc", dev) >= 0)
+ {
                 (void) inb_p(io+7); /* enable interrupts from board */
                 (void) inb_p(io+7); /* and reset irq line */
         } else {
+ if( irq )
+ printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n");
                 /* polled mode -- 20 times per second */
                 /* this is really, really slow... should it poll more often? */
                 init_timer(&ltpc_timer);
@@ -1224,7 +1218,6 @@
 
                 ltpc_timer.expires = jiffies + 5;
                 add_timer(&ltpc_timer);
- restore_flags(flags);
         }
 
         return 0;
@@ -1294,7 +1287,7 @@
                 printk(KERN_DEBUG "could not register Localtalk-PC device\n");
                 return result;
         } else {
- if(debug&DEBUG_VERBOSE) printk("0 from register_netdev\n");
+ if(debug & DEBUG_VERBOSE) printk("0 from register_netdev\n");
                 return 0;
         }
 }
@@ -1306,7 +1299,7 @@
 
         ltpc_timer.data = 0; /* signal the poll routine that we're done */
 
- if(debug&DEBUG_VERBOSE) printk("freeing irq\n");
+ if(debug & DEBUG_VERBOSE) printk("freeing irq\n");
 
         if(dev_ltpc.irq) {
                 free_irq(dev_ltpc.irq,&dev_ltpc);
@@ -1316,7 +1309,7 @@
         if(del_timer(&ltpc_timer))
         {
                 /* either the poll was never started, or a poll is in process */
- if(debug&DEBUG_VERBOSE) printk("waiting\n");
+ if(debug & DEBUG_VERBOSE) printk("waiting\n");
                 /* if it's in process, wait a bit for it to finish */
                 timeout = jiffies+HZ;
                 add_timer(&ltpc_timer);
@@ -1327,31 +1320,31 @@
                 }
         }
 
- if(debug&DEBUG_VERBOSE) printk("freeing dma\n");
+ if(debug & DEBUG_VERBOSE) printk("freeing dma\n");
 
         if(dev_ltpc.dma) {
                 free_dma(dev_ltpc.dma);
                 dev_ltpc.dma = 0;
         }
 
- if(debug&DEBUG_VERBOSE) printk("freeing ioaddr\n");
+ if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n");
 
         if(dev_ltpc.base_addr) {
                 release_region(dev_ltpc.base_addr,8);
                 dev_ltpc.base_addr = 0;
         }
 
- if(debug&DEBUG_VERBOSE) printk("free_pages\n");
+ if(debug & DEBUG_VERBOSE) printk("free_pages\n");
 
         free_pages( (unsigned long) ltdmabuf, get_order(1000));
         ltdmabuf=NULL;
         ltdmacbuf=NULL;
 
- if(debug&DEBUG_VERBOSE) printk("unregister_netdev\n");
+ if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n");
 
         unregister_netdev(&dev_ltpc);
 
- if(debug&DEBUG_VERBOSE) printk("returning from cleanup_module\n");
+ if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n");
 }
 
 module_exit(ltpc_cleanup);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Apr 07 2003 - 22:00:34 EST