lkml.org 
[lkml]   [2006]   [Oct]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 15/19] xirc2ps_cs: Cannot reset card in atomic context
    -stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: Joerg Ahrens <joerg@hydrops.han.de>

    I am using a Xircom CEM33 pcmcia NIC which has occasional hardware problems.
    If the netdev watchdog detects a transmit timeout, do_reset is called which
    msleeps - this is illegal in atomic context.

    This patch schedules the timeout handling as a workqueue item.

    Signed-off-by: Daniel Drake <dsd@gentoo.org>
    Signed-off-by: Jeff Garzik <jeff@garzik.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/net/pcmcia/xirc2ps_cs.c | 18 ++++++++++++++----
    1 file changed, 14 insertions(+), 4 deletions(-)

    --- linux-2.6.17.13.orig/drivers/net/pcmcia/xirc2ps_cs.c
    +++ linux-2.6.17.13/drivers/net/pcmcia/xirc2ps_cs.c
    @@ -345,6 +345,7 @@ typedef struct local_info_t {
    void __iomem *dingo_ccr; /* only used for CEM56 cards */
    unsigned last_ptr_value; /* last packets transmitted value */
    const char *manf_str;
    + struct work_struct tx_timeout_task;
    } local_info_t;

    /****************
    @@ -352,6 +353,7 @@ typedef struct local_info_t {
    */
    static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
    static void do_tx_timeout(struct net_device *dev);
    +static void xirc2ps_tx_timeout_task(void *data);
    static struct net_device_stats *do_get_stats(struct net_device *dev);
    static void set_addresses(struct net_device *dev);
    static void set_multicast_list(struct net_device *dev);
    @@ -589,6 +591,7 @@ xirc2ps_probe(struct pcmcia_device *link
    #ifdef HAVE_TX_TIMEOUT
    dev->tx_timeout = do_tx_timeout;
    dev->watchdog_timeo = TX_TIMEOUT;
    + INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task, dev);
    #endif

    return xirc2ps_config(link);
    @@ -1341,17 +1344,24 @@ xirc2ps_interrupt(int irq, void *dev_id,
    /*====================================================================*/

    static void
    -do_tx_timeout(struct net_device *dev)
    +xirc2ps_tx_timeout_task(void *data)
    {
    - local_info_t *lp = netdev_priv(dev);
    - printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
    - lp->stats.tx_errors++;
    + struct net_device *dev = data;
    /* reset the card */
    do_reset(dev,1);
    dev->trans_start = jiffies;
    netif_wake_queue(dev);
    }

    +static void
    +do_tx_timeout(struct net_device *dev)
    +{
    + local_info_t *lp = netdev_priv(dev);
    + lp->stats.tx_errors++;
    + printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
    + schedule_work(&lp->tx_timeout_task);
    +}
    +
    static int
    do_start_xmit(struct sk_buff *skb, struct net_device *dev)
    {
    --
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-10-10 19:21    [W:0.024 / U:0.792 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site