drivers/media/usb/dvb-usb-v2/usb_urb.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/dvb-usb-v2/usb_urb.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/dvb-usb-v2/usb_urb.c
Extension
.c
Size
9226 bytes
Lines
354
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret) {
			dev_err(&stream->udev->dev,
					"%s: could not submit urb no. %d - get them all back\n",
					KBUILD_MODNAME, i);
			usb_urb_killv2(stream);
			return ret;
		}
		stream->urbs_submitted++;
	}
	return 0;
}

static int usb_urb_free_urbs(struct usb_data_stream *stream)
{
	int i;

	usb_urb_killv2(stream);

	for (i = stream->urbs_initialized - 1; i >= 0; i--) {
		if (stream->urb_list[i]) {
			dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
					__func__, i);
			/* free the URBs */
			usb_free_urb(stream->urb_list[i]);
		}
	}
	stream->urbs_initialized = 0;

	return 0;
}

static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
{
	int i, j;

	/* allocate the URBs */
	for (i = 0; i < stream->props.count; i++) {
		dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
		stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
		if (!stream->urb_list[i]) {
			dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
			for (j = 0; j < i; j++)
				usb_free_urb(stream->urb_list[j]);
			return -ENOMEM;
		}
		usb_fill_bulk_urb(stream->urb_list[i],
				stream->udev,
				usb_rcvbulkpipe(stream->udev,
						stream->props.endpoint),
				stream->buf_list[i],
				stream->props.u.bulk.buffersize,
				usb_urb_complete, stream);

		stream->urbs_initialized++;
	}
	return 0;
}

static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
{
	int i, j;

	/* allocate the URBs */
	for (i = 0; i < stream->props.count; i++) {
		struct urb *urb;
		int frame_offset = 0;
		dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
		stream->urb_list[i] = usb_alloc_urb(
				stream->props.u.isoc.framesperurb, GFP_ATOMIC);
		if (!stream->urb_list[i]) {
			dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
			for (j = 0; j < i; j++)
				usb_free_urb(stream->urb_list[j]);
			return -ENOMEM;
		}

		urb = stream->urb_list[i];

		urb->dev = stream->udev;
		urb->context = stream;
		urb->complete = usb_urb_complete;
		urb->pipe = usb_rcvisocpipe(stream->udev,
				stream->props.endpoint);
		urb->transfer_flags = URB_ISO_ASAP;
		urb->interval = stream->props.u.isoc.interval;
		urb->number_of_packets = stream->props.u.isoc.framesperurb;
		urb->transfer_buffer_length = stream->props.u.isoc.framesize *
				stream->props.u.isoc.framesperurb;
		urb->transfer_buffer = stream->buf_list[i];

Annotation

Implementation Notes