diff options
Diffstat (limited to 'xpp/xpp_usb.c')
-rw-r--r-- | xpp/xpp_usb.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/xpp/xpp_usb.c b/xpp/xpp_usb.c index 1a62974..89571c3 100644 --- a/xpp/xpp_usb.c +++ b/xpp/xpp_usb.c @@ -292,7 +292,18 @@ static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) if(!xusb->present) { NOTICE("tried to send packets to non-exitant USB device. Ignored\n"); ret = -ENODEV; - goto out; + goto freepack; + } + /* + * If something really bad happend, do not overflow the USB stack + */ + if(atomic_read(&xusb->pending_writes) > MAX_PENDING_WRITES) { + static int rate_limit; + + if((rate_limit++ % 1000) < 10) + ERR("%s: %s: more than %d pending writes. Dropping.\n", __FUNCTION__, xbus->busname, MAX_PENDING_WRITES); + ret = -ENODEV; + goto freepack; } size = PACKET_LEN(pack); xusb_ep = &xusb->endpoints[XUSB_SEND]; @@ -300,7 +311,7 @@ static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) if (!urb) { ERR("No free urbs available\n"); ret = -ENOMEM; - goto out; + goto freepack; } packet_debug("USB_PACKET_SEND", xusb, pack); @@ -309,25 +320,21 @@ static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) ret = usb_submit_urb(urb, GFP_ATOMIC); if(ret < 0) { - ERR("%s: failed submit_urb: %d\n", __FUNCTION__, ret); + static int rate_limit; + + if((rate_limit++ % 1000) < 5) + ERR("%s: failed submit_urb: %d\n", __FUNCTION__, ret); xpp_urb_delete(urb); ret = -EBADF; - goto out; + goto freepack; } atomic_inc(&xusb->pending_writes); - if(atomic_read(&xusb->pending_writes) > MAX_PENDING_WRITES) { - static int rate_limit; - - if((rate_limit++ % 1000) < 10) - ERR("%s: %s: more than %d pending writes. Dropping.\n", __FUNCTION__, xbus->busname, MAX_PENDING_WRITES); - ret = -ENODEV; - } if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_WRITE)) XUSB_COUNTER(xusb, PCM_WRITES)++; -out: +freepack: + xbus->ops->packet_free(xbus, pack); // FIXME: eventually will be done in the urb callback if(ret < 0) XUSB_COUNTER(xusb, TX_ERRORS)++; - xbus->ops->packet_free(xbus, pack); // FIXME: eventually will be done in the urb callback return ret; } @@ -705,8 +712,8 @@ static void xusb_disconnect(struct usb_interface *interface) #ifdef CONFIG_PROC_FS if(xbus->proc_xbus_dir) { + DBG("Remove proc_entry: " PROC_USBXPP_SUMMARY "\n"); remove_proc_entry(PROC_USBXPP_SUMMARY, xbus->proc_xbus_dir); - xbus->proc_xbus_dir = NULL; } #endif xusb->present = 0; |