⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flexcop-usb.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	int l;	deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length);	if (fc_usb->tmp_buffer_length > 0) {		memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length);		fc_usb->tmp_buffer_length += buffer_length;		b = fc_usb->tmp_buffer;		l = fc_usb->tmp_buffer_length;	} else {		b=buffer;		l=buffer_length;	}	while (l >= 190) {		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 %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) );					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]);		}	if (fc_usb->iso_buffer != NULL)		pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr);}static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb){	u16 frame_size = fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize;	int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;	int buffer_offset = 0;	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);	fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr);	if (fc_usb->iso_buffer == NULL)		return -ENOMEM;	memset(fc_usb->iso_buffer, 0, bufsize);	fc_usb->buffer_size = bufsize;	/* creating iso urbs */	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)		if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {			ret = -ENOMEM;			goto urb_error;		}	/* initialising and submitting iso urbs */	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {		int frame_offset = 0;		struct urb *urb = fc_usb->iso_urb[i];		deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);		urb->dev = fc_usb->udev;		urb->context = fc_usb;		urb->complete = flexcop_usb_urb_complete;		urb->pipe = B2C2_USB_DATA_PIPE;		urb->transfer_flags = URB_ISO_ASAP;		urb->interval = 1;		urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;		urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;		urb->transfer_buffer = fc_usb->iso_buffer + buffer_offset;		buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;		for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {			deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);			urb->iso_frame_desc[j].offset = frame_offset;			urb->iso_frame_desc[j].length = frame_size;			frame_offset += frame_size;		}		if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {			err("submitting urb %d failed with %d.",i,ret);			goto urb_error;		}		deb_ts("submitted urb no. %d.\n",i);	}/* SRAM */	flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET |			FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB);	flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS);	flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1);	return 0;urb_error:	flexcop_usb_transfer_exit(fc_usb);	return ret;}static int flexcop_usb_init(struct flexcop_usb *fc_usb){	/* use the alternate setting with the larges buffer */	usb_set_interface(fc_usb->udev,0,1);	switch (fc_usb->udev->speed) {		case USB_SPEED_LOW:			err("cannot handle USB speed because it is to sLOW.");			return -ENODEV;			break;		case USB_SPEED_FULL:			info("running at FULL speed.");			break;		case USB_SPEED_HIGH:			info("running at HIGH speed.");			break;		case USB_SPEED_UNKNOWN: /* fall through */		default:			err("cannot handle USB speed because it is unkown.");			return -ENODEV;	}	usb_set_intfdata(fc_usb->uintf, fc_usb);	return 0;}static void flexcop_usb_exit(struct flexcop_usb *fc_usb){	usb_set_intfdata(fc_usb->uintf, NULL);}static int flexcop_usb_probe(struct usb_interface *intf,		const struct usb_device_id *id){	struct usb_device *udev = interface_to_usbdev(intf);	struct flexcop_usb *fc_usb = NULL;	struct flexcop_device *fc = NULL;	int ret;	if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {		err("out of memory\n");		return -ENOMEM;	}/* general flexcop init */	fc_usb = fc->bus_specific;	fc_usb->fc_dev = fc;	fc->read_ibi_reg  = flexcop_usb_read_ibi_reg;	fc->write_ibi_reg = flexcop_usb_write_ibi_reg;	fc->i2c_request = flexcop_usb_i2c_request;	fc->get_mac_addr = flexcop_usb_get_mac_addr;	fc->stream_control = flexcop_usb_stream_control;	fc->pid_filtering = 1;	fc->bus_type = FC_USB;	fc->dev = &udev->dev;	fc->owner = THIS_MODULE;/* bus specific part */	fc_usb->udev = udev;	fc_usb->uintf = intf;	if ((ret = flexcop_usb_init(fc_usb)) != 0)		goto err_kfree;/* init flexcop */	if ((ret = flexcop_device_initialize(fc)) != 0)		goto err_usb_exit;/* xfer init */	if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)		goto err_fc_exit;	info("%s successfully initialized and connected.",DRIVER_NAME);	return 0;err_fc_exit:	flexcop_device_exit(fc);err_usb_exit:	flexcop_usb_exit(fc_usb);err_kfree:	flexcop_device_kfree(fc);	return ret;}static void flexcop_usb_disconnect(struct usb_interface *intf){	struct flexcop_usb *fc_usb = usb_get_intfdata(intf);	flexcop_usb_transfer_exit(fc_usb);	flexcop_device_exit(fc_usb->fc_dev);	flexcop_usb_exit(fc_usb);	flexcop_device_kfree(fc_usb->fc_dev);	info("%s successfully deinitialized and disconnected.",DRIVER_NAME);}static struct usb_device_id flexcop_usb_table [] = {	    { USB_DEVICE(0x0af7, 0x0101) },	    { }};MODULE_DEVICE_TABLE (usb, flexcop_usb_table);/* usb specific object needed to register this driver with the usb subsystem */static struct usb_driver flexcop_usb_driver = {	.name		= "b2c2_flexcop_usb",	.probe		= flexcop_usb_probe,	.disconnect = flexcop_usb_disconnect,	.id_table	= flexcop_usb_table,};/* module stuff */static int __init flexcop_usb_module_init(void){	int result;	if ((result = usb_register(&flexcop_usb_driver))) {		err("usb_register failed. (%d)",result);		return result;	}	return 0;}static void __exit flexcop_usb_module_exit(void){	/* deregister this driver from the USB subsystem */	usb_deregister(&flexcop_usb_driver);}module_init(flexcop_usb_module_init);module_exit(flexcop_usb_module_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_NAME);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -