drivers/media/usb/dvb-usb/usb-urb.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/dvb-usb/usb-urb.c
Extension
.c
Size
7109 bytes
Lines
256
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 = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) {
			err("could not submit URB no. %d - get them all back",i);
			usb_urb_kill(stream);
			return ret;
		}
		stream->urbs_submitted++;
	}
	return 0;
}

static int usb_free_stream_buffers(struct usb_data_stream *stream)
{
	if (stream->state & USB_STATE_URB_BUF) {
		while (stream->buf_num) {
			stream->buf_num--;
			deb_mem("freeing buffer %d\n",stream->buf_num);
			usb_free_coherent(stream->udev, stream->buf_size,
					  stream->buf_list[stream->buf_num],
					  stream->dma_addr[stream->buf_num]);
		}
	}

	stream->state &= ~USB_STATE_URB_BUF;

	return 0;
}

static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size)
{
	stream->buf_num = 0;
	stream->buf_size = size;

	deb_mem("all in all I will use %lu bytes for streaming\n",num*size);

	for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
		deb_mem("allocating buffer %d\n",stream->buf_num);
		if (( stream->buf_list[stream->buf_num] =
					usb_alloc_coherent(stream->udev, size, GFP_KERNEL,
					&stream->dma_addr[stream->buf_num]) ) == NULL) {
			deb_mem("not enough memory for urb-buffer allocation.\n");
			usb_free_stream_buffers(stream);
			return -ENOMEM;
		}
		deb_mem("buffer %d: %p (dma: %Lu)\n",
			stream->buf_num,
stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]);
		memset(stream->buf_list[stream->buf_num],0,size);
		stream->state |= USB_STATE_URB_BUF;
	}
	deb_mem("allocation successful\n");

	return 0;
}

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

	if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
					stream->props.u.bulk.buffersize)) < 0)
		return i;

	/* allocate the URBs */
	for (i = 0; i < stream->props.count; i++) {
		stream->urb_list[i] = usb_alloc_urb(0, GFP_KERNEL);
		if (!stream->urb_list[i]) {
			deb_mem("not enough memory for urb_alloc_urb!.\n");
			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->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
		stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
		stream->urbs_initialized++;
	}
	return 0;
}

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

	if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
					stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0)

Annotation

Implementation Notes