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

📄 net-fd.c

📁 Linux2.4.20针对三星公司的s3c2440内核基础上的一些设备驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	int port = 0;		// XXX compound device	struct usb_net_private *net_private;	struct urb *urb;	//dbg_tx(5,"skb: %p", skb);	// XXX XXX	// return -EINVAL;	net_private = &net_private_array[interface];	if (!net_private->device) {		dbg_tx (0, "net_private NULL");		return -EUNATCH;	}#if 0#ifdef CONFIG_ARCH_SA1100	// compensate for SA-1110 DMA setup problems by sending three dummy urbs before	// any real traffic, these will be dropped at the far end	if (net_private->first) {		int i;		dbg_tx (1, "sending three init URBS");		for (i = 0; i < 3; i++) {			if ((urb =			     usbd_alloc_urb (net_private->device,					     (net_private->device->function_instance_array + port),					     CONFIG_USBD_NET_IN_ENDPOINT | IN, 200))) {				memset (urb->buffer, i, 200);				urb->actual_length = 100;				usbd_send_urb (urb);			}		}		net_private->first = 0;	}#endif#endif	if (!	    (urb =	     usbd_alloc_urb (net_private->device,			     (net_private->device->function_instance_array + port),			     CONFIG_USBD_NET_IN_ENDPOINT | IN, skb->len + 5 + in_pkt_sz))) {		dbg_tx (0, "urb alloc failed len: %d", skb->len);		return -ENOMEM;	}	if (net_private->crc) {		u32 send_fcs;		send_fcs = fcs_memcpy32 (urb->buffer, skb->data, skb->len, CRC32_INITFCS);		urb->actual_length = skb->len;		// check if we need to pre-pend a NULL byte before CRC		if ((urb->actual_length % in_pkt_sz) == (in_pkt_sz - 4)) {			send_fcs = fcs_pad32 (urb->buffer + urb->actual_length, 1, send_fcs);			urb->actual_length++;			dbg_tx (2, "do_fcs32: adding NULL byte before CRC");		}		// if transfer is less than packetsize guarantee that is at lest two packets		else if (skb->len < (in_pkt_sz - 3)) {			dbg_tx (2, "do_fcs32: len: %d padding; %d", skb->len,				(in_pkt_sz - skb->len - 3));			send_fcs =			    fcs_pad32 (urb->buffer + urb->actual_length, (in_pkt_sz - skb->len - 3),				       send_fcs);			urb->actual_length = in_pkt_sz - 3;		}#if defined(CONFIG_USBD_NET_PADDED)//#warning LINKUP Padding defined		// Linkup - minimum size of last packet		dbg_tx (2, "do_fcs32: checking actual: %d pktsize: %d remainder: %d",			urb->actual_length, in_pkt_sz, (urb->actual_length + 4) % in_pkt_sz);		while (((urb->actual_length + 4) % in_pkt_sz) <= (in_pkt_sz - 2)) {			send_fcs = fcs_pad32 (urb->buffer + urb->actual_length, 1, send_fcs);			urb->actual_length++;			//dbg_tx(3, "do_fcs32: adding NULL byte(s) before CRC");		}#endif		send_fcs = ~send_fcs;		urb->buffer[urb->actual_length++] = send_fcs & 0xff;		urb->buffer[urb->actual_length++] = (send_fcs >> 8) & 0xff;		urb->buffer[urb->actual_length++] = (send_fcs >> 16) & 0xff;		urb->buffer[urb->actual_length++] = (send_fcs >> 24) & 0xff;	}	else {		urb->buffer = skb->data;		urb->actual_length = skb->len;	}#ifdef CONFIG_USBD_NO_ZLP_SUPPORT//#warning -//#warning NO ZLP SUPPORT DEFINED	// check if we need to append a NULL byte	if (!(urb->actual_length % in_pkt_sz)) {		dbg_tx (3, "adding NULL byte after CRC");		urb->buffer[urb->actual_length++] = 0;	}#endif	// save skb for netproto_done	urb->privdata = (void *) skb;	dbg_tx (4, "skb: %p head: %p data: %p tail: %p len: %d endpoint: %x",		skb, skb->head, skb->data, skb->tail, skb->len, CONFIG_USBD_NET_IN_ENDPOINT);	dbg_tx (4, "urb: %p buffer: %p acutal_length: %d", urb, urb->buffer, urb->actual_length);	dbgPRINTmem (dbgflg_usbdfd_tx, 4, urb->buffer, urb->actual_length);	if (usbd_send_urb (urb)) {		dbg_tx (1, "usbd_send_urb failed");		urb->privdata = NULL;		usbd_dealloc_urb (urb);		return -ECOMM;	}	return 0;}static int net_set_addr (int dev, void *addr, int len){	return 0;}/**  * net_tx_timeout - called by netproto if transmit times out * @dev: which device * * Called to cancel an in progress transmit. Note that this routine is advisory, * it just sends a message to the lower layer which may or may not actually do * anything about it. */static int net_tx_timeout (int interface){	struct usb_net_private *net_private;	dbg_tx (1, "if=%d", interface);	net_private = &net_private_array[interface];	if (!net_private->device) {		return -EINVAL;	}	return usbd_cancel_urb (net_private->device, NULL);}struct usb_function_operations function_ops = {	event:net_event,	recv_urb:net_recv_urb,	recv_setup:net_recv_setup,	urb_sent:net_urb_sent,#if 0	alloc_urb_data:net_alloc_urb_data,	dealloc_urb_data:net_dealloc_urb_data#endif	    function_init:net_function_init,	function_exit:net_function_exit,};struct usb_function_driver function_driver = {	name:"Generic Network",	ops:&function_ops,	device_description:&net_device_description,	configurations:sizeof (net_description) / sizeof (struct usb_configuration_description),	configuration_description:net_description,	this_module:THIS_MODULE,};/* proc file system ********************************************************************** */int net_device_condition = NET_DEVICE_CONDITION_UNKNOWN;static int net_device_received_command = 0;static int net_device_bus_active = 0;static struct timer_list net_device_fail_check_timer;static void net_device_fail_check(unsigned long data){	if (net_device_condition == NET_DEVICE_CONDITION_RESET) {		net_device_condition = NET_DEVICE_CONDITION_FAIL;	}}static void net_device_check_condition(usb_device_event_t event){	switch (event) {	case DEVICE_RESET:		del_timer(&net_device_fail_check_timer);		net_device_condition = NET_DEVICE_CONDITION_RESET;		net_device_received_command = 0;		net_device_bus_active = 1;		net_device_fail_check_timer.function = net_device_fail_check;		net_device_fail_check_timer.expires = jiffies + 30 * 100;		add_timer(&net_device_fail_check_timer);		break;	case DEVICE_CONFIGURED:		net_device_received_command = 1;		break;	case DEVICE_BUS_INACTIVE:		net_device_bus_active = 0;		break;	case DEVICE_BUS_ACTIVITY:		net_device_bus_active = 1;		break;	default:		break;	}}/* * * net_device_proc_read - implement proc file system read. * @file: xx * @buf:  xx * @count:  xx * @pos:  xx * * Standard proc file system read function. * * We let upper layers iterate for us, *pos will indicate which device to return * statistics for. */static ssize_tnet_device_proc_read_condition(struct file *file, char *buf, size_t count, loff_t * pos){	int len = 0;	char *p;	if (*pos > 0)		return 0;	switch (net_device_condition) {	case NET_DEVICE_CONDITION_UNKNOWN:	default:		p = "Unknown\n";		break;	case NET_DEVICE_CONDITION_RESET:		p = "Enumeration Start\n";		break;	case NET_DEVICE_CONDITION_OK:		if ( !net_device_bus_active ) {			p = "Unknown -- bus inactive\n";		} else {			p = "Enumeration OK\n";		}		break;	case NET_DEVICE_CONDITION_FAIL:		if ( !net_device_bus_active ) {			p = "Unknown -- bus inactive\n";		} else		if ( !net_device_received_command ) {			p = "Unknown -- command wasn't received from host\n";			// USB cable not connected		} else {			p = "Enumeration Fail\n";		}		break;	}	len = strlen(p);	*pos += len;	if (len > count) {		len = -EINVAL;	}	else if (len > 0 && copy_to_user(buf, p, len)) {		len = -EFAULT;	}	return len;}/* * * usbd_monitor_proc_write - implement proc file system write. * @file * @buf * @count * @pos * * Proc file system write function, used to signal monitor actions complete. * (Hotplug script (or whatever) writes to the file to signal the completion * of the script.)  An ugly hack. */static ssize_tnet_device_proc_write_condition(struct file *file, const char *buf, size_t count, loff_t * pos){	if (net_device_condition != NET_DEVICE_CONDITION_RESET)		net_device_condition = NET_DEVICE_CONDITION_UNKNOWN;	return count;}static struct file_operations net_device_proc_operations_condition = {	read: net_device_proc_read_condition,	write:net_device_proc_write_condition,};/* Module init and exit ********************************************************************** */unsigned char hexdigit (char c){	return isxdigit (c) ? (isdigit (c) ? (c - '0') : (c - 'A' + 10))	    : 0;}/* * net_modinit - module init * */static int __init net_modinit (void){	char local_mac_address_buffer[13];	int i;	debug_option *op = find_debug_option (dbg_table, "net");	printk (KERN_INFO "%s (dbg=\"%s\",alwaysup=%d,OUT=%d,IN=%d)\n",		__usbd_module_info, dbg ? dbg : "", alwaysup, out_pkt_sz, in_pkt_sz);	printk (KERN_INFO "vendorID: %x productID: %x\n", CONFIG_USBD_VENDORID,		CONFIG_USBD_PRODUCTID);	if (NULL != op) {		op->sub_table = netproto_get_dbg_table ();	}	if (0 != scan_debug_options ("net_fd", dbg_table, dbg)) {		return (-EINVAL);	}	memset (net_private_array, 0, sizeof (net_private_array));	// verify pkt sizes not too small	if (out_pkt_sz < 3 || in_pkt_sz < 3) {		dbg_init (0, "Rx pkt size %d or Tx pkt size %d too small", out_pkt_sz, in_pkt_sz);		return (-EINVAL);	}	// Check for non-default packet sizes	if (out_pkt_sz != CONFIG_USBD_NET_OUT_PKTSIZE) {#ifdef CONFIG_USBD_NET_SAFE		net_default[0].wMaxPacketSize = out_pkt_sz;#endif				/* CONFIG_USBD_NET_SAFE */#ifdef CONFIG_USBD_NET_CDC		net_alt_1_endpoints[0].wMaxPacketSize = out_pkt_sz;#endif	}	if (in_pkt_sz != CONFIG_USBD_NET_IN_PKTSIZE) {#ifdef CONFIG_USBD_NET_SAFE		net_default[1].wMaxPacketSize = in_pkt_sz;#endif				/* CONFIG_USBD_NET_SAFE */#ifdef CONFIG_USBD_NET_CDC		net_alt_1_endpoints[1].wMaxPacketSize = in_pkt_sz;#endif	}	dbg_init (1, "Rx pkt size %d, Tx pkt size %d", out_pkt_sz, in_pkt_sz);	if (vendor_id) {		net_device_description.idVendor = vendor_id;	}	if (product_id) {		net_device_description.idProduct = product_id;	}	// initialize the netproto library	if (netproto_modinit (if_name, MAX_INTERFACES)) {		dbg_init (0, "netproto_modinit failed");		return -EINVAL;	}	if (local_mac_address && (strlen (local_mac_address) == 12)) {		dbg_init (1, "using local_mac_address: %s", local_mac_address);		memcpy (local_mac_address_buffer, local_mac_address, 12);	} else {		dbg_init (1, "using LOCAL_MACADDR: %s", CONFIG_USBD_NET_LOCAL_MACADDR);		memcpy (local_mac_address_buffer, CONFIG_USBD_NET_LOCAL_MACADDR, 12);	}	local_mac_address_buffer[12] = '\0';	dbg_init (1, "local_mac_address_buffer: %s", local_mac_address_buffer);	dbg_init (1, "LOCAL_MACADDR: %s", CONFIG_USBD_NET_LOCAL_MACADDR);	if (local_mac_address) {		dbg_init (1, "localmac_address: %s len: %d", local_mac_address,			  strlen (local_mac_address));	}	// save the mac address for the network device	for (i = 0; i < ETH_ALEN; i++) {		default_dev_addr[i] =		    hexdigit (local_mac_address_buffer[i * 2]) << 4 |		    hexdigit (local_mac_address_buffer[i * 2 + 1]);		//dbg_init(0, "local_mac_address[%d]: %02x %02x %d %d %02x", i, 		//        local_mac_address_buffer[i*2], local_mac_address_buffer[i*2+1], 		//        hexdigit(local_mac_address_buffer[i*2]), hexdigit(local_mac_address_buffer[i*2+1]),		//        default_dev_addr[i]);	}	// create network interface	//net_create(0);	// register us with the usb device support layer	if (usbd_register_function (&function_driver)) {		dbg_init (0, "usbd_register_function failed");		netproto_modexit ();		return -EINVAL;	}	{		struct proc_dir_entry *p;		if ((p = create_proc_entry("usb-condition", 0, 0)) == NULL) {			netproto_modexit();			return -ENOMEM;		}		p->proc_fops = &net_device_proc_operations_condition;		init_timer(&net_device_fail_check_timer);	}	return 0;}/* * function_exit - module cleanup * */static void __exit net_modexit (void){	dbg_init (1, "exiting");	// de-register us with the usb device support layer	usbd_deregister_function (&function_driver);	// destroy network interface	//net_destroy(0);	// tell the netproto library to exit	netproto_modexit ();	remove_proc_entry("usb-condition", NULL);	del_timer(&net_device_fail_check_timer);}module_init (net_modinit);module_exit (net_modexit);

⌨️ 快捷键说明

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