patch-2.0.1 linux/drivers/isdn/icn/icn.c

Next file: linux/drivers/isdn/icn/icn.h
Previous file: linux/drivers/char/tty_io.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.0/linux/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
@@ -1,4 +1,4 @@
-/* $Id: icn.c,v 1.24 1996/06/06 13:58:33 fritz Exp $
+/* $Id: icn.c,v 1.28 1996/06/28 17:02:53 fritz Exp $
  *
  * ISDN low-level module for the ICN active ISDN-Card.
  *
@@ -19,6 +19,23 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: icn.c,v $
+ * Revision 1.28  1996/06/28 17:02:53  fritz
+ * replaced memcpy_fromfs_toio.
+ *
+ * Revision 1.27  1996/06/25 18:38:59  fritz
+ * Fixed function name in error message.
+ *
+ * Revision 1.26  1996/06/24 17:20:35  fritz
+ * Bugfixes in pollbchan_send():
+ *   - Using lock field of skbuff breaks networking.
+ *   - Added channel locking
+ *   - changed dequeuing scheme.
+ * Eliminated misc. compiler warnings.
+ *
+ * Revision 1.25  1996/06/11 22:53:35  tsbogend
+ * fixed problem with large array on stack
+ * made the driver working on Linux/alpha
+ *
  * Revision 1.24  1996/06/06 13:58:33  fritz
  * Changed code to be architecture independent
  *
@@ -119,7 +136,7 @@
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.24 $";
+*revision = "$Revision: 1.28 $";
 
 static int icn_addcard(int, char *, char *);
 
@@ -135,10 +152,8 @@
         
         save_flags(flags);
         cli();
-        while ((skb = skb_dequeue(queue))) {
-                skb->free = 1;
-                kfree_skb(skb, FREE_WRITE);
-        }
+        while ((skb = skb_dequeue(queue)))
+                dev_kfree_skb(skb, FREE_WRITE);
         restore_flags(flags);
 }
 
@@ -312,7 +327,7 @@
 
         if (icn_trymaplock_channel(card,mch)) {
                 while (rbavl) {
-                        cnt = rbuf_l;
+                        cnt = readb(&rbuf_l);
                         if ((card->rcvidx[channel] + cnt) > 4000) {
                                 printk(KERN_WARNING 
                                        "icn: (%s) bogus packet on ch%d, dropping.\n",
@@ -322,9 +337,9 @@
                                 eflag = 0;
                         } else {
                                 memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
-                                              rbuf_d, cnt);
+                                              &rbuf_d, cnt);
                                 card->rcvidx[channel] += cnt;
-                                eflag = rbuf_f;
+                                eflag = readb(&rbuf_f);
                         }
                         rbnext;
                         icn_maprelease_channel(card, mch & 2);
@@ -367,36 +382,37 @@
                 while (sbfree && card->sndcount[channel]) {
                         save_flags(flags);
                         cli();
-                        skb = skb_peek(&card->spqueue[channel]);
-                        if (!skb) {
-                                restore_flags(flags);
-                                break;
-                        }
-                        if (skb->lock) {
+                        if (card->xmit_lock[channel]) {
                                 restore_flags(flags);
                                 break;
                         }
-                        skb->lock = 1;
+                        card->xmit_lock[channel]++;
                         restore_flags(flags);
-                        cnt =
-                            (sbuf_l =
-                             (skb->len > ICN_FRAGSIZE) ? ((sbuf_f = 0xff), ICN_FRAGSIZE) : ((sbuf_f = 0), skb->len));
-                        memcpy(sbuf_d, skb->data, cnt);
+                        skb = skb_dequeue(&card->spqueue[channel]);
+                        if (!skb)
+                                break;
+		        if (skb->len > ICN_FRAGSIZE) {
+			    writeb (0xff, &sbuf_f);
+			    cnt = ICN_FRAGSIZE;
+			} else {
+			    writeb (0x0, &sbuf_f);
+			    cnt = skb->len;
+			}
+		        writeb (cnt, &sbuf_l);		    
+                        memcpy_toio(&sbuf_d, skb->data, cnt);
                         skb_pull(skb, cnt);
                         card->sndcount[channel] -= cnt;
                         sbnext;        /* switch to next buffer        */
                         icn_maprelease_channel(card, mch & 2);
                         if (!skb->len) {
-                                skb = skb_dequeue(&card->spqueue[channel]);
-                                skb->free = 1;
-                                skb->lock = 0;
-                                kfree_skb(skb, FREE_WRITE);
+                                dev_kfree_skb(skb, FREE_WRITE);
                                 cmd.command = ISDN_STAT_BSENT;
                                 cmd.driver = card->myid;
                                 cmd.arg = channel;
                                 card->interface.statcallb(&cmd);
                         } else
-                                skb->lock = 0;
+                                skb_queue_head(&card->spqueue[channel], skb);
+                        card->xmit_lock[channel] = 0;
                         if (!icn_trymaplock_channel(card, mch))
                                 break;
                 }
@@ -426,6 +442,7 @@
                         /* schedule b-channel polling again */
                         save_flags(flags);
                         cli();
+                        del_timer(&card->rb_timer);
                         card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
                         add_timer(&card->rb_timer);
                         card->flags |= ICN_FLAGS_RBTIMER;
@@ -649,6 +666,7 @@
         /* schedule again */
         save_flags(flags);
         cli();
+        del_timer(&card->st_timer);
         card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
         add_timer(&card->st_timer);
         restore_flags(flags);
