From 29b2c49152786beae6d12988ce250b8e852c7f34 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Sat, 19 Feb 2011 15:33:17 -0500 Subject: [PATCH 1/3] USB: gadget: f_mtp: dequeue request on error in mtp_read In mtp_read(), if wait_event_interruptible() returns an error, we need to remove the request from the EP queue. Else, on the next call to mtp_read(), we will attempt to enqueue the request again, potentially corrupting the queue. This is what happens with musb_gadget_queue(), which does not check for duplicate requests. Based on a similar change to f_adb.c Signed-off-by: Mike Lockwood --- drivers/usb/gadget/f_mtp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c index 8128b203e76f..92dd89b340bc 100644 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -504,6 +504,7 @@ static ssize_t mtp_read(struct file *fp, char __user *buf, ret = wait_event_interruptible(dev->read_wq, dev->rx_done); if (ret < 0) { r = ret; + usb_ep_dequeue(dev->ep_out, req); goto done; } if (dev->state == STATE_BUSY) { From 25a87f387fe0421153a528b7dc70b96bea4842cd Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Wed, 9 Mar 2011 16:52:08 -0800 Subject: [PATCH 2/3] net: wireless: bcm4329: Disable wake irq at driver stop Previously at driver stop interrupts were not disabled and might cause never-ending waking up Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/bcm4329/bcmsdh_linux.c | 14 ++++++++++++++ drivers/net/wireless/bcm4329/dhd_sdio.c | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/bcm4329/bcmsdh_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_linux.c index 1e33555b0531..94f19a1c46a4 100644 --- a/drivers/net/wireless/bcm4329/bcmsdh_linux.c +++ b/drivers/net/wireless/bcm4329/bcmsdh_linux.c @@ -643,6 +643,20 @@ int bcmsdh_register_oob_intr(void * dhdp) return 0; } +void bcmsdh_set_irq(int flag) +{ + if (sdhcinfo->oob_irq_registered) { + SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag)); + if (flag) { + enable_irq(sdhcinfo->oob_irq); + enable_irq_wake(sdhcinfo->oob_irq); + } else { + disable_irq_wake(sdhcinfo->oob_irq); + disable_irq(sdhcinfo->oob_irq); + } + } +} + void bcmsdh_unregister_oob_intr(void) { SDLX_MSG(("%s: Enter\n", __FUNCTION__)); diff --git a/drivers/net/wireless/bcm4329/dhd_sdio.c b/drivers/net/wireless/bcm4329/dhd_sdio.c index f9b9eceb91c7..1380dd389cf6 100644 --- a/drivers/net/wireless/bcm4329/dhd_sdio.c +++ b/drivers/net/wireless/bcm4329/dhd_sdio.c @@ -146,6 +146,8 @@ DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); +extern void bcmsdh_set_irq(int flag); + #ifdef DHD_DEBUG /* Device console log buffer state */ typedef struct dhd_console { @@ -5749,7 +5751,9 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) /* Expect app to have torn down any connection before calling */ /* Stop the bus, disable F2 */ dhd_bus_stop(bus, FALSE); - +#if defined(OOB_INTR_ONLY) + bcmsdh_set_irq(FALSE); +#endif /* defined(OOB_INTR_ONLY) */ /* Clean tx/rx buffer pointers, detach from the dongle */ dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE); @@ -5785,6 +5789,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE); if (bcmerror == BCME_OK) { #if defined(OOB_INTR_ONLY) + bcmsdh_set_irq(TRUE); dhd_enable_oob_intr(bus, TRUE); #endif /* defined(OOB_INTR_ONLY) */ bus->dhd->dongle_reset = FALSE; From 5c58e03b81e1ac1231f1ae68e4611c31f428f2f9 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 10 Mar 2011 10:18:39 -0800 Subject: [PATCH 3/3] net: wireless: bcm4329: Allocate skb with GFP_KERNEL flag if possible Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/bcm4329/linux_osl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/bcm4329/linux_osl.c b/drivers/net/wireless/bcm4329/linux_osl.c index d00bd1ca291b..3a026eed516e 100644 --- a/drivers/net/wireless/bcm4329/linux_osl.c +++ b/drivers/net/wireless/bcm4329/linux_osl.c @@ -246,8 +246,10 @@ void* osl_pktget(osl_t *osh, uint len) { struct sk_buff *skb; + gfp_t flags; - if ((skb = dev_alloc_skb(len))) { + flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; + if ((skb = __dev_alloc_skb(len, flags))) { skb_put(skb, len); skb->priority = 0;