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

📄 usb_ctl.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		int next_device_state = sm_state_to_device_state[ next_state ];		if( usb_debug) printk( "%s%s --> [%s] --> %s. Device in %s state.\n",				pszMe, state_names[ sm_state ], event_names[ event ],				state_names[ next_state ], device_state_names[ next_device_state ] );		sm_state = next_state;		if ( usbd_info.state != next_device_state )		{			if ( configured_callback != NULL				 &&				 next_device_state == USB_STATE_CONFIGURED				 &&				 usbd_info.state != USB_STATE_SUSPENDED			   ) {			  configured_callback();			}			usbd_info.state = next_device_state;			ep_bulk_out1_state_change_notify( next_device_state );			ep_bulk_in1_state_change_notify( next_device_state );		}	}#if 1	else		printk( "%s%s --> [%s] --> ??? is an error.\n",				pszMe, state_names[ sm_state ], event_names[ event ] );#endif	return next_state;}//////////////////////////////////////////////////////////////////////////////// Private Helpers///////////////////////////////////////////////////////////////////////////////* setup default descriptors */static voidinitialize_descriptors(void){	desc.dev.bLength               = sizeof( device_desc_t );	desc.dev.bDescriptorType       = USB_DESC_DEVICE;	desc.dev.bcdUSB                = 0x100; /* 1.0 */	desc.dev.bDeviceClass          = 0xFF;	/* vendor specific */	desc.dev.bDeviceSubClass       = 0;	desc.dev.bDeviceProtocol       = 0;	desc.dev.bMaxPacketSize0       = EP0_FIFO_SIZE;	/* ep0 max fifo size */	desc.dev.idVendor              = 0;	/* vendor ID undefined */	desc.dev.idProduct             = 0; /* product */	desc.dev.bcdDevice             = 0; /* vendor assigned device release num */	desc.dev.iManufacturer         = 0;	/* index of manufacturer string */	desc.dev.iProduct              = 0; /* index of product description string */	desc.dev.iSerialNumber         = 0;	/* index of string holding product s/n */	desc.dev.bNumConfigurations    = 1;	desc.b.cfg.bLength             = sizeof( config_desc_t );	desc.b.cfg.bDescriptorType     = USB_DESC_CONFIG;	desc.b.cfg.wTotalLength        = make_word_c( sizeof(struct cdb) );	desc.b.cfg.bNumInterfaces      = 1;	desc.b.cfg.bConfigurationValue = 1;	desc.b.cfg.iConfiguration      = 0;#ifdef CONFIG_S3C2440_SMDK	desc.b.cfg.bmAttributes        = USB_CONFIG_BUSPOWERED | USB_CONFIG_SELFPOWERED;	desc.b.cfg.MaxPower            = USB_POWER( 0 );#else	desc.b.cfg.bmAttributes        = USB_CONFIG_BUSPOWERED;	desc.b.cfg.MaxPower            = USB_POWER( 500 );#endif	desc.b.intf.bLength            = sizeof( intf_desc_t );	desc.b.intf.bDescriptorType    = USB_DESC_INTERFACE;	desc.b.intf.bInterfaceNumber   = 0; /* unique intf index*/	desc.b.intf.bAlternateSetting  = 0;	desc.b.intf.bNumEndpoints      = 2;	desc.b.intf.bInterfaceClass    = 0xFF; /* vendor specific */	desc.b.intf.bInterfaceSubClass = 0;	desc.b.intf.bInterfaceProtocol = 0;	desc.b.intf.iInterface         = 0;	desc.b.ep1.bLength             = sizeof( ep_desc_t );	desc.b.ep1.bDescriptorType     = USB_DESC_ENDPOINT;	desc.b.ep1.bEndpointAddress    = USB_EP_ADDRESS( 1, USB_OUT );	desc.b.ep1.bmAttributes        = USB_EP_BULK;	desc.b.ep1.wMaxPacketSize      = make_word_c( EP1_FIFO_SIZE );	desc.b.ep1.bInterval           = 0;	desc.b.ep2.bLength             = sizeof( ep_desc_t );	desc.b.ep2.bDescriptorType     = USB_DESC_ENDPOINT;	desc.b.ep2.bEndpointAddress    = USB_EP_ADDRESS( 2, USB_IN );	desc.b.ep2.bmAttributes        = USB_EP_BULK;	desc.b.ep2.wMaxPacketSize      = make_word_c( EP2_FIFO_SIZE );	desc.b.ep2.bInterval           = 0;#if defined(CONFIG_S3C2440_USB_CDC_ENCM) || defined(CONFIG_S3C2440_USB_CDC_ENCM_MODULE)	desc.cdc_b.cfg.bLength             = sizeof( config_desc_t );	desc.cdc_b.cfg.bDescriptorType     = USB_DESC_CONFIG;	desc.cdc_b.cfg.wTotalLength        = make_word_c( sizeof(struct cdc_cdb) );	desc.cdc_b.cfg.bNumInterfaces      = 2;	desc.cdc_b.cfg.bConfigurationValue = 1;	desc.cdc_b.cfg.iConfiguration      = 0;#ifdef CONFIG_S3C2440_SMDK	desc.cdc_b.cfg.bmAttributes        = USB_CONFIG_BUSPOWERED | USB_CONFIG_SELFPOWERED;	desc.cdc_b.cfg.MaxPower            = USB_POWER( 0 );#else	desc.cdc_b.cfg.bmAttributes        = USB_CONFIG_BUSPOWERED;	desc.cdc_b.cfg.MaxPower            = USB_POWER( 500 );#endif	desc.cdc_b.comm_intf.bLength            = sizeof( intf_desc_t );	desc.cdc_b.comm_intf.bDescriptorType    = USB_DESC_INTERFACE;	desc.cdc_b.comm_intf.bInterfaceNumber   = 0;	desc.cdc_b.comm_intf.bAlternateSetting  = 0;	desc.cdc_b.comm_intf.bNumEndpoints      = 0;	desc.cdc_b.comm_intf.bInterfaceClass    = CDC_COMM_INTERFACE_CLASS;	desc.cdc_b.comm_intf.bInterfaceSubClass = CDC_COMM_INTERFACE_SUBCLASS_ENCM;	desc.cdc_b.comm_intf.bInterfaceProtocol = 0;	desc.cdc_b.comm_intf.iInterface         = 0;	desc.cdc_b.func.hdr.bLength             = sizeof( hdr_func_desc_t );	desc.cdc_b.func.hdr.bDescriptorType     = CDC_CS_INTERFACE;	desc.cdc_b.func.hdr.bDescriptorSubtype  = CDC_DESC_SUBTYPE_HEADER;	desc.cdc_b.func.hdr.bcdCDC              = CDC_CLASS_BCD_VERSION;	desc.cdc_b.func.eth.bLength             = sizeof( eth_func_desc_t );	desc.cdc_b.func.eth.bDescriptorType     = CDC_CS_INTERFACE;	desc.cdc_b.func.eth.bDescriptorSubtype  = CDC_DESC_SUBTYPE_ETHER;	desc.cdc_b.func.eth.iMACAddress         = 0;	desc.cdc_b.func.eth.bmEthernetStatistics = 0;	desc.cdc_b.func.eth.wMaxSegmentSize     = 1514;	desc.cdc_b.func.eth.wNumberMCFilters    = 0;	desc.cdc_b.func.eth.bNumberPowerFilters = 0;	desc.cdc_b.func.uni.bLength             = sizeof( union_func_desc_t );	desc.cdc_b.func.uni.bDescriptorType     = CDC_CS_INTERFACE;	desc.cdc_b.func.uni.bDescriptorSubtype  = CDC_DESC_SUBTYPE_UNION;	desc.cdc_b.func.uni.bMasterInterface    = 0;	desc.cdc_b.func.uni.bSlaveInterface     = 1;#ifdef CDC_ALTERNATE_INTERFACE	desc.cdc_b.data_intf0.bLength            = sizeof( intf_desc_t );	desc.cdc_b.data_intf0.bDescriptorType    = USB_DESC_INTERFACE;	desc.cdc_b.data_intf0.bInterfaceNumber   = 1;	desc.cdc_b.data_intf0.bAlternateSetting  = 0;	desc.cdc_b.data_intf0.bNumEndpoints      = 0;	desc.cdc_b.data_intf0.bInterfaceClass    = CDC_DATA_INTERFACE_CLASS;	desc.cdc_b.data_intf0.bInterfaceSubClass = 0;	desc.cdc_b.data_intf0.bInterfaceProtocol = 0;	desc.cdc_b.data_intf0.iInterface         = 0;#endif /* CDC_ALTERNATE_INTERFACE */	desc.cdc_b.data_intf1.bLength            = sizeof( intf_desc_t );	desc.cdc_b.data_intf1.bDescriptorType    = USB_DESC_INTERFACE;	desc.cdc_b.data_intf1.bInterfaceNumber   = 1;#ifdef CDC_ALTERNATE_INTERFACE	desc.cdc_b.data_intf1.bAlternateSetting  = 2;#else	desc.cdc_b.data_intf1.bAlternateSetting  = 0;#endif /* CDC_ALTERNATE_INTERFACE */	desc.cdc_b.data_intf1.bNumEndpoints      = 2;	desc.cdc_b.data_intf1.bInterfaceClass    = CDC_DATA_INTERFACE_CLASS;	desc.cdc_b.data_intf1.bInterfaceSubClass = 0;	desc.cdc_b.data_intf1.bInterfaceProtocol = 0;	desc.cdc_b.data_intf1.iInterface         = 0;	desc.cdc_b.ep2.bLength             = sizeof( ep_desc_t );	desc.cdc_b.ep2.bDescriptorType     = USB_DESC_ENDPOINT;	desc.cdc_b.ep2.bEndpointAddress    = USB_EP_ADDRESS( 2, USB_OUT );	desc.cdc_b.ep2.bmAttributes        = USB_EP_BULK;	desc.cdc_b.ep2.wMaxPacketSize      = make_word_c( EP2_FIFO_SIZE );	desc.cdc_b.ep2.bInterval           = 0;	desc.cdc_b.ep1.bLength             = sizeof( ep_desc_t );	desc.cdc_b.ep1.bDescriptorType     = USB_DESC_ENDPOINT;	desc.cdc_b.ep1.bEndpointAddress    = USB_EP_ADDRESS( 1, USB_IN );	desc.cdc_b.ep1.bmAttributes        = USB_EP_BULK;	desc.cdc_b.ep1.wMaxPacketSize      = make_word_c( EP1_FIFO_SIZE );	desc.cdc_b.ep1.bInterval           = 0;#endif /* CONFIG_S3C2440_USB_CDC_ENCM || CONFIG_S3C2440_USB_CDC_ENCM_MODULE */// FIXME: Add support for all endpoint...	/* set language */	/* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */	sd_zero.bDescriptorType = USB_DESC_STRING;	sd_zero.bLength         = sizeof( string_desc_t );	sd_zero.bString[0]      = make_word_c( 0x409 ); /* American English */	elfin_usb_set_string_descriptor( 0, &sd_zero );}/* soft_connect_hook() * Some devices have platform-specific circuitry to make USB * not seem to be plugged in, even when it is. This allows * software to control when a device 'appears' on the USB bus * (after Linux has booted and this driver has loaded, for * example). If you have such a circuit, control it here. */static voidsoft_connect_hook( int enable ){}/* disable the UDC at the source */static voidudc_disable(void){	soft_connect_hook( 0 );	CLKCON &= ~CLKCON_USBD;}/*  enable the udc at the source */static voidudc_enable(void){	int tmp;	CLKCON &= ~CLKCON_USBD;	UD_INDEX = UD_INDEX_EP2; // EP2 input	tmp = UD_ICSR1;	tmp &= ~(UD_ICSR1_SENTSTL | UD_ICSR1_FFLUSH | UD_ICSR1_UNDRUN);	tmp &= ~(UD_ICSR1_PKTRDY | UD_ICSR1_SENDSTL);	UD_ICSR1 = tmp;	UD_INDEX = UD_INDEX_EP1; // EP1 output	tmp = UD_OCSR1;	tmp &= ~(UD_OCSR1_SENTSTL | UD_OCSR1_FFLUSH | UD_OCSR1_OVRRUN);	tmp &= ~(UD_OCSR1_PKTRDY | UD_OCSR1_SENDSTL);	UD_OCSR1 = tmp;	CLKCON |= CLKCON_USBD;}static void reconfig_usbd(void){	UD_PWR = UD_PWR_DEFAULT;	/* EP0 */	UD_INDEX = UD_INDEX_EP0;       	UD_MAXP = (EP0_FIFO_SIZE >> 3); 	UD_INDEX = UD_INDEX_EP0;	UD_ICSR1 = EP0_CSR_SOPKTRDY | EP0_CSR_SSE;	/* EP2 */	UD_INDEX = UD_INDEX_EP2;           	UD_MAXP = (EP2_FIFO_SIZE >> 3);	UD_INDEX = UD_INDEX_EP2;	UD_ICSR1 = UD_ICSR1_FFLUSH | UD_ICSR1_CLRDT; // fifo flush, data toggle	UD_INDEX = UD_INDEX_EP2;	UD_ICSR2 = UD_ICSR2_MODEIN | UD_ICSR2_DMAIEN; // input mode, IN_PKT_RDY dis #ifdef USE_USBD_DMA	UD_ICSR2 &= ~UD_ICSR2_DMAIEN;#endif	/* EP1 */	UD_INDEX = UD_INDEX_EP1;            	UD_MAXP = (EP1_FIFO_SIZE >> 3);	UD_INDEX = UD_INDEX_EP1;	UD_ICSR1 = UD_ICSR1_FFLUSH | UD_ICSR1_CLRDT; // fifo flush, data toggle	UD_INDEX = UD_INDEX_EP1;	UD_ICSR2 = 0x0; // output mode	UD_INDEX = UD_INDEX_EP1;	UD_OCSR1 = UD_OCSR1_FFLUSH | UD_OCSR1_CLRDT; // fifo flush	UD_INDEX = UD_INDEX_EP1;	UD_OCSR2 = UD_OCSR2_DMAIEN; // OUT_PKT_RDY interrupt disable#ifdef USE_USBD_DMA	UD_OCSR2 &= ~UD_OCSR2_DMAIEN; // OUT_PKT_RDY interrupt disable#endif	UD_INTE = UD_INTE_EP0 | UD_INTE_EP2 | UD_INTE_EP1;	UD_USBINTE = UD_USBINTE_RESET | UD_USBINTE_SUSPND;}//////////////////////////////////////////////////////////////////////////////// Proc Filesystem Support//////////////////////////////////////////////////////////////////////////////#if CONFIG_PROC_FS#define SAY( fmt, args... )  p += sprintf(p, fmt, ## args )#define SAYV(  num )         p += sprintf(p, num_fmt, "Value", num )#define SAYC( label, yn )    p += sprintf(p, yn_fmt, label, yn )#define SAYS( label, v )     p += sprintf(p, cnt_fmt, label, v )static int usbctl_read_proc(char *page, char **start, off_t off,			    int count, int *eof, void *data){	 const char * cnt_fmt   = "%25.25s: %lu\n";	 // const char * num_fmt   = "%25.25s: %8.8lX\n";	 // const char * yn_fmt    = "%25.25s: %s\n";	 char * p = page;	 int len; 	 SAY( "S3C2440 USB Controller Core\n" ); 	 SAY( "Active Client: %s\n", usbd_info.client_name ? usbd_info.client_name : "none");	 SAY( "USB state: %s (%s) %d\n",		  device_state_names[ sm_state_to_device_state[ sm_state ] ],		  state_names[ sm_state ],		  sm_state );	 SAYS( "ep0 bytes read", usbd_info.stats.ep0_bytes_read );	 SAYS( "ep0 bytes written", usbd_info.stats.ep0_bytes_written );	 SAYS( "ep0 FIFO read failures", usbd_info.stats.ep0_fifo_write_failures );	 SAYS( "ep0 FIFO write failures", usbd_info.stats.ep0_fifo_write_failures );	 SAY( "\n" );	 len = ( p - page ) - off;	 if ( len < 0 )		  len = 0;	 *eof = ( len <=count ) ? 1 : 0;	 *start = page + off;	 return len;}#endif  /* CONFIG_PROC_FS *///////////////////////////////////////////////////////////////////////////////// Module Initialization and Shutdown///////////////////////////////////////////////////////////////////////////////* * usbctl_init() * Module load time. Allocate interrupt resources. Setup /proc fs * entry. Leave UDC disabled. */int __init usbctl_init( void ){	int retval = 0;	memset( &usbd_info, 0, sizeof( usbd_info ) );#if CONFIG_PROC_FS	create_proc_read_entry ( PROC_NODE_NAME, 0, NULL, usbctl_read_proc, NULL);#endif	MISCCR &= ~(1<<13 | 1<<3);	CLKCON |= CLKCON_USBD;	/* 96MHz */	//UPLLCON = FInsrt(0x3c, fPLL_MDIV) | FInsrt(4, fPLL_PDIV)| FInsrt(1, fPLL_SDIV);    //CLKDIVN |= DIVN_UPLL;   /* UCLK is 48Mhz */	printk(KERN_DEBUG "CLKCON  : [0x%08x],  LOCKTIME: [0x%08x]\n", CLKCON, LOCKTIME );	printk(KERN_DEBUG "UPLLCON : [0x%08x],  CLKDIVN : [0x%08x]\n", UPLLCON, CLKDIVN);	printk(KERN_DEBUG "MISCCR  : [0x%08x],  CLKSLOW : [0x%08x]\n", MISCCR,  CLKSLOW);	/* now allocate the IRQ. */	retval = request_irq(IRQ_USBD, udc_int_hndlr, SA_INTERRUPT, "USBD", NULL);	if (retval) {		printk("%sCouldn't request USB irq rc=%d\n",pszMe, retval);		goto err_irq;	}	printk( "S3C2440 USBD Controller Core Initialized\n");	return 0;err_irq:	return retval;}/* * usbctl_exit() * Release interrupt resources */void __exit usbctl_exit( void ){	printk("Unloading S3C2440 USBD Controller\n");	udc_disable();#if CONFIG_PROC_FS	remove_proc_entry ( PROC_NODE_NAME, NULL);#endif	free_irq(IRQ_USBD, NULL);}module_init( usbctl_init );module_exit( usbctl_exit );EXPORT_SYMBOL( elfin_usb_open );EXPORT_SYMBOL( elfin_usb_start );EXPORT_SYMBOL( elfin_usb_stop );EXPORT_SYMBOL( elfin_usb_close );EXPORT_SYMBOL( elfin_usb_get_descriptor_ptr );EXPORT_SYMBOL( elfin_usb_set_string_descriptor );EXPORT_SYMBOL( elfin_usb_get_string_descriptor );EXPORT_SYMBOL( elfin_usb_kmalloc_string_descriptor );

⌨️ 快捷键说明

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