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

📄 pdc_bus.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 2 页
字号:
	}} /* End of pdc_bus_set_interface() */void pdc_bus_get_status(__u8 *command){	unsigned char reply[4];	__u8	bmRequestType = command[0];	pdc_pipe_handle_t		handle;	__u8	reply_len = 2;	if((bus_dev->state < PDC_BUS_ADDRESSED) || !(command[0]&PDC_REQTYPE_DIR_MASK)) {		/* You are not supposed to receive this in these states */		pdc_bus_stall_control_pipe();		return;	}	/* Find request target */	switch (bmRequestType&0x03) {		case RECIP_DEVICE:          /* DEVICE */  			reply[0] = PDC_GETSTATUS_SELF_POWERED;			reply[1]=0;			break;		case RECIP_INTERFACE:       /* INTERFACE */  			reply[0]=0;			reply[1]=0;			break;				case RECIP_ENDPOINT: 			/* reply[0] needs to be 1 if the endpoint			referred to in command[3] is stalled,			otherwise 0 */			/* ep->pipe handle and context conversion */			handle = pdc_usb_to_epreg((command[4]&0x0F),(command[4]&0x80));				/* Check EP status */			ctrl_pipe_opr.handle = handle;			ctrl_pipe_opr.context = (unsigned long) bus_dev;			ctrl_pipe_opr.opr = PDC_GET_PIPE_STATUS;			pdc_pipe_operation(&ctrl_pipe_opr);			reply[0] = (ctrl_pipe_opr.pipe_status & PDC_PIPE_STALL) ? 1 : 0;			reply[1]=0;				break;				default:                        /* UNDEFINED */   			/* Stall endpoints 0 & 1 */			reply_len = 0;			return;	}		/* Write this packet */	pdc_nofif_write_control_pipe(reply, reply_len);	return;} /* End of pdc_bus_get_status() */void pdc_bus_usb_feature(__u8	*command){	__u8	bmRequestType = command[0];	__u8	inv_state = PDC_BUS_ADDRESSED;	/*      * For USB 2.0 Suppliment OTG 1.0 Specification,     * Set feature will be accepted in default state also      */	if(command[1]==SET_FEATURE) inv_state = PDC_BUS_DEFAULT;	if((bus_dev->state < inv_state) || (command[0]&PDC_REQTYPE_DIR_MASK)) {		/* You are not supposed to receive this in these states */		pdc_bus_stall_control_pipe();		return;	}	switch (bmRequestType & 0x03) {		case RECIP_DEVICE:		if (command[2]==PDC_FEATURE_REMOTE_WAKEUP) {			pdc_nofif_write_control_pipe(NULL, 0);		}#ifdef CONFIG_USB_HCDC_OTG		else if ((command[2]==PDC_FEATURE_B_HNP_ENABLE)||				(command[2]==PDC_FEATURE_A_HNP_SUPPORT)||				(command[2]==PDC_FEATURE_A_ALTHNP_SUPPORT))		{			pdc_nofif_write_control_pipe(NULL, 0);			//inform the OTG module of this			if( bus_dev->otg && bus_dev->otg->otg_notif) {				bus_dev->otg->otg_notif(bus_dev->otg->priv_data, PDC_SET_HNP,command[2]);			}		}#endif /* CONFIG_USB_HCDC_OTG */		else {			/* CF_WINDEX_FIX */			/* Stall endpoints 0 & 1 */			pdc_bus_stall_control_pipe();		}		break;							/* INTERFACE */  		case RECIP_INTERFACE:			pdc_nofif_write_control_pipe(NULL, 0);			break;							/* ENDPOINT */		case RECIP_ENDPOINT:  		{			/* Find endpoint */			pdc_pipe_handle_t handle;			int stall=(command[1]==SET_FEATURE);			handle = pdc_usb_to_epreg((command[4]&0x0F),(command[4]&0x80));			detail_debug(("pdc: endpoint stall(%d)\n",handle))			/* Set/clear endpoint stall flag */			ctrl_pipe_opr.handle = handle;			ctrl_pipe_opr.context = (unsigned long) bus_dev;			if (stall) {				ctrl_pipe_opr.opr = PDC_PIPE_STALL;			} else if(handle > 0x01) {				/* For Control In & Out already unstalled by					HW */				ctrl_pipe_opr.opr = PDC_PIPE_UNSTALL;			}			pdc_pipe_operation(&ctrl_pipe_opr);			/* 0-byte ACK */			pdc_nofif_write_control_pipe(NULL, 0);		}		break;						/* UNDEFINED */   		default:              			/* Stall endpoints 0 & 1 */			pdc_bus_stall_control_pipe();			break;	}}/* Deal with get_descriptor */void pdc_bus_get_descriptor(__u8 *command){	__u8	*desc_ptr = NULL;	__u16	desc_len = 0, req_len;	func_debug(("get_descriptor(command=%p)\n",command))	if((bus_dev->state < PDC_BUS_ADDRESSED) && !(command[0]&PDC_REQTYPE_DIR_MASK)) {		/* You are not supposed to receive this in these states */		pdc_bus_stall_control_pipe();		return;	}	switch( command[3]) {		case PDC_DEV_DESC_TYPE:			desc_ptr = device_desc;			desc_len = sizeof(device_desc);			break;		case PDC_CONFIG_DESC_TYPE:			if(command[2] < PDC_BUS_NUM_CONFIG) {				desc_ptr = conf_desc;				desc_len = sizeof(conf_desc);			}			break;		case PDC_STRING_DESC_TYPE:			switch(command[2]) {				case 0:					desc_ptr = unicode_string;					desc_len = sizeof(unicode_string);					break;								case 1:					desc_ptr = mfg_string;					desc_len = sizeof(mfg_string);					break;				case 2:					desc_ptr = product_string;					desc_len = sizeof(product_string);										break;				case 3:					desc_ptr = serial_string;					desc_len = sizeof(serial_string);				default:					break;			}			break;#ifdef CONFIG_USB_HCDC_OTG		case PDC_OTG_DESC_TYPE:			desc_ptr = &conf_desc[PDC_CONFIG_DESC_LEN+PDC_INTF_DESC_LEN+2*PDC_EP_DESC_LEN];			desc_len = desc_ptr[0];			break;#endif /* CONFIG_USB_HCDC_OTG */		default:			break;	}		if(desc_ptr) {		/* Get max length that remote end wants */		req_len =command[6]|(command[7]<<8);		if (desc_len > req_len ) {			desc_len = req_len ;    		}			pdc_nofif_write_control_pipe(desc_ptr, desc_len);	} else {		pdc_bus_stall_control_pipe();	}	return;} /* End of pdc_bus_get_descriptor() */int	pdc_nofif_write_control_pipe(__u8	*buff, __u16	len){	struct pdc_urb	*urb  = &bus_dev->ctrl_write_urb;	if(!buff) len = 0;	/* Fill the URB and submit it */	pdc_fill_non_iso_urb(urb, bus_dev->ctrl_pipe, PDC_PIPE_CONTROL, 						PDC_OPR_WRITE, buff, len, NULL,NULL);	return pdc_submit_urb(urb);} /* End of pdc_nofif_write_control_pipe() */void pdc_bus_stall_control_pipe(void){		/* Stall Control Out Pipe */	ctrl_pipe_opr.handle = bus_dev->ctrl_pipe;	ctrl_pipe_opr.context = (unsigned long) bus_dev;	ctrl_pipe_opr.opr = PDC_PIPE_STALL;	pdc_pipe_operation(&ctrl_pipe_opr);} /* End of pdc_bus_stall_control_pipe() */int pdc_bus_ctrl_pipe_notificaion(unsigned long notif_type, void *priv,unsigned char	*cmd){	__u8	RequestType;	__u8	bmRequest ;	int		result = -1;	__u8	reply[2];	struct list_head *tmp;	if(notif_type == PDC_SETUP_COMMAND) {		/* SETUP Command from the control pipe */		RequestType = cmd[0] & 0x60;				switch(RequestType) {			case STANDARD_REQUEST:				/* Process USB Standrad request */   				bmRequest = cmd[1];				switch (bmRequest) {					case GET_DESCRIPTOR:						pdc_bus_get_descriptor(cmd);						break;					case CLEAR_FEATURE:					case SET_FEATURE:						pdc_bus_usb_feature(cmd);						break;					case SET_ADDRESS:						/* 						 * Set the address in the device controller						 * and send the status back to the Host						 */						if((bus_dev->state != PDC_BUS_DEFAULT) || (cmd[0]&PDC_REQTYPE_DIR_MASK)) {							pdc_bus_stall_control_pipe();						} else {							pdc_set_device_address((unsigned long)bus_dev->pdc_config,(cmd[2]&0x7F));							pdc_nofif_write_control_pipe(NULL, 0);										bus_dev->state = PDC_BUS_ADDRESSED;						}						break;					case SET_CONFIGURATION:						pdc_bus_set_configuration(cmd);						break;					case SET_INTERFACE:							pdc_bus_set_interface(cmd);						break;					case GET_CONFIGURATION:							/* 						 * Send the current configuration, the status stage is taken care						 * by the device controller						 */						if((bus_dev->state >= PDC_BUS_DEFAULT) && (cmd[0]&PDC_REQTYPE_DIR_MASK)) {							reply[0] = bus_dev->configuration;							pdc_nofif_write_control_pipe(reply, 1);						} else {							pdc_bus_stall_control_pipe();						}						break;					case GET_INTERFACE:							/* 						 * Send the current configuration, the status stage is taken care						 * by the device controller						 */						if((bus_dev->state >= PDC_BUS_CONFIGURED) && (cmd[0]&PDC_REQTYPE_DIR_MASK)) {							reply[0] = bus_dev->interface;							pdc_nofif_write_control_pipe(reply, 1);						} else {							/* You are not supposed to receive this in these states */							pdc_bus_stall_control_pipe();						}						break;					case GET_STATUS:									pdc_bus_get_status(cmd);						break;					default:						/* SET_DESCRIPTOR, SYNCH_FRAME TODO */						/* Other requests are not known to us */						pdc_bus_stall_control_pipe();						break;				}				break;			case CLASS_REQUEST:			case VENDOR_REQUEST:				/* Process Class Vendor request */				/* Find the class driver that supports this request */				tmp = pdc_class_drv_list.next;				while (tmp != &pdc_class_drv_list) {					struct pdc_class_drv *cd = list_entry(tmp,struct pdc_class_drv, driver_list);					tmp = tmp->next;					if(cd->class_vendor) {						/* Currently done for only one class driver */						result = cd->class_vendor(cd->priv_data, cmd);						break;					}				}				if(result == 0){					pdc_nofif_write_control_pipe(NULL, 0);				}					if(result < 0){					/* Stall control in and out pipes */					pdc_bus_stall_control_pipe();				}				break;			default:				/* All other requests need to be stalled */				pdc_bus_stall_control_pipe();				break;		}				}	return 0;} /* End of pdc_bus_ctrl_pipe_notifacaion() *//*-----------------------------------------------------------------* *                     External OTG interface functions            * *-----------------------------------------------------------------*/#ifdef CONFIG_USB_HCDC_OTGint		pdc_otg_register(pdc_otg_data_t	*otg_data){		if( bus_dev && otg_data ) {		detail_debug(("Registered OTG device with device\n"))		otg_data->dc_priv_data = (void*)bus_dev;		bus_dev->otg = otg_data;		return 0;	}	return -1;}void	pdc_otg_unregister(pdc_otg_data_t	*otg_data) {	if(bus_dev && otg_data) {		detail_debug(("De-registered OTG device with device\n"))		otg_data->dc_priv_data = NULL;		bus_dev->otg = NULL;	}}void    pdc_otg_control(void *priv, unsigned long opr){	struct list_head *tmp;	pdc_dev_control(opr);	switch(opr) {		case PDC_ENABLE:		bus_dev->state = PDC_BUS_ATTACHED;		break;		case PDC_DISABLE:			bus_dev->state = PDC_BUS_INIT;			if(bus_dev->configuration) {				bus_dev->configuration = 0;				/* Find the class driver that supports this request */				tmp = pdc_class_drv_list.next;				while (tmp != &pdc_class_drv_list) {					struct pdc_class_drv *cd = list_entry(tmp,struct pdc_class_drv, driver_list);					/* Currently done for only one class driver */					if(cd->set_config)	cd->set_config(cd->priv_data,bus_dev->configuration);					tmp = tmp->next;				}			}			break;	}}#endif /* CONFIG_USB_HCDC_OTG */

⌨️ 快捷键说明

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