diff options
Diffstat (limited to 'drivers/net/hamradio')
-rw-r--r-- | drivers/net/hamradio/6pack.c | 143 | ||||
-rw-r--r-- | drivers/net/hamradio/baycom_epp.c | 202 | ||||
-rw-r--r-- | drivers/net/hamradio/baycom_par.c | 64 | ||||
-rw-r--r-- | drivers/net/hamradio/baycom_ser_fdx.c | 29 | ||||
-rw-r--r-- | drivers/net/hamradio/baycom_ser_hdx.c | 25 | ||||
-rw-r--r-- | drivers/net/hamradio/bpqether.c | 41 | ||||
-rw-r--r-- | drivers/net/hamradio/dmascc.c | 43 | ||||
-rw-r--r-- | drivers/net/hamradio/hdlcdrv.c | 91 | ||||
-rw-r--r-- | drivers/net/hamradio/scc.c | 133 | ||||
-rw-r--r-- | drivers/net/hamradio/soundmodem/sm.c | 31 | ||||
-rw-r--r-- | drivers/net/hamradio/yam.c | 27 |
11 files changed, 350 insertions, 479 deletions
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 16dc8a976..b1871485a 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -158,24 +158,6 @@ sp_free(struct sixpack *sp) } -/* Set the "sending" flag. */ -static inline void -sp_lock(struct sixpack *sp) -{ - if (test_and_set_bit(0, (void *) &sp->dev->tbusy)) - printk(KERN_WARNING "%s: trying to lock already locked device!\n", sp->dev->name); -} - - -/* Clear the "sending" flag. */ -static inline void -sp_unlock(struct sixpack *sp) -{ - if (!test_and_clear_bit(0, (void *)&sp->dev->tbusy)) - printk(KERN_WARNING "%s: trying to unlock already unlocked device!\n", sp->dev->name); -} - - /* Send one completely decapsulated IP datagram to the IP layer. */ /* This is the routine that sends the received data to the kernel AX.25. @@ -226,7 +208,7 @@ sp_encaps(struct sixpack *sp, unsigned char *icp, int len) len = sp->mtu; printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n", sp->dev->name); sp->tx_dropped++; - sp_unlock(sp); + netif_start_queue(sp->dev); return; } @@ -235,21 +217,21 @@ sp_encaps(struct sixpack *sp, unsigned char *icp, int len) if (p[0] > 5) { printk(KERN_DEBUG "%s: invalid KISS command -- dropped\n", sp->dev->name); - sp_unlock(sp); + netif_start_queue(sp->dev); return; } if ((p[0] != 0) && (len > 2)) { printk(KERN_DEBUG "%s: KISS control packet too long -- dropped\n", sp->dev->name); - sp_unlock(sp); + netif_start_queue(sp->dev); return; } if ((p[0] == 0) && (len < 15)) { printk(KERN_DEBUG "%s: bad AX.25 packet to transmit -- dropped\n", sp->dev->name); - sp_unlock(sp); + netif_start_queue(sp->dev); sp->tx_dropped++; return; } @@ -301,17 +283,18 @@ static void sixpack_write_wakeup(struct tty_struct *tty) struct sixpack *sp = (struct sixpack *) tty->disc_data; /* First make sure we're connected. */ - if (!sp || sp->magic != SIXPACK_MAGIC || !sp->dev->start) { + if (!sp || sp->magic != SIXPACK_MAGIC || + !netif_running(sp->dev)) { return; } + if (sp->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ sp->tx_packets++; tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - sp_unlock(sp); sp->tx_enable = 0; - mark_bh(NET_BH); + netif_wake_queue(sp->dev); return; } @@ -331,18 +314,9 @@ sp_xmit(struct sk_buff *skb, struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); - if (!dev->start) - { - printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name); - return 1; - } - - if (dev->tbusy) - return 1; - /* We were not busy, so we are now... :-) */ if (skb != NULL) { - sp_lock(sp); + netif_stop_queue(dev); sp->tx_bytes+=skb->len; /*---2.1.x---*/ sp_encaps(sp, skb->data, skb->len); dev_kfree_skb(skb); @@ -458,8 +432,7 @@ sp_open(struct net_device *dev) sp->tnc_ok = 0; sp->tx_enable = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); init_timer(&sp->tx_t); init_timer(&sp->resync_t); @@ -477,9 +450,8 @@ sp_close(struct net_device *dev) return -EBUSY; } sp->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); return 0; } @@ -506,7 +478,8 @@ sixpack_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, i struct sixpack *sp = (struct sixpack *) tty->disc_data; - if (!sp || sp->magic != SIXPACK_MAGIC || !sp->dev->start || !count) + if (!sp || sp->magic != SIXPACK_MAGIC || + !netif_running(sp->dev) || !count) return; save_flags(flags); @@ -723,17 +696,13 @@ static int sp_open_dev(struct net_device *dev) /* Initialize 6pack control device -- register 6pack line discipline */ -#ifdef MODULE -static int sixpack_init_ctrl_dev(void) -#else /* !MODULE */ -int __init sixpack_init_ctrl_dev(struct net_device *dummy) -#endif /* !MODULE */ +static int __init sixpack_init_ctrl_dev(void) { int status; if (sixpack_maxdev < 4) sixpack_maxdev = 4; /* Sanity */ - printk(KERN_INFO "6pack: %s (dynamic channels, max=%d)\n", + printk(KERN_INFO "AX.25: 6pack driver, %s (dynamic channels, max=%d)\n", SIXPACK_VERSION, sixpack_maxdev); sixpack_ctrls = (sixpack_ctrl_t **) kmalloc(sizeof(void*)*sixpack_maxdev, GFP_KERNEL); @@ -766,16 +735,40 @@ int __init sixpack_init_ctrl_dev(struct net_device *dummy) printk(KERN_WARNING "6pack: can't register line discipline (err = %d)\n", status); } -#ifdef MODULE return status; -#else - /* Return "not found", so that dev_init() will unlink - * the placeholder device entry for us. - */ - return ENODEV; -#endif } +static void __exit sixpack_cleanup_driver(void) +{ + int i; + + if (sixpack_ctrls != NULL) + { + for (i = 0; i < sixpack_maxdev; i++) + { + if (sixpack_ctrls[i]) + { + /* + * VSV = if dev->start==0, then device + * unregistered while close proc. + */ + if (netif_running(sixpack_ctrls[i]->dev)) + unregister_netdev(&(sixpack_ctrls[i]->dev)); + + kfree(sixpack_ctrls[i]); + sixpack_ctrls[i] = NULL; + } + } + kfree(sixpack_ctrls); + sixpack_ctrls = NULL; + } + if ((i = tty_register_ldisc(N_6PACK, NULL))) + { + printk(KERN_WARNING "6pack: can't unregister line discipline (err = %d)\n", i); + } +} + + /* Initialize the 6pack driver. Called by DDI. */ int sixpack_init(struct net_device *dev) @@ -809,6 +802,7 @@ sixpack_init(struct net_device *dev) dev->type = ARPHRD_AX25; dev->tx_queue_len = 10; dev->rebuild_header = sp_rebuild_header; + dev->tx_timeout = NULL; memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); /* Only activated in AX.25 mode */ memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); /* "" "" "" "" */ @@ -821,45 +815,8 @@ sixpack_init(struct net_device *dev) return 0; } -#ifdef MODULE - -int -init_module(void) -{ - return sixpack_init_ctrl_dev(); -} - -void -cleanup_module(void) -{ - int i; - if (sixpack_ctrls != NULL) - { - for (i = 0; i < sixpack_maxdev; i++) - { - if (sixpack_ctrls[i]) - { - /* - * VSV = if dev->start==0, then device - * unregistered while close proc. - */ - if (sixpack_ctrls[i]->dev.start) - unregister_netdev(&(sixpack_ctrls[i]->dev)); - kfree(sixpack_ctrls[i]); - sixpack_ctrls[i] = NULL; - } - } - kfree(sixpack_ctrls); - sixpack_ctrls = NULL; - } - if ((i = tty_register_ldisc(N_6PACK, NULL))) - { - printk(KERN_WARNING "6pack: can't unregister line discipline (err = %d)\n", i); - } -} -#endif /* MODULE */ /* ----> 6pack timer interrupt handler and friends. <---- */ static void @@ -1127,3 +1084,9 @@ void decode_data(byte inbyte, struct sixpack *sp) sp->rx_count = 0; } } + + +MODULE_AUTHOR("Andreas Könsgen <ajk@ccac.rwth-aachen.de>"); +MODULE_DESCRIPTION("6pack driver for AX.25"); +module_init(sixpack_init_ctrl_dev); +module_exit(sixpack_cleanup_driver); diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index d4191258d..98d228b91 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -3,7 +3,7 @@ /* * baycom_epp.c -- baycom epp radio modem driver. * - * Copyright (C) 1998-1999 + * Copyright (C) 1998-2000 * Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify @@ -26,14 +26,15 @@ * * * History: - * 0.1 xx.xx.98 Initial version by Matthias Welwarsky (dg2fef) - * 0.2 21.04.98 Massive rework by Thomas Sailer - * Integrated FPGA EPP modem configuration routines - * 0.3 11.05.98 Took FPGA config out and moved it into a separate program - * 0.4 26.07.99 Adapted to new lowlevel parport driver interface - * 0.5 03.08.99 adapt to Linus' new __setup/__initcall - * removed some pre-2.2 kernel compatibility cruft - * 0.6 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts + * 0.1 xx.xx.1998 Initial version by Matthias Welwarsky (dg2fef) + * 0.2 21.04.1998 Massive rework by Thomas Sailer + * Integrated FPGA EPP modem configuration routines + * 0.3 11.05.1998 Took FPGA config out and moved it into a separate program + * 0.4 26.07.1999 Adapted to new lowlevel parport driver interface + * 0.5 03.08.1999 adapt to Linus' new __setup/__initcall + * removed some pre-2.2 kernel compatibility cruft + * 0.6 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts + * 0.7 12.02.2000 adapted to softnet driver interface * */ @@ -47,8 +48,10 @@ #include <linux/tqueue.h> #include <linux/fs.h> #include <linux/parport.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <linux/if_arp.h> +#include <linux/kmod.h> #include <linux/hdlcdrv.h> #include <linux/baycom.h> #include <linux/soundmodem.h> @@ -89,8 +92,8 @@ static const char paranoia_str[] = KERN_ERR /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_epp"; -static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-1999 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_epp: version 0.5 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_epp: version 0.7 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ @@ -228,8 +231,7 @@ struct baycom_state { struct net_device_stats stats; unsigned int ptt_keyed; - struct sk_buff_head send_queue; /* Packets awaiting transmission */ - + struct sk_buff *skb; /* next transmit packet */ #ifdef BAYCOM_DEBUG struct debug_vals { @@ -394,15 +396,11 @@ static int exec_eppfpga(void *b) sprintf(portarg, "%ld", bc->pdev->port->base); printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg); - for (i = 0; i < current->files->max_fds; i++ ) - if (current->files->fd[i]) - close(i); - set_fs(KERNEL_DS); /* Allow execve args to be in kernel space. */ - current->uid = current->euid = current->fsuid = 0; - if (execve(eppconfig_path, argv, envp) < 0) { + i = exec_usermodehelper(eppconfig_path, argv, envp); + if (i < 0) { printk(KERN_ERR "%s: failed to exec %s -s -p %s -m %s, errno = %d\n", - bc_drvname, eppconfig_path, portarg, modearg, errno); - return -errno; + bc_drvname, eppconfig_path, portarg, modearg, i); + return i; } return 0; } @@ -515,71 +513,63 @@ static void encode_hdlc(struct baycom_state *bc) if (bc->hdlctx.bufcnt > 0) return; - while ((skb = skb_dequeue(&bc->send_queue))) { - if (skb->data[0] != 0) { - do_kiss_params(bc, skb->data, skb->len); - dev_kfree_skb(skb); - continue; - } - pkt_len = skb->len-1; /* strip KISS byte */ - if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) { - dev_kfree_skb(skb); - continue; - } - wp = bc->hdlctx.buf; - bp = skb->data+1; - crc = calc_crc_ccitt(bp, pkt_len); - crcarr[0] = crc; - crcarr[1] = crc >> 8; - *wp++ = 0x7e; - bitstream = bitbuf = numbit = 0; - while (pkt_len > -2) { - bitstream >>= 8; - bitstream |= ((unsigned int)*bp) << 8; - bitbuf |= ((unsigned int)*bp) << numbit; - notbitstream = ~bitstream; - bp++; - pkt_len--; - if (!pkt_len) - bp = crcarr; - ENCODEITERA(0); - ENCODEITERA(1); - ENCODEITERA(2); - ENCODEITERA(3); - ENCODEITERA(4); - ENCODEITERA(5); - ENCODEITERA(6); - ENCODEITERA(7); - goto enditer; - ENCODEITERB(0); - ENCODEITERB(1); - ENCODEITERB(2); - ENCODEITERB(3); - ENCODEITERB(4); - ENCODEITERB(5); - ENCODEITERB(6); - ENCODEITERB(7); - enditer: - numbit += 8; - while (numbit >= 8) { - *wp++ = bitbuf; - bitbuf >>= 8; - numbit -= 8; - } - } - bitbuf |= 0x7e7e << numbit; - numbit += 16; - while (numbit >= 8) { - *wp++ = bitbuf; - bitbuf >>= 8; - numbit -= 8; - } - bc->hdlctx.bufptr = bc->hdlctx.buf; - bc->hdlctx.bufcnt = wp - bc->hdlctx.buf; - dev_kfree_skb(skb); - bc->stats.tx_packets++; + skb = bc->skb; + if (!skb) return; + bc->skb = NULL; + pkt_len = skb->len-1; /* strip KISS byte */ + wp = bc->hdlctx.buf; + bp = skb->data+1; + crc = calc_crc_ccitt(bp, pkt_len); + crcarr[0] = crc; + crcarr[1] = crc >> 8; + *wp++ = 0x7e; + bitstream = bitbuf = numbit = 0; + while (pkt_len > -2) { + bitstream >>= 8; + bitstream |= ((unsigned int)*bp) << 8; + bitbuf |= ((unsigned int)*bp) << numbit; + notbitstream = ~bitstream; + bp++; + pkt_len--; + if (!pkt_len) + bp = crcarr; + ENCODEITERA(0); + ENCODEITERA(1); + ENCODEITERA(2); + ENCODEITERA(3); + ENCODEITERA(4); + ENCODEITERA(5); + ENCODEITERA(6); + ENCODEITERA(7); + goto enditer; + ENCODEITERB(0); + ENCODEITERB(1); + ENCODEITERB(2); + ENCODEITERB(3); + ENCODEITERB(4); + ENCODEITERB(5); + ENCODEITERB(6); + ENCODEITERB(7); + enditer: + numbit += 8; + while (numbit >= 8) { + *wp++ = bitbuf; + bitbuf >>= 8; + numbit -= 8; + } } + bitbuf |= 0x7e7e << numbit; + numbit += 16; + while (numbit >= 8) { + *wp++ = bitbuf; + bitbuf >>= 8; + numbit -= 8; + } + bc->hdlctx.bufptr = bc->hdlctx.buf; + bc->hdlctx.bufcnt = wp - bc->hdlctx.buf; + dev_kfree_skb(skb); + bc->stats.tx_packets++; } /* ---------------------------------------------------------------------- */ @@ -944,6 +934,8 @@ static void epp_bh(struct net_device *dev) bc->debug_vals.demod_cycles = time3 - time2; #endif /* BAYCOM_DEBUG */ queue_task(&bc->run_bh, &tq_timer); + if (!bc->skb) + netif_wake_queue(dev); return; epptimeout: printk(KERN_ERR "%s: EPP timeout!\n", bc_drvname); @@ -960,8 +952,20 @@ static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev) baycom_paranoia_check(dev, "baycom_send_packet", 0); bc = (struct baycom_state *)dev->priv; - skb_queue_tail(&bc->send_queue, skb); - dev->trans_start = jiffies; + if (skb->data[0] != 0) { + do_kiss_params(bc, skb->data, skb->len); + dev_kfree_skb(skb); + return 0; + } + if (bc->skb) + return -1; + /* strip KISS byte */ + if (skb->len >= HDLCDRV_MAXFLEN+1 || skb->len < 3) { + dev_kfree_skb(skb); + return 0; + } + netif_stop_queue(dev); + bc->skb = skb; return 0; } @@ -1030,8 +1034,6 @@ static int epp_open(struct net_device *dev) baycom_paranoia_check(dev, "epp_open", -ENXIO); bc = (struct baycom_state *)dev->priv; - if (dev->start) - return 0; pp = parport_enumerate(); while (pp && pp->base != dev->base_addr) pp = pp->next; @@ -1122,11 +1124,9 @@ static int epp_open(struct net_device *dev) bc->hdlctx.bufcnt = 0; bc->hdlctx.slotcnt = bc->ch_params.slottime; bc->hdlctx.calibrate = 0; - dev->start = 1; - dev->tbusy = 0; - dev->interrupt = 0; /* start the bottom half stuff */ queue_task(&bc->run_bh, &tq_timer); + netif_start_queue(dev); MOD_INC_USE_COUNT; return 0; @@ -1144,17 +1144,12 @@ static int epp_close(struct net_device *dev) { struct baycom_state *bc; struct parport *pp; - struct sk_buff *skb; unsigned char tmp[1]; baycom_paranoia_check(dev, "epp_close", -EINVAL); - if (!dev->start) - return 0; bc = (struct baycom_state *)dev->priv; pp = bc->pdev->port; bc->bh_running = 0; - dev->start = 0; - dev->tbusy = 1; run_task_queue(&tq_timer); /* dequeue bottom half */ bc->stat = EPP_DCDBIT; tmp[0] = 0; @@ -1162,9 +1157,9 @@ static int epp_close(struct net_device *dev) parport_write_control(pp, 0); /* reset the adapter */ parport_release(bc->pdev); parport_unregister_device(bc->pdev); - /* Free any buffers left in the hardware transmit queue */ - while ((skb = skb_dequeue(&bc->send_queue))) - dev_kfree_skb(skb); + if (bc->skb) + dev_kfree_skb(bc->skb); + bc->skb = NULL; printk(KERN_INFO "%s: close epp at iobase 0x%lx irq %u\n", bc_drvname, dev->base_addr, dev->irq); MOD_DEC_USE_COUNT; @@ -1280,7 +1275,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; case HDLCDRVCTL_SETMODEMPAR: - if ((!suser()) || dev->start) + if ((!suser()) || netif_running(dev)) return -EACCES; dev->base_addr = hi.data.mp.iobase; dev->irq = /*hi.data.mp.irq*/0; @@ -1319,7 +1314,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; case HDLCDRVCTL_SETMODE: - if (!suser() || dev->start) + if (!suser() || netif_running(dev)) return -EACCES; hi.data.modename[sizeof(hi.data.modename)-1] = '\0'; return baycom_setmode(bc, hi.data.modename); @@ -1385,7 +1380,7 @@ static int baycom_probe(struct net_device *dev) /* Fill in the fields of the device structure */ dev_init_buffers(dev); - skb_queue_head_init(&bc->send_queue); + bc->skb = NULL; #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) dev->hard_header = ax25_encapsulate; @@ -1402,6 +1397,7 @@ static int baycom_probe(struct net_device *dev) dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN); + dev->tx_queue_len = 16; /* New style flags */ dev->flags = 0; @@ -1461,8 +1457,6 @@ static int __init init_baycomepp(void) dev->name = bc->ifname; dev->if_port = 0; dev->init = baycom_probe; - dev->start = 0; - dev->tbusy = 1; dev->base_addr = iobase[i]; dev->irq = 0; dev->dma = 0; diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 0bd2a1725..b68063b07 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c @@ -3,7 +3,7 @@ /* * baycom_par.c -- baycom par96 and picpar radio modem driver. * - * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-2000 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -53,14 +53,16 @@ * * * History: - * 0.1 26.06.96 Adapted from baycom.c and made network driver interface - * 18.10.96 Changed to new user space access routines (copy_{to,from}_user) - * 0.3 26.04.97 init code/data tagged - * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints) - * 0.5 11.11.97 split into separate files for ser12/par96 - * 0.6 03.08.99 adapt to Linus' new __setup/__initcall - * removed some pre-2.2 kernel compatibility cruft - * 0.7 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts + * 0.1 26.06.1996 Adapted from baycom.c and made network driver interface + * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user) + * 0.3 26.04.1997 init code/data tagged + * 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints) + * 0.5 11.11.1997 split into separate files for ser12/par96 + * 0.6 03.08.1999 adapt to Linus' new __setup/__initcall + * removed some pre-2.2 kernel compatibility cruft + * 0.7 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts + * 0.8 12.02.2000 adapted to softnet driver interface + * removed direct parport access, uses parport driver methods */ /*****************************************************************************/ @@ -77,7 +79,6 @@ #include <linux/string.h> #include <asm/system.h> #include <asm/bitops.h> -#include <asm/io.h> #include <asm/uaccess.h> #include <linux/init.h> #include <linux/delay.h> @@ -99,8 +100,8 @@ /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_par"; -static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_par: version 0.6 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_par: version 0.8 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ @@ -110,13 +111,6 @@ static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ -#define SER12_EXTENT 8 - -#define LPT_DATA(dev) ((dev)->base_addr+0) -#define LPT_STATUS(dev) ((dev)->base_addr+1) -#define LPT_CONTROL(dev) ((dev)->base_addr+2) -#define LPT_IRQ_ENABLE 0x10 - #define PAR96_BURSTBITS 16 #define PAR96_BURST 4 #define PAR96_PTT 2 @@ -207,6 +201,7 @@ static __inline__ void par96_tx(struct net_device *dev, struct baycom_state *bc) { int i; unsigned int data = hdlcdrv_getbits(&bc->hdrv); + struct parport *pp = bc->pdev->port; for(i = 0; i < PAR96_BURSTBITS; i++, data >>= 1) { unsigned char val = PAR97_POWER; @@ -219,8 +214,8 @@ static __inline__ void par96_tx(struct net_device *dev, struct baycom_state *bc) (PAR96_SCRAM_TAPN << 1); if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2)) val |= PAR96_TXBIT; - outb(val, LPT_DATA(dev)); - outb(val | PAR96_BURST, LPT_DATA(dev)); + pp->ops->write_data(pp, val); + pp->ops->write_data(pp, val | PAR96_BURST); } } @@ -230,24 +225,25 @@ static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc) { int i; unsigned int data, mask, mask2, descx; + struct parport *pp = bc->pdev->port; /* * do receiver; differential decode and descramble on the fly */ for(data = i = 0; i < PAR96_BURSTBITS; i++) { bc->modem.par96.descram = (bc->modem.par96.descram << 1); - if (inb(LPT_STATUS(dev)) & PAR96_RXBIT) + if (pp->ops->read_status(pp) & PAR96_RXBIT) bc->modem.par96.descram |= 1; descx = bc->modem.par96.descram ^ (bc->modem.par96.descram >> 1); /* now the diff decoded data is inverted in descram */ - outb(PAR97_POWER | PAR96_PTT, LPT_DATA(dev)); + pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT); descx ^= ((descx >> PAR96_DESCRAM_TAPSH1) ^ (descx >> PAR96_DESCRAM_TAPSH2)); data >>= 1; if (!(descx & 1)) data |= 0x8000; - outb(PAR97_POWER | PAR96_PTT | PAR96_BURST, LPT_DATA(dev)); + pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT | PAR96_BURST); } hdlcdrv_putbits(&bc->hdrv, data); /* @@ -272,7 +268,7 @@ static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc) bc->modem.par96.dcd_count -= 2; hdlcdrv_setdcd(&bc->hdrv, bc->modem.par96.dcd_count > 0); } else { - hdlcdrv_setdcd(&bc->hdrv, !!(inb(LPT_STATUS(dev)) & PAR96_DCD)); + hdlcdrv_setdcd(&bc->hdrv, !!(pp->ops->read_status(pp) & PAR96_DCD)); } } @@ -353,13 +349,12 @@ static int par96_open(struct net_device *dev) parport_unregister_device(bc->pdev); return -EBUSY; } + pp = bc->pdev->port; dev->irq = pp->irq; - /* bc->pdev->port->ops->change_mode(bc->pdev->port, PARPORT_MODE_PCSPP); not yet implemented */ + pp->ops->data_forward(pp); bc->hdrv.par.bitrate = 9600; - /* switch off PTT */ - outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev)); - /*bc->pdev->port->ops->enable_irq(bc->pdev->port); not yet implemented */ - outb(LPT_IRQ_ENABLE, LPT_CONTROL(dev)); + pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER); /* switch off PTT */ + pp->ops->enable_irq(pp); printk(KERN_INFO "%s: par96 at iobase 0x%lx irq %u options 0x%x\n", bc_drvname, dev->base_addr, dev->irq, bc->options); MOD_INC_USE_COUNT; @@ -371,14 +366,15 @@ static int par96_open(struct net_device *dev) static int par96_close(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; + struct parport *pp; if (!dev || !bc) return -EINVAL; + pp = bc->pdev->port; /* disable interrupt */ - outb(0, LPT_CONTROL(dev)); - /*bc->pdev->port->ops->disable_irq(bc->pdev->port); not yet implemented */ + pp->ops->disable_irq(pp); /* switch off PTT */ - outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev)); + pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER); parport_release(bc->pdev); parport_unregister_device(bc->pdev); printk(KERN_INFO "%s: close par96 at iobase 0x%lx irq %u\n", @@ -449,7 +445,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, return 0; case HDLCDRVCTL_SETMODE: - if (dev->start || !suser()) + if (netif_running(dev) || !suser()) return -EACCES; hi->data.modename[sizeof(hi->data.modename)-1] = '\0'; return baycom_setmode(bc, hi->data.modename); diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 9c6e69cf6..cdcab2621 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c @@ -3,7 +3,7 @@ /* * baycom_ser_fdx.c -- baycom ser12 fullduplex radio modem driver. * - * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-2000 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,16 +55,17 @@ * * * History: - * 0.1 26.06.96 Adapted from baycom.c and made network driver interface - * 18.10.96 Changed to new user space access routines (copy_{to,from}_user) - * 0.3 26.04.97 init code/data tagged - * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints) - * 0.5 11.11.97 ser12/par96 split into separate files - * 0.6 24.01.98 Thorsten Kranzkowski, dl8bcu and Thomas Sailer: - * reduced interrupt load in transmit case - * reworked receiver - * 0.7 03.08.99 adapt to Linus' new __setup/__initcall - * 0.8 10.08.99 use module_init/module_exit + * 0.1 26.06.1996 Adapted from baycom.c and made network driver interface + * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user) + * 0.3 26.04.1997 init code/data tagged + * 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints) + * 0.5 11.11.1997 ser12/par96 split into separate files + * 0.6 24.01.1998 Thorsten Kranzkowski, dl8bcu and Thomas Sailer: + * reduced interrupt load in transmit case + * reworked receiver + * 0.7 03.08.1999 adapt to Linus' new __setup/__initcall + * 0.8 10.08.1999 use module_init/module_exit + * 0.9 12.02.2000 adapted to softnet driver interface */ /*****************************************************************************/ @@ -86,8 +87,8 @@ /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_ser_fdx"; -static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_ser_fdx: version 0.7 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_ser_fdx: version 0.9 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ @@ -554,7 +555,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, return 0; case HDLCDRVCTL_SETMODE: - if (dev->start || !suser()) + if (netif_running(dev) || !suser()) return -EACCES; hi->data.modename[sizeof(hi->data.modename)-1] = '\0'; return baycom_setmode(bc, hi->data.modename); diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index c44395f84..64b27286c 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c @@ -3,7 +3,7 @@ /* * baycom_ser_hdx.c -- baycom ser12 halfduplex radio modem driver. * - * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-2000 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,14 +47,15 @@ * * * History: - * 0.1 26.06.96 Adapted from baycom.c and made network driver interface - * 18.10.96 Changed to new user space access routines (copy_{to,from}_user) - * 0.3 26.04.97 init code/data tagged - * 0.4 08.07.97 alternative ser12 decoding algorithm (uses delta CTS ints) - * 0.5 11.11.97 ser12/par96 split into separate files - * 0.6 14.04.98 cleanups - * 0.7 03.08.99 adapt to Linus' new __setup/__initcall - * 0.8 10.08.99 use module_init/module_exit + * 0.1 26.06.1996 Adapted from baycom.c and made network driver interface + * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user) + * 0.3 26.04.1997 init code/data tagged + * 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints) + * 0.5 11.11.1997 ser12/par96 split into separate files + * 0.6 14.04.1998 cleanups + * 0.7 03.08.1999 adapt to Linus' new __setup/__initcall + * 0.8 10.08.1999 use module_init/module_exit + * 0.9 12.02.2000 adapted to softnet driver interface */ /*****************************************************************************/ @@ -76,8 +77,8 @@ /* --------------------------------------------------------------------- */ static const char bc_drvname[] = "baycom_ser_hdx"; -static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "baycom_ser_hdx: version 0.7 compiled " __TIME__ " " __DATE__ "\n"; +static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "baycom_ser_hdx: version 0.9 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ @@ -597,7 +598,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, return 0; case HDLCDRVCTL_SETMODE: - if (dev->start || !suser()) + if (netif_running(dev) || !suser()) return -EACCES; hi->data.modename[sizeof(hi->data.modename)-1] = '\0'; return baycom_setmode(bc, hi->data.modename); diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 55ed5254e..0cc9aa7c1 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -222,7 +222,7 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty dev = bpq_get_ax25_dev(dev); - if (dev == NULL || dev->start == 0) { + if (dev == NULL || !netif_running(dev)) { kfree_skb(skb); return 0; } @@ -275,7 +275,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev) * Just to be *really* sure not to send anything if the interface * is down, the ethernet device may have gone. */ - if (!dev->start) { + if (!netif_running(dev)) { bpq_check_devices(dev); kfree_skb(skb); return -ENODEV; @@ -324,7 +324,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev) bpq->stats.tx_bytes+=skb->len; dev_queue_xmit(skb); - + netif_wake_queue(dev); return 0; } @@ -407,22 +407,17 @@ static int bpq_open(struct net_device *dev) { if (bpq_check_devices(dev)) return -ENODEV; /* oops, it's gone */ - - dev->tbusy = 0; - dev->start = 1; - + MOD_INC_USE_COUNT; + netif_start_queue(dev); return 0; } static int bpq_close(struct net_device *dev) { - dev->tbusy = 1; - dev->start = 0; - + netif_stop_queue(dev); MOD_DEC_USE_COUNT; - return 0; } @@ -621,7 +616,7 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi * Initialize driver. To be called from af_ax25 if not compiled as a * module */ -int __init bpq_init(void) +static int __init bpq_init_driver(void) { struct net_device *dev; @@ -630,7 +625,7 @@ int __init bpq_init(void) register_netdevice_notifier(&bpq_dev_notifier); - printk(KERN_INFO "AX.25 ethernet driver version 0.01\n"); + printk(KERN_INFO "AX.25: bpqether driver version 0.01\n"); proc_net_create ("bpqether", 0, bpq_get_info); @@ -643,22 +638,10 @@ int __init bpq_init(void) } } read_unlock_bh(&dev_base_lock); -out: return 0; } -#ifdef MODULE -EXPORT_NO_SYMBOLS; - -MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@lykos.oche.de>"); -MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet"); - -int init_module(void) -{ - return bpq_init(); -} - -void cleanup_module(void) +static void __exit bpq_cleanup_driver(void) { struct bpqdev *bpq; @@ -671,4 +654,8 @@ void cleanup_module(void) for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next) unregister_netdev(&bpq->axdev); } -#endif + +MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@poboxes.com>"); +MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet"); +module_init(bpq_init_driver); +module_exit(bpq_cleanup_driver); diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index afba5cb14..3e7cd8e44 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -643,7 +643,6 @@ static int scc_open(struct net_device *dev) } /* Initialize local variables */ - dev->tbusy = 0; priv->rx_ptr = 0; priv->rx_over = 0; priv->rx_head = priv->rx_tail = priv->rx_count = 0; @@ -732,7 +731,7 @@ static int scc_open(struct net_device *dev) /* Configure PI2 DMA */ if (info->type <= TYPE_PI2) outb_p(1, io + PI_DREQ_MASK); - dev->start = 1; + netif_start_queue(dev); info->open++; MOD_INC_USE_COUNT; @@ -747,9 +746,8 @@ static int scc_close(struct net_device *dev) int io = dev->base_addr; int cmd = priv->cmd; - dev->start = 0; + netif_stop_queue(dev); info->open--; - MOD_DEC_USE_COUNT; if (info->type == TYPE_TWIN) /* Drop DTR */ @@ -768,6 +766,7 @@ static int scc_close(struct net_device *dev) if (info->type <= TYPE_PI2) outb_p(0, io + PI_DREQ_MASK); free_irq(dev->irq, info); } + MOD_DEC_USE_COUNT; return 0; } @@ -779,16 +778,16 @@ static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (cmd) { case SIOCGSCCPARAM: - rc = verify_area(VERIFY_WRITE, ifr->ifr_data, sizeof(struct scc_param)); - if (rc) return rc; - copy_to_user(ifr->ifr_data, &priv->param, sizeof(struct scc_param)); + if(copy_to_user(ifr->ifr_data, &priv->param, sizeof(struct scc_param))) + return -EFAULT; return 0; case SIOCSSCCPARAM: - if (!suser()) return -EPERM; - rc = verify_area(VERIFY_READ, ifr->ifr_data, sizeof(struct scc_param)); - if (rc) return rc; - if (dev->start) return -EAGAIN; - copy_from_user(&priv->param, ifr->ifr_data, sizeof(struct scc_param)); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (netif_running(dev)) + return -EAGAIN; + if(copy_from_user(&priv->param, ifr->ifr_data, sizeof(struct scc_param))) + return -EFAULT; dev->dma = priv->param.dma; return 0; default: @@ -806,18 +805,8 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) int i; /* Block a timer-based transmit from overlapping */ - if (test_and_set_bit(0, (void *) &priv->tx_sem) != 0) { - atomic_inc((void *) &priv->stats.tx_dropped); - dev_kfree_skb(skb); - return 0; - } - - /* Return with an error if we cannot accept more data */ - if (dev->tbusy) { - priv->tx_sem = 0; - return -1; - } - + netif_stop_queue(dev); + /* Transfer data to DMA buffer */ i = priv->tx_head; memcpy(priv->tx_buf[i], skb->data+1, skb->len-1); @@ -829,7 +818,8 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) /* Set the busy flag if we just filled up the last buffer */ priv->tx_head = (i + 1) % NUM_TX_BUF; priv->tx_count++; - if (priv->tx_count == NUM_TX_BUF) dev->tbusy = 1; + if (priv->tx_count != NUM_TX_BUF) + netif_wake_queue(dev); /* Set new TX state */ if (priv->tx_state == TX_IDLE) { @@ -1139,7 +1129,6 @@ static void es_isr(struct net_device *dev) /* Remove frame from FIFO */ priv->tx_tail = (i + 1) % NUM_TX_BUF; priv->tx_count--; - dev->tbusy = 0; /* Check if another frame is available and we are allowed to transmit */ if (priv->tx_count && (jiffies - priv->tx_start) < priv->param.txtime) { if (dev->dma) { @@ -1171,7 +1160,7 @@ static void es_isr(struct net_device *dev) priv->stats.tx_packets++; } /* Inform upper layers */ - mark_bh(NET_BH); + netif_wake_queue(dev); } /* DCD transition */ diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 67a835b02..a3560c207 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -3,7 +3,7 @@ /* * hdlcdrv.c -- HDLC packet radio network driver. * - * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-2000 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,16 +27,17 @@ * Written 1993-94 by Donald Becker. * * History: - * 0.1 21.09.96 Started - * 18.10.96 Changed to new user space access routines - * (copy_{to,from}_user) - * 0.2 21.11.96 various small changes - * 0.3 03.03.97 fixed (hopefully) IP not working with ax.25 as a module - * 0.4 16.04.97 init code/data tagged - * 0.5 30.07.97 made HDLC buffers bigger (solves a problem with the - * soundmodem driver) - * 0.6 05.04.98 add spinlocks - * 0.7 03.08.99 removed some old compatibility cruft + * 0.1 21.09.1996 Started + * 18.10.1996 Changed to new user space access routines + * (copy_{to,from}_user) + * 0.2 21.11.1996 various small changes + * 0.3 03.03.1997 fixed (hopefully) IP not working with ax.25 as a module + * 0.4 16.04.1997 init code/data tagged + * 0.5 30.07.1997 made HDLC buffers bigger (solves a problem with the + * soundmodem driver) + * 0.6 05.04.1998 add spinlocks + * 0.7 03.08.1999 removed some old compatibility cruft + * 0.8 12.02.2000 adapted to softnet driver interface */ /*****************************************************************************/ @@ -366,29 +367,25 @@ void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s) clear_bit(0, &s->hdlctx.in_hdlc_tx); return; } - if (!(skb = skb_dequeue(&s->send_queue))) { - int flgs = tenms_to_2flags - (s, s->ch_params.tx_tail); + if (!(skb = s->skb)) { + int flgs = tenms_to_2flags(s, s->ch_params.tx_tail); if (flgs < 2) flgs = 2; s->hdlctx.tx_state = 1; s->hdlctx.numflags = flgs; break; } - if (skb->data[0] != 0) { - do_kiss_params(s, skb->data, skb->len); - dev_kfree_skb(skb); - break; - } + s->skb = NULL; + netif_wake_queue(dev); pkt_len = skb->len-1; /* strip KISS byte */ if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) { s->hdlctx.tx_state = 0; s->hdlctx.numflags = 1; - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); break; } memcpy(s->hdlctx.buffer, skb->data+1, pkt_len); - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); s->hdlctx.bp = s->hdlctx.buffer; append_crc_ccitt(s->hdlctx.buffer, pkt_len); s->hdlctx.len = pkt_len+2; /* the appended CRC */ @@ -454,8 +451,7 @@ static inline unsigned short random_num(void) void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s) { - if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || - skb_queue_empty(&s->send_queue)) + if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb) return; if (s->ch_params.fulldup) { start_tx(dev, s); @@ -499,8 +495,15 @@ static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev) if (hdlcdrv_paranoia_check(dev, "hdlcdrv_send_packet")) return 0; sm = (struct hdlcdrv_state *)dev->priv; - skb_queue_tail(&sm->send_queue, skb); - dev->trans_start = jiffies; + if (skb->data[0] != 0) { + do_kiss_params(sm, skb->data, skb->len); + dev_kfree_skb(skb); + return 0; + } + if (sm->skb) + return -1; + netif_stop_queue(dev); + sm->skb = skb; return 0; } @@ -550,12 +553,9 @@ static int hdlcdrv_open(struct net_device *dev) return -EINVAL; s = (struct hdlcdrv_state *)dev->priv; - if (dev->start) - return 0; if (!s->ops || !s->ops->open) return -ENODEV; - dev->start = 1; /* * initialise some variables */ @@ -573,14 +573,9 @@ static int hdlcdrv_open(struct net_device *dev) s->hdlctx.calibrate = 0; i = s->ops->open(dev); - if (i) { - dev->start = 0; + if (i) return i; - } - - dev->tbusy = 0; - dev->interrupt = 0; - + netif_start_queue(dev); return 0; } @@ -592,23 +587,17 @@ static int hdlcdrv_open(struct net_device *dev) static int hdlcdrv_close(struct net_device *dev) { struct hdlcdrv_state *s; - struct sk_buff *skb; int i = 0; if (hdlcdrv_paranoia_check(dev, "hdlcdrv_close")) return -EINVAL; s = (struct hdlcdrv_state *)dev->priv; - if (!dev->start) - return 0; - dev->start = 0; - dev->tbusy = 1; - if (s->ops && s->ops->close) i = s->ops->close(dev); - /* Free any buffers left in the hardware transmit queue */ - while ((skb = skb_dequeue(&s->send_queue))) - dev_kfree_skb(skb); + if (s->skb) + dev_kfree_skb(s->skb); + s->skb = NULL; return i; } @@ -667,7 +656,7 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; case HDLCDRVCTL_SETMODEMPAR: - if ((!suser()) || dev->start) + if ((!suser()) || netif_running(dev)) return -EACCES; dev->base_addr = bi.data.mp.iobase; dev->irq = bi.data.mp.irq; @@ -801,10 +790,9 @@ static int hdlcdrv_probe(struct net_device *dev) dev->get_stats = hdlcdrv_get_stats; /* Fill in the fields of the device structure */ - dev_init_buffers(dev); - skb_queue_head_init(&s->send_queue); + s->skb = NULL; #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) dev->hard_header = ax25_encapsulate; @@ -821,6 +809,7 @@ static int hdlcdrv_probe(struct net_device *dev) dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN); + dev->tx_queue_len = 16; /* New style flags */ dev->flags = 0; @@ -857,8 +846,6 @@ int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *o dev->name = s->ifname; dev->if_port = 0; dev->init = hdlcdrv_probe; - dev->start = 0; - dev->tbusy = 1; dev->base_addr = baseaddr; dev->irq = irq; dev->dma = dma; @@ -884,7 +871,7 @@ int hdlcdrv_unregister_hdlcdrv(struct net_device *dev) return -EINVAL; if (s->magic != HDLCDRV_MAGIC) return -EINVAL; - if (dev->start && s->ops->close) + if (s->ops->close) s->ops->close(dev); unregister_netdev(dev); kfree(s); @@ -911,8 +898,8 @@ MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder"); int __init init_module(void) { - printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n"); - printk(KERN_INFO "hdlcdrv: version 0.7 compiled " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "hdlcdrv: (C) 1996-2000 Thomas Sailer HB9JNX/AE4WA\n"); + printk(KERN_INFO "hdlcdrv: version 0.8 compiled " __TIME__ " " __DATE__ "\n"); return 0; } diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 4de421874..09bb422f1 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -1,7 +1,7 @@ #define RCS_ID "$Id: scc.c,v 1.75 1998/11/04 15:15:01 jreuter Exp jreuter $" #define VERSION "3.0" -#define BANNER "Z8530 SCC driver version "VERSION".dl1bke (experimental) by DL1BKE\n" +#define BANNER "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n" /* * Please use z8530drv-utils-3.0 with this version. @@ -19,7 +19,7 @@ ******************************************************************** - Copyright (c) 1993, 1998 Joerg Reuter DL1BKE + Copyright (c) 1993, 2000 Joerg Reuter DL1BKE portions (c) 1993 Guido ten Dolle PE1NNZ @@ -104,6 +104,9 @@ flags that aren't... Restarting the DPLL does not help either, it resynchronizes too slow and the first received frame gets lost. + 2000-02-13 Fixed for new network driver interface changes, still + does TX timeouts itself since it uses its own queue + scheme. Thanks to all who contributed to this driver with ideas and bug reports! @@ -236,9 +239,6 @@ static unsigned char Driver_Initialized = 0; static int Nchips = 0; static io_port Vector_Latch = 0; -MODULE_AUTHOR("Joerg Reuter <jreuter@poboxes.com>"); -MODULE_DESCRIPTION("Network Device Driver for Z8530 based HDLC cards for Amateur Packet Radio"); -MODULE_SUPPORTED_DEVICE("scc"); /* ******************************************************************** */ /* * Port Access Functions * */ @@ -314,17 +314,6 @@ static inline void scc_sti(int irq) /* * Some useful macros * */ /* ******************************************************************** */ - -static inline void scc_lock_dev(struct scc_channel *scc) -{ - scc->dev->tbusy = 1; -} - -static inline void scc_unlock_dev(struct scc_channel *scc) -{ - scc->dev->tbusy = 0; -} - static inline void scc_discard_buffers(struct scc_channel *scc) { unsigned long flags; @@ -382,7 +371,7 @@ static inline void flush_rx_FIFO(struct scc_channel *scc) if(scc->rx_buff != NULL) /* did we receive something? */ { scc->stat.rxerrs++; /* then count it as an error */ - kfree_skb(scc->rx_buff); + dev_kfree_skb_irq(scc->rx_buff); scc->rx_buff = NULL; } } @@ -411,7 +400,7 @@ static inline void scc_txint(struct scc_channel *scc) { skb = skb_dequeue(&scc->tx_queue); scc->tx_buff = skb; - scc_unlock_dev(scc); + netif_wake_queue(scc->dev); if (skb == NULL) { @@ -422,7 +411,7 @@ static inline void scc_txint(struct scc_channel *scc) if (skb->len == 0) /* Paranoia... */ { - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); scc->tx_buff = NULL; scc_tx_done(scc); Outb(scc->ctrl, RES_Tx_P); @@ -448,7 +437,7 @@ static inline void scc_txint(struct scc_channel *scc) { Outb(scc->ctrl, RES_Tx_P); /* reset pending int */ cl(scc, R10, ABUNDER); /* send CRC */ - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); scc->tx_buff = NULL; scc->stat.tx_state = TXS_NEWFRAME; /* next frame... */ return; @@ -533,7 +522,7 @@ static inline void scc_exint(struct scc_channel *scc) if (scc->tx_buff != NULL) { - dev_kfree_skb(scc->tx_buff); + dev_kfree_skb_irq(scc->tx_buff); scc->tx_buff = NULL; } @@ -583,7 +572,7 @@ static inline void scc_rxint(struct scc_channel *scc) #ifdef notdef printk(KERN_DEBUG "z8530drv: oops, scc_rxint() received huge frame...\n"); #endif - kfree_skb(skb); + dev_kfree_skb_irq(skb); scc->rx_buff = NULL; Inb(scc->data); or(scc, R3, ENT_HM); @@ -613,7 +602,7 @@ static inline void scc_spint(struct scc_channel *scc) or(scc,R3,ENT_HM); /* enter hunt mode for next flag */ if (skb != NULL) - kfree_skb(skb); + dev_kfree_skb_irq(skb); scc->rx_buff = NULL; } @@ -629,7 +618,7 @@ static inline void scc_spint(struct scc_channel *scc) scc->rx_buff = NULL; scc->stat.rxframes++; } else { /* a bad frame */ - kfree_skb(skb); + dev_kfree_skb_irq(skb); scc->rx_buff = NULL; scc->stat.rxerrs++; } @@ -1112,7 +1101,7 @@ static void scc_tx_done(struct scc_channel *scc) scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime); } - scc_unlock_dev(scc); + netif_wake_queue(scc->dev); } @@ -1163,7 +1152,7 @@ static void t_dwait(unsigned long channel) if (skb_queue_len(&scc->tx_queue) == 0) /* nothing to send */ { scc->stat.tx_state = TXS_IDLE; - scc_unlock_dev(scc); /* t_maxkeyup locked it. */ + netif_wake_queue(scc->dev); /* t_maxkeyup locked it. */ return; } @@ -1243,7 +1232,7 @@ static void t_tail(unsigned long channel) } scc->stat.tx_state = TXS_IDLE; - scc_unlock_dev(scc); + netif_wake_queue(scc->dev); } @@ -1257,14 +1246,13 @@ static void t_busy(unsigned long channel) struct scc_channel *scc = (struct scc_channel *) channel; del_timer(&scc->tx_t); - scc_lock_dev(scc); + netif_stop_queue(scc->dev); /* don't pile on the wabbit! */ scc_discard_buffers(scc); - scc->stat.txerrs++; scc->stat.tx_state = TXS_IDLE; - - scc_unlock_dev(scc); + + netif_wake_queue(scc->dev); } /* MAXKEYUP timeout @@ -1285,7 +1273,7 @@ static void t_maxkeyup(unsigned long channel) * accept new data. */ - scc_lock_dev(scc); + netif_stop_queue(scc->dev); scc_discard_buffers(scc); del_timer(&scc->tx_t); @@ -1460,8 +1448,7 @@ static void scc_stop_calibrate(unsigned long channel) Outb(scc->ctrl,RES_EXT_INT); /* reset ext/status interrupts */ Outb(scc->ctrl,RES_EXT_INT); - scc_unlock_dev(scc); - + netif_wake_queue(scc->dev); restore_flags(flags); } @@ -1474,7 +1461,7 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern save_flags(flags); cli(); - scc_lock_dev(scc); + netif_stop_queue(scc->dev); scc_discard_buffers(scc); del_timer(&scc->tx_wdog); @@ -1497,7 +1484,6 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern Outb(scc->ctrl,RES_EXT_INT); scc_key_trx(scc, TX_ON); - restore_flags(flags); } @@ -1583,7 +1569,9 @@ static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev dev = scc->dev; memset(dev, 0, sizeof(struct net_device)); - buf = (unsigned char *) kmalloc(10, GFP_KERNEL); + if ((buf = (unsigned char *) kmalloc(10, GFP_KERNEL)) == NULL) + return -ENOMEM; + strcpy(buf, name); dev->priv = (void *) scc; @@ -1627,6 +1615,7 @@ static int scc_net_init(struct net_device *dev) dev->set_mac_address = scc_net_set_mac_address; dev->get_stats = scc_net_get_stats; dev->do_ioctl = scc_net_ioctl; + dev->tx_timeout = NULL; memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN); @@ -1647,22 +1636,17 @@ static int scc_net_open(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; - if (scc == NULL || scc->magic != SCC_MAGIC) - return -ENODEV; - if (!scc->init) return -EINVAL; MOD_INC_USE_COUNT; - + scc->tx_buff = NULL; skb_queue_head_init(&scc->tx_queue); init_channel(scc); - dev->tbusy = 0; - dev->start = 1; - + netif_start_queue(dev); return 0; } @@ -1673,10 +1657,7 @@ static int scc_net_close(struct net_device *dev) struct scc_channel *scc = (struct scc_channel *) dev->priv; unsigned long flags; - if (scc == NULL || scc->magic != SCC_MAGIC) - return -ENODEV; - - MOD_DEC_USE_COUNT; + netif_stop_queue(dev); save_flags(flags); cli(); @@ -1692,9 +1673,7 @@ static int scc_net_close(struct net_device *dev) scc_discard_buffers(scc); - dev->tbusy = 1; - dev->start = 0; - + MOD_DEC_USE_COUNT; return 0; } @@ -1704,7 +1683,7 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb) { if (skb->len == 0) { - kfree_skb(skb); + dev_kfree_skb_irq(skb); return; } @@ -1726,12 +1705,6 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev) struct scc_channel *scc = (struct scc_channel *) dev->priv; unsigned long flags; char kisscmd; - - if (scc == NULL || scc->magic != SCC_MAGIC || dev->tbusy) - { - dev_kfree_skb(skb); - return 0; - } if (skb->len > scc->stat.bufsize || skb->len < 2) { @@ -1759,12 +1732,12 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev) if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len) { struct sk_buff *skb_del; - skb_del = __skb_dequeue(&scc->tx_queue); + skb_del = skb_dequeue(&scc->tx_queue); dev_kfree_skb(skb_del); } - __skb_queue_tail(&scc->tx_queue, skb); - + skb_queue_tail(&scc->tx_queue, skb); dev->trans_start = jiffies; + /* * Start transmission if the trx state is idle or @@ -1781,8 +1754,7 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev) scc_start_tx_timer(scc, t_dwait, 0); } - restore_flags(flags); - + restore_flags(flags); return 0; } @@ -1811,9 +1783,6 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct scc_channel *scc; scc = (struct scc_channel *) dev->priv; - if (scc == NULL || scc->magic != SCC_MAGIC) - return -EINVAL; - arg = (void *) ifr->ifr_data; if (!Driver_Initialized) @@ -2052,9 +2021,6 @@ static struct net_device_stats *scc_net_get_stats(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; - if (scc == NULL || scc->magic != SCC_MAGIC) - return NULL; - scc->dev_stat.rx_errors = scc->stat.rxerrs + scc->stat.rx_over; scc->dev_stat.tx_errors = scc->stat.txerrs + scc->stat.tx_under; scc->dev_stat.rx_fifo_errors = scc->stat.rx_over; @@ -2186,7 +2152,7 @@ done: /* * Init SCC driver * */ /* ******************************************************************** */ -int __init scc_init (void) +static int __init scc_init_driver (void) { int chip, chan, k, result; char devname[10]; @@ -2222,25 +2188,7 @@ int __init scc_init (void) return 0; } -/* ******************************************************************** */ -/* * Module support * */ -/* ******************************************************************** */ - - -#ifdef MODULE -int init_module(void) -{ - int result = 0; - - result = scc_init(); - - if (result == 0) - printk(KERN_INFO "Copyright 1993,1998 Joerg Reuter DL1BKE (jreuter@poboxes.com)\n"); - - return result; -} - -void cleanup_module(void) +static void __exit scc_cleanup_driver(void) { long flags; io_port ctrl; @@ -2283,4 +2231,9 @@ void cleanup_module(void) scc_net_procfs_remove(); } -#endif + +MODULE_AUTHOR("Joerg Reuter <jreuter@poboxes.com>"); +MODULE_DESCRIPTION("AX.25 Device Driver for Z8530 based HDLC cards"); +MODULE_SUPPORTED_DEVICE("scc"); +module_init(scc_init_driver); +module_exit(scc_cleanup_driver); diff --git a/drivers/net/hamradio/soundmodem/sm.c b/drivers/net/hamradio/soundmodem/sm.c index 6fa4aca6b..4e5e3e9b9 100644 --- a/drivers/net/hamradio/soundmodem/sm.c +++ b/drivers/net/hamradio/soundmodem/sm.c @@ -3,7 +3,7 @@ /* * sm.c -- soundcard radio modem driver. * - * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1996-2000 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,17 +34,18 @@ * * * History: - * 0.1 21.09.96 Started - * 18.10.96 Changed to new user space access routines (copy_{to,from}_user) - * 0.4 21.01.97 Separately compileable soundcard/modem modules - * 0.5 03.03.97 fixed LPT probing (check_lpt result was interpreted the wrong way round) - * 0.6 16.04.97 init code/data tagged - * 0.7 30.07.97 fixed halfduplex interrupt handlers/hotfix for CS423X - * 0.8 14.04.98 cleanups - * 0.9 03.08.99 adapt to Linus' new __setup/__initcall - * use parport lowlevel drivers instead of directly writing to a parallel port - * removed some pre-2.2 kernel compatibility cruft - * 0.10 10.08.99 Check if parport can do SPP and is safe to access during interrupt contexts + * 0.1 21.09.1996 Started + * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user) + * 0.4 21.01.1997 Separately compileable soundcard/modem modules + * 0.5 03.03.1997 fixed LPT probing (check_lpt result was interpreted the wrong way round) + * 0.6 16.04.1997 init code/data tagged + * 0.7 30.07.1997 fixed halfduplex interrupt handlers/hotfix for CS423X + * 0.8 14.04.1998 cleanups + * 0.9 03.08.1999 adapt to Linus' new __setup/__initcall + * use parport lowlevel drivers instead of directly writing to a parallel port + * removed some pre-2.2 kernel compatibility cruft + * 0.10 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts + * 0.11 12.02.2000 adapted to softnet driver interface */ /*****************************************************************************/ @@ -63,8 +64,8 @@ /* --------------------------------------------------------------------- */ /*static*/ const char sm_drvname[] = "soundmodem"; -static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-1999 Thomas Sailer, HB9JNX/AE4WA\n" -KERN_INFO "soundmodem: version 0.9 compiled " __TIME__ " " __DATE__ "\n"; +static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n" +KERN_INFO "soundmodem: version 0.11 compiled " __TIME__ " " __DATE__ "\n"; /* --------------------------------------------------------------------- */ @@ -508,7 +509,7 @@ static int sm_ioctl(struct net_device *dev, struct ifreq *ifr, return 0; case HDLCDRVCTL_SETMODE: - if (dev->start || !suser()) + if (netif_running(dev) || !suser()) return -EACCES; hi->data.modename[sizeof(hi->data.modename)-1] = '\0'; return sethw(dev, sm, hi->data.modename); diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index e99d4c7a9..400facbf8 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -649,7 +649,7 @@ static void yam_dotimer(unsigned long dummy) for (i = 0; i < NR_PORTS; i++) { struct net_device *dev = &yam_ports[i].dev; - if (dev->start) + if (netif_running(dev)) yam_arbitrate(dev); } yam_timer.expires = jiffies + HZ / 100; @@ -748,7 +748,7 @@ static void yam_interrupt(int irq, void *dev_id, struct pt_regs *regs) yp = &yam_ports[i]; dev = &yp->dev; - if (!dev->start) + if (!netif_running(dev)) continue; while ((iir = IIR_MASK & inb(IIR(dev->base_addr))) != IIR_NOPEND) { @@ -794,7 +794,7 @@ static int yam_net_get_info(char *buffer, char **start, off_t offset, int length if (yam_ports[i].iobase == 0 || yam_ports[i].irq == 0) continue; len += sprintf(buffer + len, "Device %s\n", yam_ports[i].name); - len += sprintf(buffer + len, " Up %d\n", yam_ports[i].dev.start); + len += sprintf(buffer + len, " Up %d\n", netif_running(&yam_ports[i].dev)); len += sprintf(buffer + len, " Speed %u\n", yam_ports[i].bitrate); len += sprintf(buffer + len, " IoBase 0x%x\n", yam_ports[i].iobase); len += sprintf(buffer + len, " BaudRate %u\n", yam_ports[i].baudrate); @@ -903,7 +903,9 @@ static int yam_open(struct net_device *dev) request_region(dev->base_addr, YAM_EXTENT, dev->name); yam_set_uart(dev); - dev->start = 1; + + netif_start_queue(dev); + yp->slotcnt = yp->slot / 10; /* Reset overruns for all ports - FPGA programming makes overruns */ @@ -935,8 +937,7 @@ static int yam_close(struct net_device *dev) /* Remove IRQ handler if last */ free_irq(dev->irq, NULL); release_region(dev->base_addr, YAM_EXTENT); - dev->start = 0; - dev->tbusy = 1; + netif_stop_queue(dev); while ((skb = skb_dequeue(&yp->send_queue))) dev_kfree_skb(skb); @@ -973,7 +974,7 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EINVAL; /* unused */ case SIOCYAMSMCS: - if (dev->start) + if (netif_running(dev)) return -EINVAL; /* Cannot change this parameter when up */ ym = kmalloc(sizeof(struct yamdrv_ioctl_mcs), GFP_ATOMIC); ym->bitrate = 9600; @@ -989,13 +990,13 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (copy_from_user(&yi, ifr->ifr_data, sizeof(struct yamdrv_ioctl_cfg))) return -EFAULT; - if ((yi.cfg.mask & YAM_IOBASE) && dev->start) + if ((yi.cfg.mask & YAM_IOBASE) && netif_running(dev)) return -EINVAL; /* Cannot change this parameter when up */ - if ((yi.cfg.mask & YAM_IRQ) && dev->start) + if ((yi.cfg.mask & YAM_IRQ) && netif_running(dev)) return -EINVAL; /* Cannot change this parameter when up */ - if ((yi.cfg.mask & YAM_BITRATE) && dev->start) + if ((yi.cfg.mask & YAM_BITRATE) && netif_running(dev)) return -EINVAL; /* Cannot change this parameter when up */ - if ((yi.cfg.mask & YAM_BAUDRATE) && dev->start) + if ((yi.cfg.mask & YAM_BAUDRATE) && netif_running(dev)) return -EINVAL; /* Cannot change this parameter when up */ if (yi.cfg.mask & YAM_IOBASE) { @@ -1164,8 +1165,6 @@ int __init yam_init(void) dev->irq = yam_ports[i].irq; dev->init = yam_probe; dev->if_port = 0; - dev->start = 0; - dev->tbusy = 1; if (register_netdev(dev)) { printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name); @@ -1211,7 +1210,7 @@ void cleanup_module(void) struct net_device *dev = &yam_ports[i].dev; if (!dev->priv) continue; - if (dev->start) + if (netif_running(dev)) yam_close(dev); unregister_netdev(dev); } |