@@ -671,8 +689,8 @@
         unsigned long flags;
 
         if (len > 4000) {
-                skb->free = 1;
-                kfree_skb(skb, FREE_WRITE);
+                printk(KERN_WARNING
+                       "icn: Send packet too large\n");
                 return -EINVAL;
         }
         if (len) {
@@ -685,7 +703,6 @@
                 card->sndcount[channel] += len;
                 skb_queue_tail(&card->spqueue[channel], skb);
                 restore_flags(flags);
-                icn_pollbchan_send(channel, card);
         }
         return len;
 }
@@ -751,13 +768,17 @@
 {
         int ret;
         ulong flags;
-        unsigned char codebuf[ICN_CODE_STAGE1];
+	u_char *codebuf;
 
 #ifdef BOOT_DEBUG
         printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
 #endif
         if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE1)))
                 return ret;
+        if (!(codebuf = kmalloc(ICN_CODE_STAGE1,GFP_KERNEL))) {
+                printk(KERN_WARNING "icn: Could not allocate code buffer\n");
+                return -ENOMEM;
+        }
         save_flags(flags);
         cli();
         if (!card->rvalid) {
@@ -768,6 +789,7 @@
                                card->port,
                                card->port + ICN_PORTLEN);
                         restore_flags(flags);
+                        kfree(codebuf);
                         return -EBUSY;
                 }
                 request_region(card->port, ICN_PORTLEN, card->regname);
@@ -804,8 +826,8 @@
         icn_lock_channel(card,0);                                  /* Lock Bank 0      */
         restore_flags(flags);
         SLEEP(1);
-        memcpy_fromfs(codebuf, buffer, ICN_CODE_STAGE1);           /* Copy code        */
-        memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);
+        memcpy_fromfs(codebuf, buffer, ICN_CODE_STAGE1);
+        memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);           /* Copy code        */
 #ifdef BOOT_DEBUG
         printk(KERN_DEBUG "Bootloader transfered\n");
 #endif
@@ -821,12 +843,12 @@
                 icn_lock_channel(card,2);                          /* Lock Bank 8     */
                 restore_flags(flags);
                 SLEEP(1);
-                memcpy_fromfs(codebuf, buffer, ICN_CODE_STAGE1);   /* Copy code        */
-                memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);
+                memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);           /* Copy code        */
 #ifdef BOOT_DEBUG
                 printk(KERN_DEBUG "Bootloader transfered\n");
 #endif
         }
+        kfree(codebuf);
         SLEEP(1);
         OUTB_P(0xff, ICN_RUN);                                     /* Start Boot-Code */
         if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1)))
@@ -849,6 +871,7 @@
 static int icn_loadproto(u_char * buffer, icn_card * card)
 {
         register u_char *p = buffer;
+        u_char codebuf[256];
         uint left = ICN_CODE_STAGE2;
         uint cnt;
         int timer;
@@ -874,7 +897,8 @@
         while (left) {
                 if (sbfree) {                           /* If there is a free buffer...  */
                         cnt = MIN(256, left);
-                        memcpy_fromfs(&sbuf_l, p, cnt); /* copy data                     */
+                        memcpy_fromfs(codebuf, p, cnt);
+                        memcpy_toio(&sbuf_l, codebuf, cnt); /* copy data                     */ 
                         sbnext;                         /* switch to next buffer         */
                         p += cnt;
                         left -= cnt;
@@ -892,7 +916,7 @@
                         schedule();
                 }
         }
-        sbuf_n = 0x20;
+        writeb (0x20, &sbuf_n);
         timer = 0;
         while (1) {
                 if (readb(&cmd_o) || readb(&cmd_i)) {
@@ -1094,7 +1118,7 @@
                                 }
                                 break;
                         case ICN_IOCTL_GETMMIO:
-                                return (int) dev.shmem;
+                                return (long) dev.shmem;
                         case ICN_IOCTL_SETPORT:
                                 if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
                                     || a == 0x340 || a == 0x350 || a == 0x360 ||
@@ -1391,7 +1415,8 @@
         if (card)
                 return (icn_command(c, card));
         printk(KERN_ERR
-               "icn: if_command called with invalid driverId!\n");
+               "icn: if_command %d called with invalid driverId %d!\n",
+		c->command, c->driver);
         return -ENODEV;
 }
 
@@ -1433,7 +1458,7 @@
                 return (icn_sendbuf(channel, skb, card));
         }
         printk(KERN_ERR
-               "icn: if_readstatus called with invalid driverId!\n");
+               "icn: if_sendbuf called with invalid driverId!\n");
         return -ENODEV;
 }
 
@@ -1455,9 +1480,6 @@
         card->interface.channels = ICN_BCH;
         card->interface.maxbufsize = 4000;
         card->interface.command = if_command;
-	/*
-        card->interface.writebuf = if_sendbuf;
-	*/
 	card->interface.writebuf_skb = if_sendbuf;
         card->interface.writecmd = if_writecmd;
         card->interface.readstat = if_readstatus;
@@ -1558,7 +1580,7 @@
         char rev[10];
 
         memset(&dev, 0, sizeof(icn_dev));
-        dev.shmem = (icn_shmem *) (membase & 0x0ffc000);
+        dev.shmem = (icn_shmem *) ((unsigned long)membase & 0x0ffc000);
         dev.channel = -1;
         dev.mcard   = NULL;
 
@@ -1571,8 +1593,8 @@
                 *p = 0;
         } else
                 strcpy(rev, " ??? ");
-        printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08x\n", rev,
-               (uint) dev.shmem);
+        printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
+               (ulong) dev.shmem);
         return (icn_addcard(portbase,icn_id,icn_id2));
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov