drivers/media/usb/b2c2/flexcop-usb.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/b2c2/flexcop-usb.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/b2c2/flexcop-usb.c
Extension
.c
Size
17014 bytes
Lines
638
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 (*b == 0xff) {
			switch (*(b+1) & 0x03) {
			case 0x01: /* media packet */
				if (*(b+2) == 0x47)
					flexcop_pass_dmx_packets(
							fc_usb->fc_dev, b+2, 1);
				else
					deb_ts("not ts packet %*ph\n", 4, b+2);
				b += 190;
				l -= 190;
				break;
			default:
				deb_ts("wrong packet type\n");
				l = 0;
				break;
			}
		} else {
			deb_ts("wrong header\n");
			l = 0;
		}
	}

	if (l > 0)
		memcpy(fc_usb->tmp_buffer, b, l);
	fc_usb->tmp_buffer_length = l;
}

static void flexcop_usb_urb_complete(struct urb *urb)
{
	struct flexcop_usb *fc_usb = urb->context;
	int i;

	if (urb->actual_length > 0)
		deb_ts("urb completed, bufsize: %d actlen; %d\n",
			urb->transfer_buffer_length, urb->actual_length);

	for (i = 0; i < urb->number_of_packets; i++) {
		if (urb->iso_frame_desc[i].status < 0) {
			err("iso frame descriptor %d has an error: %d\n", i,
				urb->iso_frame_desc[i].status);
		} else
			if (urb->iso_frame_desc[i].actual_length > 0) {
				deb_ts("passed %d bytes to the demux\n",
					urb->iso_frame_desc[i].actual_length);

				flexcop_usb_process_frame(fc_usb,
					urb->transfer_buffer +
						urb->iso_frame_desc[i].offset,
					urb->iso_frame_desc[i].actual_length);
			}
		urb->iso_frame_desc[i].status = 0;
		urb->iso_frame_desc[i].actual_length = 0;
	}
	usb_submit_urb(urb, GFP_ATOMIC);
}

static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff)
{
	/* submit/kill iso packets */
	return 0;
}

static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
{
	int i;
	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
		if (fc_usb->iso_urb[i] != NULL) {
			deb_ts("unlinking/killing urb no. %d\n", i);
			usb_kill_urb(fc_usb->iso_urb[i]);
			usb_free_urb(fc_usb->iso_urb[i]);
		}

	usb_free_coherent(fc_usb->udev, fc_usb->buffer_size,
			  fc_usb->iso_buffer, fc_usb->dma_addr);

}

static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
{
	struct usb_host_interface *alt = fc_usb->uintf->cur_altsetting;
	u16 frame_size;
	int bufsize, i, j, ret;
	int buffer_offset = 0;

	frame_size = usb_endpoint_maxp(&alt->endpoint[0].desc);
	bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size;

	deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
	       B2C2_USB_NUM_ISO_URB,
			B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize);

Annotation

Implementation Notes