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

📄 usb_ep0.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				     pszMe, req.wValue);			}			set_ep0_de_out;			break;		case GET_STATUS:			clear_ep0_opr;			UD_FIFO0 = device_status;			UD_FIFO0 = 0x00;			set_ep0_de_in;			break;		case GET_CONFIGURATION:			clear_ep0_opr;			UD_FIFO0 = set_configuration;			set_ep0_de_in;			break;		case GET_DESCRIPTOR:			get_descriptor(req);			break;		default:			set_ep0_de_out;		}		break;		/* Interface Recipient */	case kTargetInterface:		switch (req.bRequest) {		case SET_INTERFACE:			set_interface = req.wValue;			set_ep0_de_out;			break;		case GET_INTERFACE:			clear_ep0_opr;			UD_FIFO0 = set_interface;			set_ep0_de_in;			break;		}		break;	case kTargetEndpoint:		switch (req.bRequest) {		case SET_FEATURE:			set_feature(req);			break;		case CLEAR_FEATURE:			clear_feature(req);			break;		case GET_STATUS:			clear_ep0_opr;			e = windex_to_ep_num(req.wIndex);			if (e == 0) {				UD_FIFO0 = ep0_status;				UD_FIFO0 = 0x00;			} else if (e == 2) {				UD_FIFO0 = ep_bulk_in_status;				UD_FIFO0 = 0x00;			} else if (e == 1) {				UD_FIFO0 = ep_bulk_out_status;				UD_FIFO0 = 0x00;			}			set_ep0_de_in;			break;		case GET_DESCRIPTOR:			get_descriptor(req);			break;		}	}}static voidget_descriptor(usb_dev_request_t req){	string_desc_t *pString;	ep_desc_t * pEndpoint = 0;	desc_t *pDesc = elfin_usb_get_descriptor_ptr();	int type = req.wValue >> 8;	int idx = req.wValue & 0xFF;	switch (type) {	case USB_DESC_DEVICE:		PRINTKD("\nget descriptor() DEV: req.wLengh=%d, pDesc->dev.bength=%d\n\n",		     req.wLength, pDesc->dev.bLength);		clear_ep0_opr;		queue_and_start_write(&pDesc->dev, req.wLength, pDesc->dev.bLength);		break;	case USB_DESC_CONFIG:		clear_ep0_opr;#if defined(CONFIG_S3C2440_USB_CDC_ENCM) || defined(CONFIG_S3C2440_USB_CDC_ENCM_MODULE)		if (pDesc->dev.bDeviceClass == CDC_DEVICE_CLASS) {			queue_and_start_write(&pDesc->cdc_b, req.wLength, 					sizeof (struct cdc_cdb));		} else {			queue_and_start_write(&pDesc->b, req.wLength, 					sizeof (struct cdb));		}#else		queue_and_start_write(&pDesc->b, req.wLength, 					sizeof (struct cdb));#endif /* CONFIG_S3C2440_USB_CDC_ENCM || CONFIG_S3C2440_USB_CDC_ENCM_MODULE */		PRINTKD("\nget descriptor() CONFIG: req.wLengh=%d, pDesc->dev.bength=%d\n\n",		     req.wLength, pDesc->dev.bLength);		break;	case USB_DESC_STRING:		PRINTKD("STRING STRING\n");		pString = elfin_usb_get_string_descriptor(idx);		if (pString) {			if (idx != 0) {	// if not language index				printk("%sReturn string %d: ", pszMe, idx);				psdesc(pString);			}			PRINTKD("\nget descriptor() String: req.wLengh=%d, pDesc->dev.bength=%d\n\n",			     req.wLength, pDesc->dev.bLength);			clear_ep0_opr;			queue_and_start_write(pString, req.wLength, pString->bLength);		}		break;	case USB_DESC_INTERFACE:#if defined(CONFIG_S3C2440_USB_CDC_ENCM) || defined(CONFIG_S3C2440_USB_CDC_ENCM_MODULE)		if (pDesc->dev.bDeviceClass == CDC_DEVICE_CLASS) {			if (idx == pDesc->cdc_b.comm_intf.bInterfaceNumber) {				printk("CDC_DEVICE_CLASS:intf\n");				clear_ep0_opr;				queue_and_start_write(&pDesc->cdc_b.comm_intf,						req.wLength,						pDesc->cdc_b.comm_intf.bLength +						pDesc->cdc_b.func.hdr.bLength +						pDesc->cdc_b.func.uni.bLength +						pDesc->cdc_b.func.eth.bLength);			}#ifdef CDC_ALTERNATE_INTERFACE			else if (idx == pDesc->cdc_b.data_intf0.bInterfaceNumber) {				printk("CDC_DEVICE_CLASS:intf0\n");				clear_ep0_opr;				queue_and_start_write(&pDesc->cdc_b.data_intf0,						req.wLength, pDesc->cdc_b.data_intf0.bLength);			}#endif				/* CDC_ALTERNATE_INTERFACE */			else if (idx == pDesc->cdc_b.data_intf1.bInterfaceNumber) {				printk("CDC_DEVICE_CLASS:intf1\n");				clear_ep0_opr;				queue_and_start_write( &pDesc->cdc_b.data_intf1,						req.wLength, pDesc->cdc_b.data_intf1.bLength);			}		} else {			if (idx == pDesc->b.intf.bInterfaceNumber) {				printk("intf\n");				clear_ep0_opr;				queue_and_start_write(&pDesc->b.intf,						req.wLength, pDesc->b.intf.bLength);			}		}#else		if (idx == pDesc->b.intf.bInterfaceNumber) {			clear_ep0_opr;			queue_and_start_write(&pDesc->b.intf,					req.wLength, pDesc->b.intf.bLength);		}#endif /* CONFIG_S3C2440_USB_CDC_ENCM || CONFIG_S3C2440_USB_CDC_ENCM_MODULE */		break;	case USB_DESC_ENDPOINT: /* correct? 21Feb01ww */		if ( idx == 1 )			pEndpoint = &pDesc->b.ep1; //[BULK_IN1];		else if ( idx == 2 )			pEndpoint = &pDesc->b.ep2; //[BULK_OUT1];		else			pEndpoint = NULL;		if ( pEndpoint ) {			clear_ep0_opr;			queue_and_start_write( pEndpoint,					req.wLength, pEndpoint->bLength );		} else {			printk("%sunkown endpoint index %d Stall.\n", pszMe, idx );		}		break;	default:		clear_ep0_opr;		set_ep0_de_in;		break;	}}static voidep0_transmit(void){	int i, data_length;	__u32 reg_ep0_status;	__u32 reg_int_status;	UD_INDEX = UD_INDEX_EP0;	reg_ep0_status = UD_ICSR1;	PRINTKD("EP0 want to send : %d byte\n", wr.transfer_length);	/* ep0 input fifo check */	if ((reg_ep0_status & EP0_CSR_IPKRDY) == 0) {		data_length = wr.transfer_length - wr.transfered_data;		data_length = MIN(data_length, EP0_FIFO_SIZE);	/* EP0 MAX Packet size */		/* need to check RESET, RESUME and SUSPEND Interrupts */		reg_int_status = UD_USBINT;		reg_int_status &= UD_USBINT_RESET | UD_USBINT_RESUM | UD_USBINT_SUSPND;		if (reg_int_status == UD_USBINT_RESET)			return;		PRINTKD(" SENDING... [");		for (i = 0; i < data_length; i++) {			UD_FIFO0 = *wr.p;			PRINTKD("%2.2X ", *wr.p);			wr.p++;			wr.transfered_data++;		}		PRINTKD("] \n");		PRINTKD("EP0 transfered : %d bytes\n", wr.transfered_data);		PRINTKD("wr.transfered_data = %d, wr.transfer_length = %d\n",			wr.transfered_data, wr.transfer_length);		if (wr.transfered_data == wr.transfer_length) {			reg_int_status = UD_USBINT;			reg_int_status &= UD_USBINT_RESET | UD_USBINT_RESUM | UD_USBINT_SUSPND;			if (reg_int_status == UD_USBINT_RESET)				return;//			if (((wr.transfer_length % 8) == 0) && control_complete == 0) {			if (control_complete == 0) {				control_complete = 1;				set_ep0_ipr;			} else {				control_complete = 0;				set_ep0_de_in;				ep0_state = EP0_STATE_IDLE;			}			return;		}		set_ep0_ipr;	}}static voidset_feature(usb_dev_request_t req){	int ep;	switch (req.wValue) {	case fEndpoint_Halt:		ep = windex_to_ep_num(req.wIndex);		if (ep == 0) {			printk("%sset feature [endpoint halt] on control\n", pszMe);			ep0_status = 0x001;			set_ep0_ss;			clear_ep0_opr;		} else if (ep == 2) {			printk("%set feature [endpoint halt] on xmitter\n", pszMe);			ep_bulk_in_status = 0x0001;			UD_INDEX = UD_INDEX_EP2;			UD_ICSR1 |= UD_ICSR1_CLRDT;			//ep2_stall();		} else if (ep == 1) {			printk("%set feature [endpoint halt] on receiver\n", pszMe);			ep_bulk_out_status = 0x0001;			UD_INDEX = UD_INDEX_EP1;			UD_OCSR1 |= UD_OCSR1_SENDSTL;			//ep1_stall();		} else {			printk ("%sUnsupported feature selector (%d) in set feature\n",			     pszMe, req.wValue);			set_ep0_de_out;		}		break;	case fDevice_Remote_Wakeup:		device_status = 0x02;		set_ep0_de_out;		break;	default:		set_ep0_de_out;		break;	}}static voidclear_feature(usb_dev_request_t req){	int ep;	switch (req.wValue) {	case fEndpoint_Halt:		ep = windex_to_ep_num(req.wIndex);		if (ep == 0)	// ep0			ep0_status = 0x0000;		else if (ep == 2) {	// ep2  input			ep_bulk_in_status = 0x0000;			clear_stall_ep4_out;	// ep4??			PRINTKD(__FUNCTION__ "(): confused. - bushi\n");		} else if (ep == 1) {	// ep1 output			ep_bulk_out_status = 0x0000;			clear_stall_ep1_out;	//??		} else			PRINTKD("%sUnsupported endpoint (%d)\n", pszMe, ep);		set_ep0_de_out;		break;	case fDevice_Remote_Wakeup:		device_status = 0x00;		set_ep0_de_out;		break;	default:		set_ep0_de_out;		break;	}}static void queue_and_start_write( void * data, int req, int act ){	PRINTKD( "write start: bytes requested=%d actual=%d\n", req, act);	wr.p = (unsigned char*) data;	wr.transfer_length = wr.bytes_left = MIN( act, req );	wr.transfered_data = 0;	ep0_state = EP0_STATE_TRANSFER;		ep0_transmit();	return;}static voidset_descriptor(void){	set_ep0_de_out;}static voidep0_receive(void){}/* * read_fifo() * Read 1-8 bytes out of FIFO and put in request. * Called to do the initial read of setup requests * from the host. Return number of bytes read. * * Like write fifo above, this driver uses multiple * reads checked agains the count register with an * overall timeout. * */static intread_fifo(usb_dev_request_t * request){	int bytes_read = 0;	int fifo_count = 0;	int i, ep;	unsigned char *pOut = (unsigned char *) request;	ep = windex_to_ep_num(request->wIndex);	PRINTKD(__FUNCTION__ "(): ep = %d\n", ep);	switch (ep) {	case 0: UD_INDEX = UD_INDEX_EP0; break;	case 1: UD_INDEX = UD_INDEX_EP1; break;	case 2: UD_INDEX = UD_INDEX_EP2; break;	default:		PRINTKD(__FUNCTION__ "(): ???? ep = %d\n", ep);		UD_INDEX = UD_INDEX_EP0;	}	fifo_count = ((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff;	ASSERT(fifo_count <= EP0_FIFO_SIZE);	PRINTKD(__FUNCTION__ "(): fifo_count =%d ", fifo_count);	while (fifo_count--) {		i = 0;		do {			*pOut = (unsigned char) UD_FIFO0;			udelay(10);			i++;		} while ((((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff) != fifo_count			 && i < 10);		if (i == 10) {			printk("%sread_fifo(): read failure\n", pszMe);			usbd_info.stats.ep0_fifo_read_failures++;		}		pOut++;		bytes_read++;	}	PRINTKD("bytes_read=%d\n", bytes_read);	usbd_info.stats.ep0_bytes_read++;	return bytes_read;}/* end usb_ep0.c */

⌨️ 快捷键说明

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