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

📄 speedtch.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		dbg ("udsl_atm_open: no memory for vcc_data!");		up (&instance->serialize);		return -ENOMEM;	}	memset (new, 0, sizeof (struct udsl_vcc_data));	new->vcc = vcc;	new->vpi = vpi;	new->vci = vci;	/* udsl_extract_cells requires at least one cell */	max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;	if (!(new->sarb = alloc_skb (max_pdu, GFP_KERNEL))) {		dbg ("udsl_atm_open: no memory for SAR buffer!");	        kfree (new);		up (&instance->serialize);		return -ENOMEM;	}	vcc->dev_data = new;	tasklet_disable (&instance->receive_tasklet);	list_add (&new->list, &instance->vcc_list);	tasklet_enable (&instance->receive_tasklet);	set_bit (ATM_VF_ADDR, &vcc->flags);	set_bit (ATM_VF_PARTIAL, &vcc->flags);	set_bit (ATM_VF_READY, &vcc->flags);	up (&instance->serialize);	tasklet_schedule (&instance->receive_tasklet);	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, max_pdu);	return 0;}static void udsl_atm_close (struct atm_vcc *vcc){	struct udsl_instance_data *instance = vcc->dev->dev_data;	struct udsl_vcc_data *vcc_data = vcc->dev_data;	dbg ("udsl_atm_close called");	if (!instance || !vcc_data) {		dbg ("udsl_atm_close: NULL data!");		return;	}	dbg ("udsl_atm_close: deallocating vcc 0x%p with vpi %d vci %d", vcc_data, vcc_data->vpi, vcc_data->vci);	udsl_cancel_send (instance, vcc);	down (&instance->serialize); /* vs self, udsl_atm_open */	tasklet_disable (&instance->receive_tasklet);	list_del (&vcc_data->list);	tasklet_enable (&instance->receive_tasklet);	kfree_skb (vcc_data->sarb);	vcc_data->sarb = NULL;	kfree (vcc_data);	vcc->dev_data = NULL;	vcc->vpi = ATM_VPI_UNSPEC;	vcc->vci = ATM_VCI_UNSPEC;	clear_bit (ATM_VF_READY, &vcc->flags);	clear_bit (ATM_VF_PARTIAL, &vcc->flags);	clear_bit (ATM_VF_ADDR, &vcc->flags);	up (&instance->serialize);	dbg ("udsl_atm_close successful");}static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void __user *arg){	switch (cmd) {	case ATM_QUERYLOOP:		return put_user (ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;	default:		return -ENOIOCTLCMD;	}}/************  USB  ************/static int udsl_set_alternate (struct udsl_instance_data *instance){	down (&instance->serialize); /* vs self */	if (!instance->firmware_loaded) {		int ret;		if ((ret = usb_set_interface (instance->usb_dev, 1, 1)) < 0) {			dbg ("udsl_set_alternate: usb_set_interface returned %d!", ret);			up (&instance->serialize);			return ret;		}		instance->firmware_loaded = 1;	}	up (&instance->serialize);	tasklet_schedule (&instance->receive_tasklet);	return 0;}static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data){	struct udsl_instance_data *instance = usb_get_intfdata (intf);	dbg ("udsl_usb_ioctl entered");	if (!instance) {		dbg ("udsl_usb_ioctl: NULL instance!");		return -ENODEV;	}	switch (code) {	case UDSL_IOCTL_LINE_UP:		instance->atm_dev->signal = ATM_PHY_SIG_FOUND;		return udsl_set_alternate (instance);	case UDSL_IOCTL_LINE_DOWN:		instance->atm_dev->signal = ATM_PHY_SIG_LOST;		return 0;	default:		return -ENOTTY;	}}static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id){	struct usb_device *dev = interface_to_usbdev(intf);	int ifnum = intf->altsetting->desc.bInterfaceNumber;	struct udsl_instance_data *instance;	unsigned char mac_str [13];	int i, length;	char *buf;	dbg ("udsl_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d",	     dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))		return -ENODEV;	dbg ("udsl_usb_probe: device accepted");	/* instance init */	if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) {		dbg ("udsl_usb_probe: no memory for instance data!");		return -ENOMEM;	}	memset (instance, 0, sizeof (struct udsl_instance_data));	init_MUTEX (&instance->serialize);	instance->usb_dev = dev;	INIT_LIST_HEAD (&instance->vcc_list);	spin_lock_init (&instance->receive_lock);	INIT_LIST_HEAD (&instance->spare_receivers);	INIT_LIST_HEAD (&instance->filled_receive_buffers);	tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance);	INIT_LIST_HEAD (&instance->spare_receive_buffers);	skb_queue_head_init (&instance->sndqueue);	spin_lock_init (&instance->send_lock);	INIT_LIST_HEAD (&instance->spare_senders);	INIT_LIST_HEAD (&instance->spare_send_buffers);	tasklet_init (&instance->send_tasklet, udsl_process_send, (unsigned long) instance);	INIT_LIST_HEAD (&instance->filled_send_buffers);	/* receive init */	for (i = 0; i < num_rcv_urbs; i++) {		struct udsl_receiver *rcv = &(instance->receivers [i]);		if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {			dbg ("udsl_usb_probe: no memory for receive urb %d!", i);			goto fail;		}		rcv->instance = instance;		list_add (&rcv->list, &instance->spare_receivers);	}	for (i = 0; i < num_rcv_bufs; i++) {		struct udsl_receive_buffer *buf = &(instance->receive_buffers [i]);		if (!(buf->base = kmalloc (rcv_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {			dbg ("udsl_usb_probe: no memory for receive buffer %d!", i);			goto fail;		}		list_add (&buf->list, &instance->spare_receive_buffers);	}	/* send init */	for (i = 0; i < num_snd_urbs; i++) {		struct udsl_sender *snd = &(instance->senders [i]);		if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {			dbg ("udsl_usb_probe: no memory for send urb %d!", i);			goto fail;		}		snd->instance = instance;		list_add (&snd->list, &instance->spare_senders);	}	for (i = 0; i < num_snd_bufs; i++) {		struct udsl_send_buffer *buf = &(instance->send_buffers [i]);		if (!(buf->base = kmalloc (snd_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {			dbg ("udsl_usb_probe: no memory for send buffer %d!", i);			goto fail;		}		list_add (&buf->list, &instance->spare_send_buffers);	}	/* ATM init */	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, NULL))) {		dbg ("udsl_usb_probe: failed to register ATM device!");		goto fail;	}	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;	/* temp init ATM device, set to 128kbit */	instance->atm_dev->link_rate = 128 * 1000 / 424;	/* set MAC address, it is stored in the serial number */	memset (instance->atm_dev->esi, 0, sizeof (instance->atm_dev->esi));	if (usb_string (dev, dev->descriptor.iSerialNumber, mac_str, sizeof (mac_str)) == 12)		for (i = 0; i < 6; i++)			instance->atm_dev->esi [i] = (hex2int (mac_str [i * 2]) * 16) + (hex2int (mac_str [i * 2 + 1]));	/* device description */	buf = instance->description;	length = sizeof (instance->description);	if ((i = usb_string (dev, dev->descriptor.iProduct, buf, length)) < 0)		goto finish;	buf += i;	length -= i;	i = scnprintf (buf, length, " (");	buf += i;	length -= i;	if (length <= 0 || (i = usb_make_path (dev, buf, length)) < 0)		goto finish;	buf += i;	length -= i;	snprintf (buf, length, ")");finish:	/* ready for ATM callbacks */	wmb ();	instance->atm_dev->dev_data = instance;	usb_set_intfdata (intf, instance);	return 0;fail:	for (i = 0; i < num_snd_bufs; i++)		kfree (instance->send_buffers [i].base);	for (i = 0; i < num_snd_urbs; i++)		usb_free_urb (instance->senders [i].urb);	for (i = 0; i < num_rcv_bufs; i++)		kfree (instance->receive_buffers [i].base);	for (i = 0; i < num_rcv_urbs; i++)		usb_free_urb (instance->receivers [i].urb);	kfree (instance);	return -ENOMEM;}static void udsl_usb_disconnect (struct usb_interface *intf){	struct udsl_instance_data *instance = usb_get_intfdata (intf);	struct list_head *pos;	unsigned int count;	int result, i;	dbg ("udsl_usb_disconnect entered");	usb_set_intfdata (intf, NULL);	if (!instance) {		dbg ("udsl_usb_disconnect: NULL instance!");		return;	}	/* receive finalize */	tasklet_disable (&instance->receive_tasklet);	for (i = 0; i < num_rcv_urbs; i++)		if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d!", i, result);	/* wait for completion handlers to finish */	do {		count = 0;		spin_lock_irq (&instance->receive_lock);		list_for_each (pos, &instance->spare_receivers)			DEBUG_ON (++count > num_rcv_urbs);		spin_unlock_irq (&instance->receive_lock);		dbg ("udsl_usb_disconnect: found %u spare receivers", count);		if (count == num_rcv_urbs)			break;		set_current_state (TASK_RUNNING);		schedule ();	} while (1);	/* no need to take the spinlock */	INIT_LIST_HEAD (&instance->filled_receive_buffers);	INIT_LIST_HEAD (&instance->spare_receive_buffers);	tasklet_enable (&instance->receive_tasklet);	for (i = 0; i < num_rcv_urbs; i++)		usb_free_urb (instance->receivers [i].urb);	for (i = 0; i < num_rcv_bufs; i++)		kfree (instance->receive_buffers [i].base);	/* send finalize */	tasklet_disable (&instance->send_tasklet);	for (i = 0; i < num_snd_urbs; i++)		if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d!", i, result);	/* wait for completion handlers to finish */	do {		count = 0;		spin_lock_irq (&instance->send_lock);		list_for_each (pos, &instance->spare_senders)			DEBUG_ON (++count > num_snd_urbs);		spin_unlock_irq (&instance->send_lock);		dbg ("udsl_usb_disconnect: found %u spare senders", count);		if (count == num_snd_urbs)			break;		set_current_state (TASK_RUNNING);		schedule ();	} while (1);	/* no need to take the spinlock */	INIT_LIST_HEAD (&instance->spare_senders);	INIT_LIST_HEAD (&instance->spare_send_buffers);	instance->current_buffer = NULL;	tasklet_enable (&instance->send_tasklet);	for (i = 0; i < num_snd_urbs; i++)		usb_free_urb (instance->senders [i].urb);	for (i = 0; i < num_snd_bufs; i++)		kfree (instance->send_buffers [i].base);	wmb ();	instance->usb_dev = NULL;	/* ATM finalize */	shutdown_atm_dev (instance->atm_dev); /* frees instance, kills tasklets */}/*************  init  *************/static int __init udsl_usb_init (void){	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);	if (sizeof (struct udsl_control) > sizeof (((struct sk_buff *)0)->cb)) {		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");		return -EIO;	}	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS) || (num_snd_urbs > UDSL_MAX_SND_URBS) ||	    (num_rcv_bufs > UDSL_MAX_RCV_BUFS) || (num_snd_bufs > UDSL_MAX_SND_BUFS) ||	    (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE) || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))		return -EINVAL;	return usb_register (&udsl_usb_driver);}static void __exit udsl_usb_cleanup (void){	dbg ("udsl_usb_cleanup entered");	usb_deregister (&udsl_usb_driver);}module_init (udsl_usb_init);module_exit (udsl_usb_cleanup);MODULE_AUTHOR (DRIVER_AUTHOR);MODULE_DESCRIPTION (DRIVER_DESC);MODULE_LICENSE ("GPL");MODULE_VERSION (DRIVER_VERSION);/**************  debug  **************/#ifdef VERBOSE_DEBUGstatic int udsl_print_packet (const unsigned char *data, int len){	unsigned char buffer [256];	int i = 0, j = 0;	for (i = 0; i < len;) {		buffer [0] = '\0';		sprintf (buffer, "%.3d :", i);		for (j = 0; (j < 16) && (i < len); j++, i++) {			sprintf (buffer, "%s %2.2x", buffer, data [i]);		}		dbg ("%s", buffer);	}	return i;}#endif

⌨️ 快捷键说明

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