aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/n_gsm.c111
1 files changed, 91 insertions, 20 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 9a13e510daea..a38114b01fea 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -133,6 +133,7 @@ struct gsm_dlci {
133#define DLCI_OPENING 1 /* Sending SABM not seen UA */ 133#define DLCI_OPENING 1 /* Sending SABM not seen UA */
134#define DLCI_OPEN 2 /* SABM/UA complete */ 134#define DLCI_OPEN 2 /* SABM/UA complete */
135#define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */ 135#define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */
136 struct kref ref; /* freed from port or mux close */
136 struct mutex mutex; 137 struct mutex mutex;
137 138
138 /* Link layer */ 139 /* Link layer */
@@ -194,6 +195,7 @@ struct gsm_mux {
194 struct tty_struct *tty; /* The tty our ldisc is bound to */ 195 struct tty_struct *tty; /* The tty our ldisc is bound to */
195 spinlock_t lock; 196 spinlock_t lock;
196 unsigned int num; 197 unsigned int num;
198 struct kref ref;
197 199
198 /* Events on the GSM channel */ 200 /* Events on the GSM channel */
199 wait_queue_head_t event; 201 wait_queue_head_t event;
@@ -1606,6 +1608,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
1606 if (dlci == NULL) 1608 if (dlci == NULL)
1607 return NULL; 1609 return NULL;
1608 spin_lock_init(&dlci->lock); 1610 spin_lock_init(&dlci->lock);
1611 kref_init(&dlci->ref);
1609 mutex_init(&dlci->mutex); 1612 mutex_init(&dlci->mutex);
1610 dlci->fifo = &dlci->_fifo; 1613 dlci->fifo = &dlci->_fifo;
1611 if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) { 1614 if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) {
@@ -1632,26 +1635,52 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
1632} 1635}
1633 1636
1634/** 1637/**
1635 * gsm_dlci_free - release DLCI 1638 * gsm_dlci_free - free DLCI
1639 * @dlci: DLCI to free
1640 *
1641 * Free up a DLCI.
1642 *
1643 * Can sleep.
1644 */
1645static void gsm_dlci_free(struct kref *ref)
1646{
1647 struct gsm_dlci *dlci = container_of(ref, struct gsm_dlci, ref);
1648
1649 del_timer_sync(&dlci->t1);
1650 dlci->gsm->dlci[dlci->addr] = NULL;
1651 kfifo_free(dlci->fifo);
1652 while ((dlci->skb = skb_dequeue(&dlci->skb_list)))
1653 kfree_skb(dlci->skb);
1654 kfree(dlci);
1655}
1656
1657static inline void dlci_get(struct gsm_dlci *dlci)
1658{
1659 kref_get(&dlci->ref);
1660}
1661
1662static inline void dlci_put(struct gsm_dlci *dlci)
1663{
1664 kref_put(&dlci->ref, gsm_dlci_free);
1665}
1666
1667/**
1668 * gsm_dlci_release - release DLCI
1636 * @dlci: DLCI to destroy 1669 * @dlci: DLCI to destroy
1637 * 1670 *
1638 * Free up a DLCI. Currently to keep the lifetime rules sane we only 1671 * Release a DLCI. Actual free is deferred until either
1639 * clean up DLCI objects when the MUX closes rather than as the port 1672 * mux is closed or tty is closed - whichever is last.
1640 * is closed down on both the tty and mux levels.
1641 * 1673 *
1642 * Can sleep. 1674 * Can sleep.
1643 */ 1675 */
1644static void gsm_dlci_free(struct gsm_dlci *dlci) 1676static void gsm_dlci_release(struct gsm_dlci *dlci)
1645{ 1677{
1646 struct tty_struct *tty = tty_port_tty_get(&dlci->port); 1678 struct tty_struct *tty = tty_port_tty_get(&dlci->port);
1647 if (tty) { 1679 if (tty) {
1648 tty_vhangup(tty); 1680 tty_vhangup(tty);
1649 tty_kref_put(tty); 1681 tty_kref_put(tty);
1650 } 1682 }
1651 del_timer_sync(&dlci->t1); 1683 dlci_put(dlci);
1652 dlci->gsm->dlci[dlci->addr] = NULL;
1653 kfifo_free(dlci->fifo);
1654 kfree(dlci);
1655} 1684}
1656 1685
1657/* 1686/*
@@ -1989,7 +2018,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm)
1989 /* Free up any link layer users */ 2018 /* Free up any link layer users */
1990 for (i = 0; i < NUM_DLCI; i++) 2019 for (i = 0; i < NUM_DLCI; i++)
1991 if (gsm->dlci[i]) 2020 if (gsm->dlci[i])
1992 gsm_dlci_free(gsm->dlci[i]); 2021 gsm_dlci_release(gsm->dlci[i]);
1993 /* Now wipe the queues */ 2022 /* Now wipe the queues */
1994 for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) { 2023 for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) {
1995 gsm->tx_head = txq->next; 2024 gsm->tx_head = txq->next;
@@ -2050,8 +2079,7 @@ EXPORT_SYMBOL_GPL(gsm_activate_mux);
2050 * gsm_free_mux - free up a mux 2079 * gsm_free_mux - free up a mux
2051 * @mux: mux to free 2080 * @mux: mux to free
2052 * 2081 *
2053 * Dispose of allocated resources for a dead mux. No refcounting 2082 * Dispose of allocated resources for a dead mux
2054 * at present so the mux must be truly dead.
2055 */ 2083 */
2056void gsm_free_mux(struct gsm_mux *gsm) 2084void gsm_free_mux(struct gsm_mux *gsm)
2057{ 2085{
@@ -2062,6 +2090,28 @@ void gsm_free_mux(struct gsm_mux *gsm)
2062EXPORT_SYMBOL_GPL(gsm_free_mux); 2090EXPORT_SYMBOL_GPL(gsm_free_mux);
2063 2091
2064/** 2092/**
2093 * gsm_free_muxr - free up a mux
2094 * @mux: mux to free
2095 *
2096 * Dispose of allocated resources for a dead mux
2097 */
2098static void gsm_free_muxr(struct kref *ref)
2099{
2100 struct gsm_mux *gsm = container_of(ref, struct gsm_mux, ref);
2101 gsm_free_mux(gsm);
2102}
2103
2104static inline void mux_get(struct gsm_mux *gsm)
2105{
2106 kref_get(&gsm->ref);
2107}
2108
2109static inline void mux_put(struct gsm_mux *gsm)
2110{
2111 kref_put(&gsm->ref, gsm_free_muxr);
2112}
2113
2114/**
2065 * gsm_alloc_mux - allocate a mux 2115 * gsm_alloc_mux - allocate a mux
2066 * 2116 *
2067 * Creates a new mux ready for activation. 2117 * Creates a new mux ready for activation.
@@ -2084,6 +2134,7 @@ struct gsm_mux *gsm_alloc_mux(void)
2084 return NULL; 2134 return NULL;
2085 } 2135 }
2086 spin_lock_init(&gsm->lock); 2136 spin_lock_init(&gsm->lock);
2137 kref_init(&gsm->ref);
2087 2138
2088 gsm->t1 = T1; 2139 gsm->t1 = T1;
2089 gsm->t2 = T2; 2140 gsm->t2 = T2;
@@ -2255,7 +2306,7 @@ static void gsmld_close(struct tty_struct *tty)
2255 2306
2256 gsmld_flush_buffer(tty); 2307 gsmld_flush_buffer(tty);
2257 /* Do other clean up here */ 2308 /* Do other clean up here */
2258 gsm_free_mux(gsm); 2309 mux_put(gsm);
2259} 2310}
2260 2311
2261/** 2312/**
@@ -2554,12 +2605,22 @@ static void net_free(struct kref *ref)
2554 } 2605 }
2555} 2606}
2556 2607
2608static inline void muxnet_get(struct gsm_mux_net *mux_net)
2609{
2610 kref_get(&mux_net->ref);
2611}
2612
2613static inline void muxnet_put(struct gsm_mux_net *mux_net)
2614{
2615 kref_put(&mux_net->ref, net_free);
2616}
2617
2557static int gsm_mux_net_start_xmit(struct sk_buff *skb, 2618static int gsm_mux_net_start_xmit(struct sk_buff *skb,
2558 struct net_device *net) 2619 struct net_device *net)
2559{ 2620{
2560 struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net); 2621 struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
2561 struct gsm_dlci *dlci = mux_net->dlci; 2622 struct gsm_dlci *dlci = mux_net->dlci;
2562 kref_get(&mux_net->ref); 2623 muxnet_get(mux_net);
2563 2624
2564 skb_queue_head(&dlci->skb_list, skb); 2625 skb_queue_head(&dlci->skb_list, skb);
2565 STATS(net).tx_packets++; 2626 STATS(net).tx_packets++;
@@ -2567,7 +2628,7 @@ static int gsm_mux_net_start_xmit(struct sk_buff *skb,
2567 gsm_dlci_data_kick(dlci); 2628 gsm_dlci_data_kick(dlci);
2568 /* And tell the kernel when the last transmit started. */ 2629 /* And tell the kernel when the last transmit started. */
2569 net->trans_start = jiffies; 2630 net->trans_start = jiffies;
2570 kref_put(&mux_net->ref, net_free); 2631 muxnet_put(mux_net);
2571 return NETDEV_TX_OK; 2632 return NETDEV_TX_OK;
2572} 2633}
2573 2634
@@ -2587,14 +2648,14 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,
2587 struct net_device *net = dlci->net; 2648 struct net_device *net = dlci->net;
2588 struct sk_buff *skb; 2649 struct sk_buff *skb;
2589 struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net); 2650 struct gsm_mux_net *mux_net = (struct gsm_mux_net *)netdev_priv(net);
2590 kref_get(&mux_net->ref); 2651 muxnet_get(mux_net);
2591 2652
2592 /* Allocate an sk_buff */ 2653 /* Allocate an sk_buff */
2593 skb = dev_alloc_skb(size + NET_IP_ALIGN); 2654 skb = dev_alloc_skb(size + NET_IP_ALIGN);
2594 if (!skb) { 2655 if (!skb) {
2595 /* We got no receive buffer. */ 2656 /* We got no receive buffer. */
2596 STATS(net).rx_dropped++; 2657 STATS(net).rx_dropped++;
2597 kref_put(&mux_net->ref, net_free); 2658 muxnet_put(mux_net);
2598 return; 2659 return;
2599 } 2660 }
2600 skb_reserve(skb, NET_IP_ALIGN); 2661 skb_reserve(skb, NET_IP_ALIGN);
@@ -2609,7 +2670,7 @@ static void gsm_mux_rx_netchar(struct gsm_dlci *dlci,
2609 /* update out statistics */ 2670 /* update out statistics */
2610 STATS(net).rx_packets++; 2671 STATS(net).rx_packets++;
2611 STATS(net).rx_bytes += size; 2672 STATS(net).rx_bytes += size;
2612 kref_put(&mux_net->ref, net_free); 2673 muxnet_put(mux_net);
2613 return; 2674 return;
2614} 2675}
2615 2676
@@ -2652,7 +2713,7 @@ static void gsm_destroy_network(struct gsm_dlci *dlci)
2652 if (!dlci->net) 2713 if (!dlci->net)
2653 return; 2714 return;
2654 mux_net = (struct gsm_mux_net *)netdev_priv(dlci->net); 2715 mux_net = (struct gsm_mux_net *)netdev_priv(dlci->net);
2655 kref_put(&mux_net->ref, net_free); 2716 muxnet_put(mux_net);
2656} 2717}
2657 2718
2658 2719
@@ -2814,6 +2875,9 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
2814 port = &dlci->port; 2875 port = &dlci->port;
2815 port->count++; 2876 port->count++;
2816 tty->driver_data = dlci; 2877 tty->driver_data = dlci;
2878 dlci_get(dlci);
2879 dlci_get(dlci->gsm->dlci[0]);
2880 mux_get(dlci->gsm);
2817 tty_port_tty_set(port, tty); 2881 tty_port_tty_set(port, tty);
2818 2882
2819 dlci->modem_rx = 0; 2883 dlci->modem_rx = 0;
@@ -2829,16 +2893,23 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
2829static void gsmtty_close(struct tty_struct *tty, struct file *filp) 2893static void gsmtty_close(struct tty_struct *tty, struct file *filp)
2830{ 2894{
2831 struct gsm_dlci *dlci = tty->driver_data; 2895 struct gsm_dlci *dlci = tty->driver_data;
2896 struct gsm_mux *gsm;
2897
2832 if (dlci == NULL) 2898 if (dlci == NULL)
2833 return; 2899 return;
2834 mutex_lock(&dlci->mutex); 2900 mutex_lock(&dlci->mutex);
2835 gsm_destroy_network(dlci); 2901 gsm_destroy_network(dlci);
2836 mutex_unlock(&dlci->mutex); 2902 mutex_unlock(&dlci->mutex);
2903 gsm = dlci->gsm;
2837 if (tty_port_close_start(&dlci->port, tty, filp) == 0) 2904 if (tty_port_close_start(&dlci->port, tty, filp) == 0)
2838 return; 2905 goto out;
2839 gsm_dlci_begin_close(dlci); 2906 gsm_dlci_begin_close(dlci);
2840 tty_port_close_end(&dlci->port, tty); 2907 tty_port_close_end(&dlci->port, tty);
2841 tty_port_tty_set(&dlci->port, NULL); 2908 tty_port_tty_set(&dlci->port, NULL);
2909out:
2910 dlci_put(dlci);
2911 dlci_put(gsm->dlci[0]);
2912 mux_put(gsm);
2842} 2913}
2843 2914
2844static void gsmtty_hangup(struct tty_struct *tty) 2915static void gsmtty_hangup(struct tty_struct *tty)