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

📄 devmscd.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 2 页
字号:
} /* End of devmscd_set_command_res *//*  * read URB complete function.  * In case of IDLE state, this is a CBW. Other cases it is a data request * reurn */void devmscd_read_urb_complete(struct pdc_urb *urb){	struct devmscd_device	*dev = &devmscd_dev;	mscd_req_t				*req;	func_debug(("devmscd_read_urb_complete(%p)\n",urb))	switch(dev->state) {		case DEVMSCD_IDLE:			/* This is a CBW packet */			dev->tx_residue = (dev->cbw[8] | (dev->cbw[9] << 8));	   		dev->tx_residue |= ((dev->cbw[10] << 16) | (dev->cbw[11] << 24));			/* Copy the CBW tag to the CSW tag */			dev->csw[4] = dev->cbw[4];        	dev->csw[5] = dev->cbw[5];        	dev->csw[6] = dev->cbw[6];        	dev->csw[7] = dev->cbw[7];			devmscd_change_state(dev, DEVMSCD_CBW);			/* send this command to the mass storage bridge */			mscd_fill_req(	(&bridge_req), MSCD_COMMAND, 							(&dev->cbw[DEVMSCD_CBW_WRAPPER]), 							(DEVMSCD_CBW_LENGTH - DEVMSCD_CBW_WRAPPER), 							devmscd_set_command_res, NULL);			mscdbridge_submit_req(&bridge_req);			if(dev->cbw[12] & DEVMSCD_CBWFLAG_IN) {				/* Data to Host, so Data out from Device */				devmscd_change_state(dev, DEVMSCD_DATA_OUT);			} else {				/* Data from Host, so Data in to Device */				devmscd_change_state(dev, DEVMSCD_DATA_IN);			}			break;		case DEVMSCD_DATA_IN:	   		dev->tx_residue -= urb->actual_length;			req = bridge_read_req;			if(req) {				/* Call the call back function */				req->res_data_len = urb->actual_length;				req->status = MSCD_SUCCESS;				bridge_read_req = NULL;				if(req->complete)	req->complete(req);			}			break;	}	urb->status = PDC_URB_COMPLETE;} /* End of devmscd_read_urb_complete *//*  *  Call the call back function of the bridge request *  If the status stage is already sent by the bridge, finish the status  *  stage */void devmscd_write_urb_complete(struct pdc_urb *urb){	struct devmscd_device	*dev = &devmscd_dev;	mscd_req_t				*req;	struct pdc_pipe_opr		bulk_pipe_opr;	func_debug(("devmscd_write_urb_complete(%p)\n",urb))	dev->tx_residue -= urb->actual_length;	if(dev->status_queue) {		if(dev->tx_residue) {			/* Send a stall */			bulk_pipe_opr.handle = dev->data_out_pipe;			bulk_pipe_opr.context = (unsigned long) dev;			bulk_pipe_opr.opr = PDC_PIPE_STALL;			mdelay(3);			pdc_pipe_operation(&bulk_pipe_opr);					dev->csw[8] = dev->tx_residue & 0xFF;       		dev->csw[9] = (dev->tx_residue >> 8) & 0xFF;			dev->csw[10] = (dev->tx_residue >> 16) & 0xFF;       		dev->csw[11] = (dev->tx_residue >> 24) & 0xFF;		}		/* Already status is received, so send the status */		devmscd_read_data(dev->cbw,DEVMSCD_CBW_LENGTH);		devmscd_write_data(dev->csw, DEVMSCD_CSW_LENGTH);		devmscd_change_state(dev, DEVMSCD_IDLE);		dev->status_queue = 0;	}	if(devmscd_dev.state != DEVMSCD_CSW) {		/* Update the transfer residue *///		devmscd_dev.tx_residue -= urb->actual_length;		req = bridge_write_req;		if(req) {			/* call the bridge call back function */			req->res_data_len = urb->actual_length;			req->status = MSCD_SUCCESS;			bridge_write_req = NULL;			if(req->complete)	req->complete(req);		}	}	urb->status = PDC_URB_COMPLETE;} /* End of devmscd_write_urb_complete *//*  * Bulk Only Trnasport, Mass storage reset. * Go back to Idle state, no transfer residue. */void devmscd_reset(struct devmscd_device *dev){		func_debug(("devmscd_reset(%p)\n",dev))	devmscd_change_state(dev, DEVMSCD_IDLE);	dev->tx_residue = 0x00;	dev->status_queue = 0;	read_urb.status = PDC_URB_COMPLETE;	write_urb.status = PDC_URB_COMPLETE;		/* Initialize the CSW signature */	dev->csw[0] = 0x55; 	dev->csw[1] = 0x53; 	dev->csw[2] = 0x42; 	dev->csw[3] = 0x53;} /* End of devmscd_reset */int devmscd_configure(void *__dev, unsigned char cfg){	struct devmscd_device	*dev = (struct devmscd_device *)__dev;	if(dev) {		if(cfg) {			devmscd_reset(dev);				dev->data_in_pipe = PDC_INV_PIPE_HANDLE;			dev->data_out_pipe = PDC_INV_PIPE_HANDLE;			/* Configure the device */			dev->data_in_pipe = pdc_open_pipe(&bulk_pipe_desc[0]);			if(dev->data_in_pipe != PDC_INV_PIPE_HANDLE) {				dev->data_out_pipe = pdc_open_pipe(&bulk_pipe_desc[1]);				if(dev->data_out_pipe != PDC_INV_PIPE_HANDLE) {					/* Start waiting for CBW data */					devmscd_read_data(dev->cbw,DEVMSCD_CBW_LENGTH);				} else {					pdc_close_pipe(dev->data_in_pipe);					dev->data_in_pipe = PDC_INV_PIPE_HANDLE;				}			}		} else {				/* Cancel all data requests to the device */				if(read_urb.status == PDC_URB_PENDING) pdc_cancel_urb(&read_urb);				/* Un configure the device */				if(dev->data_in_pipe != PDC_INV_PIPE_HANDLE) {					pdc_close_pipe(dev->data_in_pipe);					dev->data_in_pipe = PDC_INV_PIPE_HANDLE;				}				if(dev->data_out_pipe != PDC_INV_PIPE_HANDLE) {					pdc_close_pipe(dev->data_out_pipe);					dev->data_out_pipe = PDC_INV_PIPE_HANDLE;				}						devmscd_reset(dev);			}		}	return 0;}/* * The class request can have the following return values * == 0 success and no data to send/receive * >  0 success data stage is needed through dev urb * < 0  failure of the command, send stall * */int devmscd_class_req(void *__dev, __u8	*req){	__u8	cls_req = req[1];	int		result;	struct devmscd_device	*dev = (struct devmscd_device *)__dev;	func_debug(("devmscd_class_req(%p)\n",req))	switch(cls_req) {		case DEVMSCD_MS_RESET:			detail_debug(("DEVMSCD_RESET\n"))			/* Inform the mass storage bridge about the reset */			mscd_fill_req(&bridge_req, MSCDBRIDGE_RESET, NULL, 0x00, NULL, NULL);			mscdbridge_submit_req(&bridge_req);			/* Reset internal variables */			devmscd_reset(dev);				result =  0;			break;		case DEVMSCD_GET_MAX_LUN:			/*			 * This command is not supported by this class driver 			 */			result =  -1;			break;		default:			result =  -1;			break;	}	return result;} /* devmscd_class_req */struct pdc_class_drv devmscd_drv = {	name:			DRIVER_NAME,	class_vendor:	devmscd_class_req,	set_config:		devmscd_configure,	set_intf:		NULL,	priv_data:		&devmscd_dev,};/* * module initialization function * Initialize the physical disk. * Register the class driver with the functional interface to the  * peripheral controller driver and wait for the it to call connect * function */static int __init devmscd_module_init (void) {	int	result;	func_debug(("devmscd_module_init(void)\n"))	bridge_read_req = NULL;	bridge_write_req = NULL;	bulk_pipe_desc[0].ep = 1;	bulk_pipe_desc[0].ep_dir = PDC_EP_DIR_OUT;	bulk_pipe_desc[0].context = (unsigned long)(&devmscd_drv);	bulk_pipe_desc[0].priv = (void*)(&devmscd_drv);	bulk_pipe_desc[0].notify = NULL;	bulk_pipe_desc[1].ep = 2;	bulk_pipe_desc[1].ep_dir = PDC_EP_DIR_IN;	bulk_pipe_desc[1].context = (unsigned long)(&devmscd_drv);	bulk_pipe_desc[1].priv = (void*)(&devmscd_drv);	bulk_pipe_desc[1].notify = NULL;	/* Initialize mass storage bridge */	mscd_fill_req(&bridge_req, MSCDBRIDGE_INIT, NULL, 0x00, NULL, NULL);	result = mscdbridge_submit_req(&bridge_req);	if(result < 0) return result;	/* register to the device controller driver */	return pdc_register_class_drv(&devmscd_drv);} /* End of devmscd_module_init *//* * module close function * shutdown the physical disk * unregister the class driver from the peripheral controller driver. */static void __exit devmscd_module_cleanup (void) {	func_debug(("devmscd_module_cleanup(void)\n"))	/* de-register to the device controller driver */	pdc_deregister_class_drv(&devmscd_drv);		/* Notify the bridge that we are going off */	mscd_fill_req(&bridge_req, MSCDBRIDGE_DEINIT, NULL, 0x00, NULL, NULL);	mscdbridge_submit_req(&bridge_req);	return;} /* End of devmscd_module_cleanup */module_init (devmscd_module_init);module_exit (devmscd_module_cleanup);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_AUTHOR(DRIVER_AUTHOR);

⌨️ 快捷键说明

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