From adeab1afb7de89555c69aab5ca21300c14af6369 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 12 Jul 2009 21:09:20 -0700 Subject: NET: Fix locking issues in PPP, 6pack, mkiss and strip line disciplines. Guido Trentalancia reports: I am trying to use the kiss driver in the Linux kernel that is being shipped with Fedora 10 but unfortunately I get the following oops: mkiss: AX.25 Multikiss, Hans Albas PE1AYX mkiss: ax0: crc mode is auto. ADDRCONF(NETDEV_CHANGE): ax0: link becomes ready ------------[ cut here ]------------ WARNING: at kernel/softirq.c:77 __local_bh_disable+0x2f/0x83() (Not tainted) [...] unloaded: microcode] Pid: 0, comm: swapper Not tainted 2.6.27.25-170.2.72.fc10.i686 #1 [] warn_on_slowpath+0x65/0x8b [] ? _spin_unlock_irqrestore+0x22/0x38 [] ? __enqueue_entity+0xe3/0xeb [] ? enqueue_entity+0x203/0x20b [] ? enqueue_task_fair+0x3b/0x3f [] ? resched_task+0x3a/0x6e [] ? _spin_unlock_irqrestore+0x22/0x38 [] ? _spin_lock_bh+0xb/0x16 [] __local_bh_disable+0x2f/0x83 [] local_bh_disable+0xb/0xd [] _spin_lock_bh+0xb/0x16 [] mkiss_receive_buf+0x2fb/0x3a6 [mkiss] [] flush_to_ldisc+0xf7/0x198 [] tty_flip_buffer_push+0x41/0x51 [] ftdi_process_read+0x375/0x4ad [ftdi_sio] [] ftdi_read_bulk_callback+0x130/0x138 [ftdi_sio] [] usb_hcd_giveback_urb+0x63/0x93 [] uhci_giveback_urb+0xe5/0x15f [] uhci_scan_schedule+0x52e/0x767 [] ? psmouse_handle_byte+0xc/0xe5 [] ? acpi_ev_gpe_detect+0xd6/0xe1 [] uhci_irq+0x110/0x125 [] usb_hcd_irq+0x40/0xa3 [] handle_IRQ_event+0x2f/0x64 [] handle_level_irq+0x74/0xbe [] ? handle_level_irq+0x0/0xbe [] do_IRQ+0xc7/0xfe [] common_interrupt+0x28/0x30 [] ? acpi_idle_enter_simple+0x162/0x19d [] cpuidle_idle_call+0x60/0x92 [] cpu_idle+0x101/0x134 [] rest_init+0x4e/0x50 ======================= ---[ end trace b7cc8076093467ad ]--- ------------[ cut here ]------------ WARNING: at kernel/softirq.c:136 _local_bh_enable_ip+0x3d/0xc4() [...] Pid: 0, comm: swapper Tainted: G W 2.6.27.25-170.2.72.fc10.i686 [] warn_on_slowpath+0x65/0x8b [] ? _spin_unlock_irqrestore+0x22/0x38 [] ? __enqueue_entity+0xe3/0xeb [] ? enqueue_entity+0x203/0x20b [] ? enqueue_task_fair+0x3b/0x3f [] ? resched_task+0x3a/0x6e [] ? _spin_unlock_irqrestore+0x22/0x38 [] ? _spin_lock_bh+0xb/0x16 [] ? mkiss_receive_buf+0x33d/0x3a6 [mkiss] [] _local_bh_enable_ip+0x3d/0xc4 [] local_bh_enable_ip+0x8/0xa [] _spin_unlock_bh+0x11/0x13 [] mkiss_receive_buf+0x33d/0x3a6 [mkiss] [] flush_to_ldisc+0xf7/0x198 [] tty_flip_buffer_push+0x41/0x51 [] ftdi_process_read+0x375/0x4ad [ftdi_sio] [] ftdi_read_bulk_callback+0x130/0x138 [ftdi_sio] [] usb_hcd_giveback_urb+0x63/0x93 [] uhci_giveback_urb+0xe5/0x15f [] uhci_scan_schedule+0x52e/0x767 [] ? psmouse_handle_byte+0xc/0xe5 [] ? acpi_ev_gpe_detect+0xd6/0xe1 [] uhci_irq+0x110/0x125 [] usb_hcd_irq+0x40/0xa3 [] handle_IRQ_event+0x2f/0x64 [] handle_level_irq+0x74/0xbe [] ? handle_level_irq+0x0/0xbe [] do_IRQ+0xc7/0xfe [] common_interrupt+0x28/0x30 [] ? acpi_idle_enter_simple+0x162/0x19d [] cpuidle_idle_call+0x60/0x92 [] cpu_idle+0x101/0x134 [] rest_init+0x4e/0x50 ======================= ---[ end trace b7cc8076093467ad ]--- mkiss: ax0: Trying crc-smack mkiss: ax0: Trying crc-flexnet The issue was, that the locking code in mkiss was assuming it was only ever being called in process or bh context. Fixed by converting the involved locking code to use irq-safe locks. Review of other networking line disciplines shows that 6pack, both sync and async PPP and STRIP have similar issues. The ppp_async one is the most interesting one as it sorts out half of the issue as far back as 2004 in commit http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commitdiff;h=2996d8deaeddd01820691a872550dc0cfba0c37d Signed-off-by: Ralf Baechle Reported-by: Guido Trentalancia Signed-off-by: David S. Miller --- drivers/net/hamradio/6pack.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net/hamradio/6pack.c') diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 155160052c8b..913a56406594 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -398,13 +398,14 @@ static DEFINE_RWLOCK(disc_data_lock); static struct sixpack *sp_get(struct tty_struct *tty) { + unsigned long flags; struct sixpack *sp; - read_lock(&disc_data_lock); + read_lock_irqsave(&disc_data_lock, flags); sp = tty->disc_data; if (sp) atomic_inc(&sp->refcnt); - read_unlock(&disc_data_lock); + read_unlock_irqrestore(&disc_data_lock, flags); return sp; } @@ -688,12 +689,13 @@ out: */ static void sixpack_close(struct tty_struct *tty) { + unsigned long flags; struct sixpack *sp; - write_lock(&disc_data_lock); + write_lock_irqsave(&disc_data_lock, flags); sp = tty->disc_data; tty->disc_data = NULL; - write_unlock(&disc_data_lock); + write_unlock_irqrestore(&disc_data_lock, flags); if (!sp) return; -- cgit v1.2.3 From 252aa9d94a04252046f3a382e6aca1b5c95921d8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 14 Jul 2009 13:13:41 -0700 Subject: Revert "NET: Fix locking issues in PPP, 6pack, mkiss and strip line disciplines." This reverts commit adeab1afb7de89555c69aab5ca21300c14af6369. As Alan Cox explained, the TTY layer changes that went recently to get rid of the tty->low_latency stuff fixes this already, and even for -stable it's the ->low_latency changes that should go in to fix this, rather than this patch. Signed-off-by: David S. Miller --- drivers/net/hamradio/6pack.c | 10 ++++------ drivers/net/hamradio/mkiss.c | 41 +++++++++++++++++------------------------ drivers/net/ppp_async.c | 11 ++++------- drivers/net/ppp_synctty.c | 11 ++++------- drivers/net/wireless/strip.c | 39 +++++++++++++++------------------------ 5 files changed, 44 insertions(+), 68 deletions(-) (limited to 'drivers/net/hamradio/6pack.c') diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 913a56406594..155160052c8b 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -398,14 +398,13 @@ static DEFINE_RWLOCK(disc_data_lock); static struct sixpack *sp_get(struct tty_struct *tty) { - unsigned long flags; struct sixpack *sp; - read_lock_irqsave(&disc_data_lock, flags); + read_lock(&disc_data_lock); sp = tty->disc_data; if (sp) atomic_inc(&sp->refcnt); - read_unlock_irqrestore(&disc_data_lock, flags); + read_unlock(&disc_data_lock); return sp; } @@ -689,13 +688,12 @@ out: */ static void sixpack_close(struct tty_struct *tty) { - unsigned long flags; struct sixpack *sp; - write_lock_irqsave(&disc_data_lock, flags); + write_lock(&disc_data_lock); sp = tty->disc_data; tty->disc_data = NULL; - write_unlock_irqrestore(&disc_data_lock, flags); + write_unlock(&disc_data_lock); if (!sp) return; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index a7286500c186..fda2fc83e9a1 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -244,16 +244,15 @@ static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ static void ax_bump(struct mkiss *ax) { - unsigned long flags; struct sk_buff *skb; int count; - spin_lock_irqsave(&ax->buflock, flags); + spin_lock_bh(&ax->buflock); if (ax->rbuff[0] > 0x0f) { if (ax->rbuff[0] & 0x80) { if (check_crc_16(ax->rbuff, ax->rcount) < 0) { ax->dev->stats.rx_errors++; - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); return; } @@ -268,7 +267,7 @@ static void ax_bump(struct mkiss *ax) } else if (ax->rbuff[0] & 0x20) { if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { ax->dev->stats.rx_errors++; - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); return; } if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) { @@ -295,7 +294,7 @@ static void ax_bump(struct mkiss *ax) printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name); ax->dev->stats.rx_dropped++; - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); return; } @@ -304,13 +303,11 @@ static void ax_bump(struct mkiss *ax) netif_rx(skb); ax->dev->stats.rx_packets++; ax->dev->stats.rx_bytes += count; - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); } static void kiss_unesc(struct mkiss *ax, unsigned char s) { - unsigned long flags; - switch (s) { case END: /* drop keeptest bit = VSV */ @@ -337,18 +334,18 @@ static void kiss_unesc(struct mkiss *ax, unsigned char s) break; } - spin_lock_irqsave(&ax->buflock, flags); + spin_lock_bh(&ax->buflock); if (!test_bit(AXF_ERROR, &ax->flags)) { if (ax->rcount < ax->buffsize) { ax->rbuff[ax->rcount++] = s; - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); return; } ax->dev->stats.rx_over_errors++; set_bit(AXF_ERROR, &ax->flags); } - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); } static int ax_set_mac_address(struct net_device *dev, void *addr) @@ -370,7 +367,6 @@ static void ax_changedmtu(struct mkiss *ax) { struct net_device *dev = ax->dev; unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; - unsigned long flags; int len; len = dev->mtu * 2; @@ -396,7 +392,7 @@ static void ax_changedmtu(struct mkiss *ax) return; } - spin_lock_irqsave(&ax->buflock, flags); + spin_lock_bh(&ax->buflock); oxbuff = ax->xbuff; ax->xbuff = xbuff; @@ -427,7 +423,7 @@ static void ax_changedmtu(struct mkiss *ax) ax->mtu = dev->mtu + 73; ax->buffsize = len; - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); kfree(oxbuff); kfree(orbuff); @@ -437,7 +433,6 @@ static void ax_changedmtu(struct mkiss *ax) static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) { struct mkiss *ax = netdev_priv(dev); - unsigned long flags; unsigned char *p; int actual, count; @@ -454,7 +449,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) p = icp; - spin_lock_irqsave(&ax->buflock, flags); + spin_lock_bh(&ax->buflock); if ((*p & 0x0f) != 0) { /* Configuration Command (kissparms(1). * Protocol spec says: never append CRC. @@ -484,7 +479,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) ax->crcauto = (cmd ? 0 : 1); printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd); } - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); netif_start_queue(dev); return; @@ -517,7 +512,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) count = kiss_esc(p, (unsigned char *)ax->xbuff, len); } } - spin_unlock_irqrestore(&ax->buflock, flags); + spin_unlock_bh(&ax->buflock); set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); actual = ax->tty->ops->write(ax->tty, ax->xbuff, count); @@ -709,14 +704,13 @@ static DEFINE_RWLOCK(disc_data_lock); static struct mkiss *mkiss_get(struct tty_struct *tty) { - unsigned long flags; struct mkiss *ax; - read_lock_irqsave(&disc_data_lock, flags); + read_lock(&disc_data_lock); ax = tty->disc_data; if (ax) atomic_inc(&ax->refcnt); - read_unlock_irqrestore(&disc_data_lock, flags); + read_unlock(&disc_data_lock); return ax; } @@ -815,13 +809,12 @@ out: static void mkiss_close(struct tty_struct *tty) { - unsigned long flags; struct mkiss *ax; - write_lock_irqsave(&disc_data_lock, flags); + write_lock(&disc_data_lock); ax = tty->disc_data; tty->disc_data = NULL; - write_unlock_irqrestore(&disc_data_lock, flags); + write_unlock(&disc_data_lock); if (!ax) return; diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 1fd319bf758e..17c116bb332c 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -132,15 +132,13 @@ static DEFINE_RWLOCK(disc_data_lock); static struct asyncppp *ap_get(struct tty_struct *tty) { - unsigned long flags; struct asyncppp *ap; - read_lock_irqsave(&disc_data_lock, flags); + read_lock(&disc_data_lock); ap = tty->disc_data; if (ap != NULL) atomic_inc(&ap->refcnt); - read_unlock_irqrestore(&disc_data_lock, flags); - + read_unlock(&disc_data_lock); return ap; } @@ -217,13 +215,12 @@ ppp_asynctty_open(struct tty_struct *tty) static void ppp_asynctty_close(struct tty_struct *tty) { - unsigned long flags; struct asyncppp *ap; - write_lock_irqsave(&disc_data_lock, flags); + write_lock_irq(&disc_data_lock); ap = tty->disc_data; tty->disc_data = NULL; - write_unlock_irqrestore(&disc_data_lock, flags); + write_unlock_irq(&disc_data_lock); if (!ap) return; diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 1b3f75febee1..aa3d39f38e22 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -182,15 +182,13 @@ static DEFINE_RWLOCK(disc_data_lock); static struct syncppp *sp_get(struct tty_struct *tty) { - unsigned long flags; struct syncppp *ap; - read_lock_irqsave(&disc_data_lock, flags); + read_lock(&disc_data_lock); ap = tty->disc_data; if (ap != NULL) atomic_inc(&ap->refcnt); - read_unlock_irqrestore(&disc_data_lock, flags); - + read_unlock(&disc_data_lock); return ap; } @@ -264,13 +262,12 @@ ppp_sync_open(struct tty_struct *tty) static void ppp_sync_close(struct tty_struct *tty) { - unsigned long flags; struct syncppp *ap; - write_lock_irqsave(&disc_data_lock, flags); + write_lock_irq(&disc_data_lock); ap = tty->disc_data; tty->disc_data = NULL; - write_unlock_irqrestore(&disc_data_lock, flags); + write_unlock_irq(&disc_data_lock); if (!ap) return; diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 3d39f6587eb9..38366a56b71f 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -856,7 +856,6 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu) unsigned char *orbuff = strip_info->rx_buff; unsigned char *osbuff = strip_info->sx_buff; unsigned char *otbuff = strip_info->tx_buff; - unsigned long flags; if (new_mtu > MAX_SEND_MTU) { printk(KERN_ERR @@ -865,11 +864,11 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } - spin_lock_irqsave(&strip_lock, flags); + spin_lock_bh(&strip_lock); if (!allocate_buffers(strip_info, new_mtu)) { printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n", strip_info->dev->name); - spin_unlock_irqrestore(&strip_lock, flags); + spin_unlock_bh(&strip_lock); return -ENOMEM; } @@ -893,7 +892,7 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu) } } strip_info->tx_head = strip_info->tx_buff; - spin_unlock_irqrestore(&strip_lock, flags); + spin_unlock_bh(&strip_lock); printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n", strip_info->dev->name, old_mtu, strip_info->mtu); @@ -984,13 +983,10 @@ static void strip_seq_neighbours(struct seq_file *seq, const MetricomNodeTable * table, const char *title) { - unsigned long flags; + /* We wrap this in a do/while loop, so if the table changes */ + /* while we're reading it, we just go around and try again. */ struct timeval t; - /* - * We wrap this in a do/while loop, so if the table changes - * while we're reading it, we just go around and try again. - */ do { int i; t = table->timestamp; @@ -999,9 +995,9 @@ static void strip_seq_neighbours(struct seq_file *seq, for (i = 0; i < table->num_nodes; i++) { MetricomNode node; - spin_lock_irqsave(&strip_lock, flags); + spin_lock_bh(&strip_lock); node = table->node[i]; - spin_unlock_irqrestore(&strip_lock, flags); + spin_unlock_bh(&strip_lock); seq_printf(seq, " %s\n", node.c); } } while (table->timestamp.tv_sec != t.tv_sec @@ -1540,7 +1536,6 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb) static int strip_xmit(struct sk_buff *skb, struct net_device *dev) { struct strip *strip_info = netdev_priv(dev); - unsigned long flags; if (!netif_running(dev)) { printk(KERN_ERR "%s: xmit call when iface is down\n", @@ -1579,11 +1574,11 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev) strip_info->dev->name, sx_pps_count / 8); } - spin_lock_irqsave(&strip_lock, flags); + spin_lock_bh(&strip_lock); strip_send(strip_info, skb); - spin_unlock_irqrestore(&strip_lock, flags); + spin_unlock_bh(&strip_lock); if (skb) dev_kfree_skb(skb); @@ -2268,13 +2263,12 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp, { struct strip *strip_info = tty->disc_data; const unsigned char *end = cp + count; - unsigned long flags; if (!strip_info || strip_info->magic != STRIP_MAGIC || !netif_running(strip_info->dev)) return; - spin_lock_irqsave(&strip_lock, flags); + spin_lock_bh(&strip_lock); #if 0 { struct timeval tv; @@ -2341,7 +2335,7 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp, } cp++; } - spin_unlock_irqrestore(&strip_lock, flags); + spin_unlock_bh(&strip_lock); } @@ -2529,11 +2523,9 @@ static void strip_dev_setup(struct net_device *dev) static void strip_free(struct strip *strip_info) { - unsigned long flags; - - spin_lock_irqsave(&strip_lock, flags); + spin_lock_bh(&strip_lock); list_del_rcu(&strip_info->list); - spin_unlock_irqrestore(&strip_lock, flags); + spin_unlock_bh(&strip_lock); strip_info->magic = 0; @@ -2547,7 +2539,6 @@ static void strip_free(struct strip *strip_info) static struct strip *strip_alloc(void) { struct list_head *n; - unsigned long flags; struct net_device *dev; struct strip *strip_info; @@ -2571,7 +2562,7 @@ static struct strip *strip_alloc(void) strip_info->idle_timer.function = strip_IdleTask; - spin_lock_irqsave(&strip_lock, flags); + spin_lock_bh(&strip_lock); rescan: /* * Search the list to find where to put our new entry @@ -2590,7 +2581,7 @@ static struct strip *strip_alloc(void) sprintf(dev->name, "st%ld", dev->base_addr); list_add_tail_rcu(&strip_info->list, &strip_list); - spin_unlock_irqrestore(&strip_lock, flags); + spin_unlock_bh(&strip_lock); return strip_info; } -- cgit v1.2.3 From 673325951ef440ebace311bd542a9378d1b3025b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 17 Jul 2009 04:47:19 +0000 Subject: Update Andreas Koensgen's email address The kernel has used a stale email address of Andreas for a few years. Signed-off-by: Ralf Baechle Signed-off-by: David S. Miller --- CREDITS | 2 +- Documentation/networking/6pack.txt | 2 +- MAINTAINERS | 2 +- drivers/net/hamradio/6pack.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/hamradio/6pack.c') diff --git a/CREDITS b/CREDITS index 2b88fb37ad50..e76d300e9fe4 100644 --- a/CREDITS +++ b/CREDITS @@ -1856,7 +1856,7 @@ E: rfkoenig@immd4.informatik.uni-erlangen.de D: The Linux Support Team Erlangen N: Andreas Koensgen -E: ajk@iehk.rwth-aachen.de +E: ajk@comnets.uni-bremen.de D: 6pack driver for AX.25 N: Harald Koerfgen diff --git a/Documentation/networking/6pack.txt b/Documentation/networking/6pack.txt index d0777a1200e1..8f339428fdf4 100644 --- a/Documentation/networking/6pack.txt +++ b/Documentation/networking/6pack.txt @@ -1,7 +1,7 @@ This is the 6pack-mini-HOWTO, written by Andreas Könsgen DG3KQ -Internet: ajk@iehk.rwth-aachen.de +Internet: ajk@comnets.uni-bremen.de AMPR-net: dg3kq@db0pra.ampr.org AX.25: dg3kq@db0ach.#nrw.deu.eu diff --git a/MAINTAINERS b/MAINTAINERS index 0bd82fa6d2f5..6c6bb95acb15 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -150,7 +150,7 @@ F: drivers/scsi/53c700* 6PACK NETWORK DRIVER FOR AX.25 P: Andreas Koensgen -M: ajk@iehk.rwth-aachen.de +M: ajk@comnets.uni-bremen.de L: linux-hams@vger.kernel.org S: Maintained F: drivers/net/hamradio/6pack.c diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 155160052c8b..981ab530e9ac 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -3,7 +3,7 @@ * devices like TTY. It interfaces between a raw TTY and the * kernel's AX.25 protocol layers. * - * Authors: Andreas Könsgen + * Authors: Andreas Könsgen * Ralf Baechle DL5RB * * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by -- cgit v1.2.3