in most_usb.c [392:440]
static void hdm_read_completion(struct urb *urb)
{
struct mbo *mbo = urb->context;
struct most_dev *mdev = to_mdev(mbo->ifp);
unsigned int channel = mbo->hdm_channel_id;
struct device *dev = &mdev->usb_device->dev;
spinlock_t *lock = mdev->channel_lock + channel;
unsigned long flags;
spin_lock_irqsave(lock, flags);
mbo->processed_length = 0;
mbo->status = MBO_E_INVAL;
if (likely(mdev->is_channel_healthy[channel])) {
switch (urb->status) {
case 0:
case -ESHUTDOWN:
mbo->processed_length = urb->actual_length;
mbo->status = MBO_SUCCESS;
if (mdev->padding_active[channel] &&
hdm_remove_padding(mdev, channel, mbo)) {
mbo->processed_length = 0;
mbo->status = MBO_E_INVAL;
}
break;
case -EPIPE:
dev_warn(dev, "Broken pipe on ep%02x\n",
mdev->ep_address[channel]);
mdev->is_channel_healthy[channel] = false;
mdev->clear_work[channel].pipe = urb->pipe;
schedule_work(&mdev->clear_work[channel].ws);
break;
case -ENODEV:
case -EPROTO:
mbo->status = MBO_E_CLOSE;
break;
case -EOVERFLOW:
dev_warn(dev, "Babble on ep%02x\n",
mdev->ep_address[channel]);
break;
}
}
spin_unlock_irqrestore(lock, flags);
if (likely(mbo->complete))
mbo->complete(mbo);
usb_free_urb(urb);
}