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

📄 usb_ctl.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
	 return ( i < MAX_STRING_DESC )		    ? string_desc_array[i]		    : NULL;}/* optional: kmalloc and unicode up a string descriptor */string_desc_t *sa1100_usb_kmalloc_string_descriptor( const char * p ){	 string_desc_t * pResult = NULL;	 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 ];	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;			ep1_state_change_notify( next_device_state );			ep2_state_change_notify( 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){	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       = 8;	/* 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;	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   = 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( 64 );	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( 64 );	desc.b.ep2.bInterval           = 0;	/* 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 */	sa1100_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 ){#ifdef CONFIG_SA1100_EXTENEX1	 if (machine_is_extenex1() ) {		  if ( enable ) {			   PPDR |= PPC_USB_SOFT_CON;			   PPSR |= PPC_USB_SOFT_CON;		  } else {			   PPSR &= ~PPC_USB_SOFT_CON;			   PPDR &= ~PPC_USB_SOFT_CON;		  }	 }#endif}/* disable the UDC at the source */static voidudc_disable(void){	soft_connect_hook( 0 );	UDC_set( Ser0UDCCR, UDCCR_UDD );}/*  enable the udc at the source */static voidudc_enable(void){	UDC_clear(Ser0UDCCR, UDCCR_UDD);}// HACK DEBUG  3Mar01ww// Well, maybe not, it really seems to help!  08Mar01wwstatic voidcore_kicker( void ){	 __u32 car = Ser0UDCAR;	 __u32 imp = Ser0UDCIMP;	 __u32 omp = Ser0UDCOMP;	 UDC_set( Ser0UDCCR, UDCCR_UDD );	 udelay( 300 );	 UDC_clear(Ser0UDCCR, UDCCR_UDD);	 Ser0UDCAR = car;	 Ser0UDCIMP = imp;	 Ser0UDCOMP = omp;}//////////////////////////////////////////////////////////////////////////////// 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";	 unsigned long v;	 char * p = page;	 int len; 	 SAY( "SA1100 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 );	 SAY( "\n" );	 v = Ser0UDCAR;	 SAY( "%25.25s: 0x%8.8lX - %ld\n", "Address Register", v, v );	 v = Ser0UDCIMP;	 SAY( "%25.25s: %ld (%8.8lX)\n", "IN  max packet size", v+1, v );	 v = Ser0UDCOMP;	 SAY( "%25.25s: %ld (%8.8lX)\n", "OUT max packet size", v+1, v );	 v = Ser0UDCCR;	 SAY( "\nUDC Mask Register\n" );	 SAYV( v );	 SAYC( "UDC Active",                ( v & UDCCR_UDA ) ? yes : no );	 SAYC( "Suspend interrupts masked", ( v & UDCCR_SUSIM ) ? yes : no );	 SAYC( "Resume interrupts masked",  ( v & UDCCR_RESIM ) ? yes : no );	 SAYC( "Reset interrupts masked",   ( v & UDCCR_REM ) ? yes : no );	 v = Ser0UDCSR;	 SAY( "\nUDC Interrupt Request Register\n" );	 SAYV( v );	 SAYC( "Reset pending",      ( v & UDCSR_RSTIR ) ? yes : no );	 SAYC( "Suspend pending",    ( v & UDCSR_SUSIR ) ? yes : no );	 SAYC( "Resume pending",     ( v & UDCSR_RESIR ) ? yes : no );	 SAYC( "ep0 pending",        ( v & UDCSR_EIR )   ? yes : no );	 SAYC( "receiver pending",   ( v & UDCSR_RIR )   ? yes : no );	 SAYC( "tramsitter pending", ( v & UDCSR_TIR )   ? yes : no );#ifdef CONFIG_SA1100_EXTENEX1	 SAYC( "\nSoft connect", (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden" );#endif#if 0	 v = Ser0UDCCS0;	 SAY( "\nUDC Endpoint Zero Status Register\n" );	 SAYV( v );	 SAYC( "Out Packet Ready", ( v & UDCCS0_OPR ) ? yes : no );	 SAYC( "In Packet Ready",  ( v & UDCCS0_IPR ) ? yes : no );	 SAYC( "Sent Stall",       ( v & UDCCS0_SST ) ? yes : no );	 SAYC( "Force Stall",      ( v & UDCCS0_FST ) ? yes : no );	 SAYC( "Data End",         ( v & UDCCS0_DE )  ? yes : no );	 SAYC( "Data Setup End",   ( v & UDCCS0_SE )  ? yes : no );	 SAYC( "Serviced (SO)",    ( v & UDCCS0_SO )  ? yes : no );	 v = Ser0UDCCS1;	 SAY( "\nUDC Receiver Status Register\n" );	 SAYV( v );	 SAYC( "Receive Packet Complete", ( v & UDCCS1_RPC ) ? yes : no );	 SAYC( "Sent Stall",              ( v & UDCCS1_SST ) ? yes : no );	 SAYC( "Force Stall",             ( v & UDCCS1_FST ) ? yes : no );	 SAYC( "Receive Packet Error",    ( v & UDCCS1_RPE ) ? yes : no );	 SAYC( "Receive FIFO not empty",  ( v & UDCCS1_RNE ) ? yes : no );	 v = Ser0UDCCS2;	 SAY( "\nUDC Transmitter Status Register\n" );	 SAYV( v );	 SAYC( "FIFO has < 8 of 16 chars", ( v & UDCCS2_TFS ) ? yes : no );	 SAYC( "Transmit Packet Complete", ( v & UDCCS2_TPC ) ? yes : no );	 SAYC( "Transmit FIFO underrun",   ( v & UDCCS2_TUR ) ? yes : no );	 SAYC( "Transmit Packet Error",    ( v & UDCCS2_TPE ) ? yes : no );	 SAYC( "Sent Stall",               ( v & UDCCS2_SST ) ? yes : no );	 SAYC( "Force Stall",              ( v & UDCCS2_FST ) ? yes : no );#endif	 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 dma and interrupt resources. Setup /proc fs * entry. Leave UDC disabled. */int __init usbctl_init( void ){	int retval = 0;	udc_disable();	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	/* setup rx dma */	retval = sa1100_request_dma(&usbd_info.dmach_rx, "USB receive", DMA_Ser0UDCRd);	if (retval) {		printk("%sunable to register for rx dma rc=%d\n", pszMe, retval );		goto err_rx_dma;	}	/* setup tx dma */	retval = sa1100_request_dma(&usbd_info.dmach_tx, "USB transmit", DMA_Ser0UDCWr);	if (retval) {		printk("%sunable to register for tx dma rc=%d\n",pszMe,retval);		goto err_tx_dma;	}	/* now allocate the IRQ. */	retval = request_irq(IRQ_Ser0UDC, udc_int_hndlr, SA_INTERRUPT,			  "SA USB core", NULL);	if (retval) {		printk("%sCouldn't request USB irq rc=%d\n",pszMe, retval);		goto err_irq;	}	printk( "SA1100 USB Controller Core Initialized\n");	return 0;err_irq:	sa1100_free_dma(usbd_info.dmach_tx);	usbd_info.dmach_tx = 0;err_tx_dma:	sa1100_free_dma(usbd_info.dmach_rx);	usbd_info.dmach_rx = 0;err_rx_dma:	return retval;}/* * usbctl_exit() * Release DMA and interrupt resources */void __exit usbctl_exit( void ){    printk("Unloading SA1100 USB Controller\n");	udc_disable();#if CONFIG_PROC_FS    remove_proc_entry ( PROC_NODE_NAME, NULL);#endif    sa1100_free_dma(usbd_info.dmach_rx);    sa1100_free_dma(usbd_info.dmach_tx);    free_irq(IRQ_Ser0UDC, NULL);}EXPORT_SYMBOL( sa1100_usb_open );EXPORT_SYMBOL( sa1100_usb_start );EXPORT_SYMBOL( sa1100_usb_stop );EXPORT_SYMBOL( sa1100_usb_close );EXPORT_SYMBOL( sa1100_usb_get_descriptor_ptr );EXPORT_SYMBOL( sa1100_usb_set_string_descriptor );EXPORT_SYMBOL( sa1100_usb_get_string_descriptor );EXPORT_SYMBOL( sa1100_usb_kmalloc_string_descriptor );module_init( usbctl_init );module_exit( usbctl_exit );

⌨️ 快捷键说明

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