static void hdm_read_completion()

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);
}