static void data_bridge_write_cb(struct urb *urb) { struct sk_buff *skb = urb->context; struct timestamp_info *info = (struct timestamp_info *)skb->cb; struct data_bridge *dev = info->dev; struct bridge *brdg = dev->brdg; int pending; pr_debug("%s: dev:%p\n", __func__, dev); switch (urb->status) { case 0: /*success*/ dev->to_modem++; dev->tx_num_of_bytes += skb->len; dbg_timestamp("UL", skb); break; case -EPROTO: dev->err = -EPROTO; break; case -EPIPE: set_bit(TX_HALT, &dev->flags); dev_err(&dev->intf->dev, "%s: epout halted\n", __func__); schedule_work(&dev->kevent); /* FALLTHROUGH */ case -ESHUTDOWN: case -ENOENT: /* suspended */ case -ECONNRESET: /* unplug */ case -EOVERFLOW: /*babble error*/ /* FALLTHROUGH */ default: pr_debug_ratelimited("%s: non zero urb status = %d\n", __func__, urb->status); } usb_free_urb(urb); dev_kfree_skb_any(skb); pending = atomic_dec_return(&dev->pending_txurbs); /*flow ctrl*/ if (brdg && fctrl_support && pending <= fctrl_dis_thld && test_and_clear_bit(TX_THROTTLED, &brdg->flags)) { pr_debug_ratelimited("%s: disable flow ctrl: pend urbs:%u\n", __func__, pending); dev->tx_unthrottled_cnt++; if (brdg->ops.unthrottle_tx) brdg->ops.unthrottle_tx(brdg->ctx); } /* if we are here after device disconnect * usb_unbind_interface() takes care of * residual pm_autopm_get_interface_* calls */ if (urb->dev->state != USB_STATE_NOTATTACHED) usb_autopm_put_interface_async(dev->intf); }
static void data_bridge_write_cb(struct urb *urb) { struct sk_buff *skb = urb->context; struct timestamp_info *info = (struct timestamp_info *)skb->cb; struct data_bridge *dev = info->dev; struct bridge *brdg = dev->brdg; int pending; pr_debug("%s: dev:%p\n", __func__, dev); switch (urb->status) { case 0: dbg_timestamp("UL", skb); break; case -EPROTO: dev->err = -EPROTO; break; case -EPIPE: set_bit(TX_HALT, &dev->flags); dev_err(&dev->intf->dev, "%s: epout halted\n", __func__); schedule_work(&dev->kevent); case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: case -EOVERFLOW: default: pr_debug_ratelimited("%s: non zero urb status = %d\n", __func__, urb->status); } usb_free_urb(urb); dev_kfree_skb_any(skb); pending = atomic_dec_return(&dev->pending_txurbs); if (brdg && fctrl_support && pending <= fctrl_dis_thld && test_and_clear_bit(TX_THROTTLED, &brdg->flags)) { pr_debug_ratelimited("%s: disable flow ctrl: pend urbs:%u\n", __func__, pending); dev->tx_unthrottled_cnt++; if (brdg->ops.unthrottle_tx) brdg->ops.unthrottle_tx(brdg->ctx); } if (urb->dev->state != USB_STATE_NOTATTACHED) usb_autopm_put_interface_async(dev->intf); }