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

📄 usb_ctl.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
{	 int retval;	 LOG("\n");	 if ( i < MAX_STRING_DESC ) {		  string_desc_array[i] = p;		  retval = 0;	 } else {		  retval = -EINVAL;	 }	 return retval;}/* optional: get a previously set string descriptor */string_desc_t *s3c2410_usb_get_string_descriptor( int i ){	LOG("\n");	 return ( i < MAX_STRING_DESC )		    ? string_desc_array[i]		    : NULL;}/* optional: kmalloc and unicode up a string descriptor */string_desc_t *s3c2410_usb_kmalloc_string_descriptor( const char * p ){	 string_desc_t * pResult = NULL;	 LOG("\n");	 if ( p ) {		  int len = strlen( p );		  int uni_len = len * sizeof( __u16 );		  pResult = (string_desc_t*) kmalloc( uni_len + 2, GFP_KERNEL ); /* ugh! */		  if ( pResult != NULL ) {			   int i;			   pResult->bLength = uni_len + 2;			   pResult->bDescriptorType = USB_DESC_STRING;			   for( i = 0; i < len ; i++ ) {					pResult->bString[i] = make_word( (__u16) p[i] );			   }		  }	 }	 return pResult;}//////////////////////////////////////////////////////////////////////////////// Exports to rest of driver///////////////////////////////////////////////////////////////////////////////* called by the int handler here and the two endpoint files when interesting   .."events" happen */intusbctl_next_state_on_event( int event ){	int next_state = device_state_machine[ sm_state ][ event ];	LOG("\n");	if ( next_state != kError )	{		int next_device_state = sm_state_to_device_state[ next_state ];		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;		}	}#if 0	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){	LOG("\n");	desc.dev.bLength               = sizeof( device_desc_t );	desc.dev.bDescriptorType       = USB_DESC_DEVICE;	desc.dev.bcdUSB                = 0x100; /* 1.1 */	desc.dev.bDeviceClass          = 0xFF;	/* vendor specific */	desc.dev.bDeviceSubClass       = 0x0;	desc.dev.bDeviceProtocol       = 0x0;	desc.dev.bMaxPacketSize0       = 0x8;	/* ep0 max fifo size in s3c2410*/	desc.dev.idVendor              = 0x49f; /* vendor ID undefined */	desc.dev.idProduct             = 0x505a; /* product */	desc.dev.bcdDevice             = 0x01 ; /* 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    = 0x1;	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;	desc.b.cfg.bmAttributes        = USB_CONFIG_BUSPOWERED;	desc.b.cfg.MaxPower            = USB_POWER( 500 );	desc.b.intf.bLength            = sizeof( intf_desc_t );	desc.b.intf.bDescriptorType    = USB_DESC_INTERFACE;	desc.b.intf.bInterfaceNumber   = 0x0; /* unique intf index*/	desc.b.intf.bAlternateSetting  = 0x0;	desc.b.intf.bNumEndpoints      = 2; /* endpoint number excluding ep0 */	desc.b.intf.bInterfaceClass    = 0xFF; /* vendor specific */	desc.b.intf.bInterfaceSubClass = 0x0;	desc.b.intf.bInterfaceProtocol = 0x0;	desc.b.intf.iInterface         = 0x0;	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( 64 );        desc.b.ep1.bInterval	       = 0x0;				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( 64 );	desc.b.ep2.bInterval           = 0x0;	/* 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 */	s3c2410_usb_set_string_descriptor( 0, &sd_zero );}//////////////////////////////////////////////////////////////////////////////// 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 * num_fmt   = "%25.25s: %8.8lX\n";	const char * cnt_fmt   = "%25.25s: %lu\n";	const char * yn_fmt    = "%25.25s: %s\n";	const char * yes       = "YES";	const char * no        = "NO";	const char * mask      = "MASK";	const char * enable    = "ENABLE";	unsigned long v;	unsigned long backup;	char * p = page;	int len;	SAY( "S3C2410 USB Controller Core\n" );	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 );	 	v = UD_FIFO0;	SAY( "%25.25s: 0x%8.8lX - %ld\n", "EP_FIFO0", v, v );	 	SAY( "\n" );	v = UD_FUNC;	SAY( "%25.25s: 0x%8.8lX - %ld\n", "Address Register", v, v );	backup = UD_INDEX;	UD_INDEX = UD_INDEX_EP0;	v = UD_MAXP;	SAY( "%25.25s: %ld (%8.8lX)\n", "EP0 size(EP0)", v, v );	 	UD_INDEX = UD_INDEX_EP2;	v = UD_MAXP;	SAY( "%25.25s: %ld (%8.8lX)\n", "IN  max packet size(EP2)", v, v );	UD_INDEX = UD_INDEX_EP1;	v = UD_MAXP;	SAY( "%25.25s: %ld (%8.8lX)\n", "OUT max packet size(EP1)", v, v );	UD_INDEX = backup;	v = UD_PWR;	SAY( "\nUDC POWER Management Register\n" );	SAYV( v );	SAYC( "ISO Update(R)",    ( v & UD_PWR_ISOUP )     ? yes : no );	SAYC( "USB Reset(R)",   ( v & UD_PWR_RESET ) ? yes : no );	SAYC( "MCU Resume(RW)",  ( v & UD_PWR_RESUME  ) ? yes : no );	SAYC( "Suspend Mode(R)",( v & UD_PWR_SUSPND ) ? yes : no );	SAYC( "Suspend Mode enable bit(RW)",  ( v & UD_PWR_ENSUSPND ) ? yes : no );		 	 	v = UD_INT;	SAY( "\nUDC Interrupt Register\n" );	SAYV( v );	SAYC( "EP4 pending",        ( v & UD_INT_EP4 )     ? yes : no );	SAYC( "EP3 pending",        ( v & UD_INT_EP3 )     ? yes : no );	SAYC( "EP2 pending",        ( v & UD_INT_EP2 )     ? yes : no );	SAYC( "EP1 pending",        ( v & UD_INT_EP1 )     ? yes : no );	SAYC( "EP0 pending",        ( v & UD_INT_EP0 )     ? yes : no );	v = UD_USBINT;	SAY( "\nUSB Interrupt Register\n" );	SAYV( v );	SAYC( "Reset",        ( v & UD_USBINT_RESET )     ? yes : no );	SAYC( "Resume",        ( v & UD_USBINT_RESUM )     ? yes : no );	SAYC( "Suspend",        ( v & UD_USBINT_SUSPND )     ? yes : no );	v = UD_INTE;	SAY( "\nUDC Interrupt Enable Register\n" );	SAYV( v );	SAYC( "EP4",                !( v & UD_INTE_EP4 )    ? mask : enable );	SAYC( "EP3",                !( v & UD_INTE_EP3 )    ? mask : enable );	SAYC( "EP2",                !( v & UD_INTE_EP2 )    ? mask : enable );	SAYC( "EP1",                !( v & UD_INTE_EP1 )    ? mask : enable );	SAYC( "EP0",                !( v & UD_INTE_EP0 )    ? mask : enable );	v = UD_USBINTE;	SAY( "\nUSB Interrupt Enable Register\n" );	SAYV( v );	SAYC( "Reset",              !( v & UD_USBINTE_RESET )    ? mask : enable );	SAYC( "Suspend",            !( v & UD_USBINTE_SUSPND )  ? mask : enable );	len = ( p - page ) - off;	if ( len < 0 )	     len = 0;	*eof = ( len <=count ) ? 1 : 0;	*start = page + off;	return len;}#endif  /* CONFIG_PROC_FS */#if defined(CONFIG_PM) && defined(CONFIG_MIZI)void usbctl_suspend(void){	/* TODO: FIXME: */}void usbctl_resume(void){	/* TODO: FIXME: */}#endif//////////////////////////////////////////////////////////////////////////////// Module Initialization and Shutdown///////////////////////////////////////////////////////////////////////////////* * usbctl_init() * Module load time. Allocate dma and interrupt resources. Setup /proc fs * entry. Leave UDC disabled. */int __init usbctl_init( void ){	int retval = 0;#if CONFIG_MAX_ROOT_PORTS > 1	printk("check your kernel config.\n");	return -ENODEV;#endif	memset( &usbd_info, 0, sizeof( usbd_info ) );	usbd_info.dmach_tx = DMA_CH3; // ep1	usbd_info.dmach_rx = DMA_CH0; // ep2#if CONFIG_PROC_FS	create_proc_read_entry ( PROC_NODE_NAME, 0, NULL, usbctl_read_proc, NULL);#endif#ifdef USE_USBD_DMA	lsdkjflsdkjsdlkjflksdjf	/* setup dma */#if 1	retval = s3c2410_request_dma("USB", DMA_CH0, 								 ep1_dma_callback, NULL);	if (retval) {		printk("%sunable to register for dma rc=%d\n", pszMe, retval);		goto err_dma;	}	retval = s3c2410_request_dma("USB", DMA_CH2, 								 NULL, ep2_dma_callback);	if (retval) {		printk("%sunable to register for dma rc=%d\n", pszMe, retval);		goto err_dma;	}#else	retval = s3c2410_request_dma("USB", DMA_CH0, 								 ep1_dma_callback, ep2_dma_callback);	if (retval) {		printk("%sunable to register for dma rc=%d\n", pszMe, retval);		goto err_dma;	}#endif#endif // USE_USBD_DMA		/* now allocate the IRQ. */	retval = request_irq(IRQ_USBD, udc_int_hndlr, SA_INTERRUPT,			  "S3C2410 USB core", NULL);	if (retval) {		printk("%sCouldn't request USB irq rc=%d\n",pszMe, retval);		goto err_irq;	}	/* MISC. register */	MISCCR &= ~MISCCR_USBPAD;	/* UPLLCON */	UPLLCON = FInsrt(0x78, fPLL_MDIV) | FInsrt(0x02, fPLL_PDIV) 				| FInsrt(0x03, fPLL_SDIV);	/* CLKCON */	CLKCON |= CLKCON_USBD;    	Clear_pending(INT_USBD);	printk( "S3C2410 USB Controller Core Initialized\n");	return 0;err_irq:#ifdef USE_USBD_DMA	s3c2410_free_dma(DMA_CH0);	s3c2410_free_dma(DMA_CH3);#endif err_dma:	usbd_info.dmach_tx = 0;	usbd_info.dmach_rx = 0;	return retval;}/* * usbctl_exit() * Release DMA and interrupt resources */void __exit usbctl_exit( void ){    printk("Unloading S3C2410 USB Controller\n");	CLKCON &= ~CLKCON_USBD;#ifdef CONFIG_PROC_FS    remove_proc_entry ( PROC_NODE_NAME, NULL);#endif#ifdef USE_USBD_DMA    s3c2410_free_dma(usbd_info.dmach_rx);    s3c2410_free_dma(usbd_info.dmach_tx);#endif    free_irq(IRQ_USBD, NULL);}EXPORT_SYMBOL( s3c2410_usb_open );EXPORT_SYMBOL( s3c2410_usb_start );EXPORT_SYMBOL( s3c2410_usb_stop );EXPORT_SYMBOL( s3c2410_usb_close );EXPORT_SYMBOL( s3c2410_usb_get_descriptor_ptr );EXPORT_SYMBOL( s3c2410_usb_set_string_descriptor );EXPORT_SYMBOL( s3c2410_usb_get_string_descriptor );EXPORT_SYMBOL( s3c2410_usb_kmalloc_string_descriptor );#if defined(CONFIG_PM) && defined(CONFIG_MIZI)EXPORT_SYMBOL( usbctl_resume );EXPORT_SYMBOL( usbctl_suspend );#endifmodule_init( usbctl_init );module_exit( usbctl_exit );

⌨️ 快捷键说明

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