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

📄 usb_pdc.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 3 页
字号:
} /* End of pdc_open_pipe() *//* * Close an already opened pipe * @pipe_handle:	pipe handle */void pdc_close_pipe(pdc_pipe_handle_t   pipe_handle){	__u8	ep;	struct pdc_pipe *pipe;    struct pdc_dev 		*pdc=usb_devices;	func_debug(("pdc_close_pipe(pipe_handle=%x)\n",pipe_handle))	if(pipe_handle < PDC_MAX_PIPES) {		pipe = pdc->ep_pipes + pipe_handle;		/* If the pipe is opened then cleanup the stuff */		if(pipe->ep_state == PDC_PIPE_OPEN) {			pipe->pipe_desc =  NULL;			pipe->ep_state = PDC_PIPE_CONFIG;		}		/* 		 * Get the endpoint and if it is control ep then close		 * the control IN pipe also		 */   		ep = pdc_pipe_to_epreg(pipe_handle); 		if(ep == 0) {			pdc_close_pipe(pipe_handle + 1);		}	}} /* End of pdc_close_pipe() */int pdc_submit_control_urb(struct pdc_dev	*pdc, struct pdc_urb *urb_req){	struct pdc_pipe	*pipe;	struct pdc_urb	*urb;	unsigned long	length;	pdc_pipe_handle_t	handle = urb_req->pipe;	func_debug(("pdc_submit_control_urb(urb=%p)\n",urb_req))		if(urb_req->operation == PDC_OPR_WRITE) handle += 1;	/* Control IN pipe */	pipe = pdc->ep_pipes + handle;	urb = pipe->urb;	/* Insert the URB in to the pipe URB queue (FIFO) */	if(!urb) {		pipe->urb  = urb_req;	} else {		while(urb) {			if(urb->next != NULL)	urb = urb->next;			else urb->next = urb_req;		}	}	/* set the output parameters */	urb_req->actual_length = 0;	urb_req->next = NULL;	if(urb_req->operation == PDC_OPR_WRITE) {		if(pipe->urb == urb_req)	{			length = urb_req->transfer_buffer_length;			if(urb_req->transfer_buffer_length > pipe->ep_desc->max_pkt_size) {				length = pipe->ep_desc->max_pkt_size;			}			writeendpoint(handle,urb_req->transfer_buffer,length);			urb_req->actual_length += length;		}		if(urb_req->actual_length == urb_req->transfer_buffer_length) {			urb_req->status = PDC_URB_COMPLETE;			pipe->urb = urb_req->next;			if(urb_req->complete) urb_req->complete(urb);		}	} else if(urb_req->operation == PDC_OPR_READ) {		/* TODO */	}	return 0;}/* * Submit an urb for data transfer * @urb: urb request block */int pdc_submit_urb(struct pdc_urb *urb_req){	struct pdc_pipe	*pipe;	struct pdc_urb	*urb;	unsigned long flags;    struct pdc_dev 		*pdc=usb_devices;	func_debug(("pdc_submit_urb(urb=%p)\n",urb_req))	if(urb_req->pipe > PDC_MAX_PIPES)	return -EINVAL;	if(urb_req->pipe < 2)	return pdc_submit_control_urb(pdc, urb_req);	pipe = pdc->ep_pipes + urb_req->pipe;	spin_lock_irqsave(&pdc_rdwr_lock, flags);	urb = pipe->urb;	/* Insert the URB in to the pipe URB queue (FIFO) */	if(!urb) {		pipe->urb  = urb_req;	} else {		while(urb) {			if(urb->next != NULL)	urb = urb->next;			else urb->next = urb_req;		}	}	/* set the output parameters */	urb_req->actual_length = 0;	urb_req->next = NULL;	if(urb_req->operation == PDC_OPR_READ) {		/* 		 * handle the read request, if there are no URB's,		 * call the rx_data function 		 */		if(pipe->urb == urb_req)	{			rx_data(pdc, urb_req->pipe);		}	} else if(urb_req->operation == PDC_OPR_WRITE) {		/*		 * Handle the write request.		 * If the Pipe is not stalled and the transmission is idle		 * start the transmission		 */		pipe->ep_status = (pdc_read16(CMD_CHECKEPSTATUS+(urb_req->pipe)) & STATUS_EPSTAL) ? PDC_PIPE_STALL : PDC_PIPE_UNSTALL ;		if(pipe->txrx_idle && pipe->ep_status != PDC_PIPE_STALL) {			tx_data(pdc, urb_req->pipe, 1);	/* Kick the transfer */		}	}	spin_unlock_irqrestore(&pdc_rdwr_lock, flags);	return 0;} /* End of pdc_submit_urb *//* * Cancel an urb for data transfer * @urb: urb request block */int pdc_cancel_urb(struct pdc_urb *urb_req){	struct pdc_pipe	*pipe;	struct pdc_urb	*urb, *prev_urb;	unsigned long flags;    struct pdc_dev 		*pdc=usb_devices;	func_debug(("pdc_cancel_urb(%p)\n",urb_req))	/* Check the pipe value */	if(urb_req->pipe > PDC_MAX_PIPES)	return -EINVAL;	pipe = pdc->ep_pipes + urb_req->pipe;	if((urb_req->pipe == 0) && (urb_req->operation == PDC_OPR_WRITE)) {		/* Special case of control IN pipe */		pipe++;	}	spin_lock_irqsave(&pdc_rdwr_lock, flags);	prev_urb = NULL;	urb = pipe->urb;	/* 	 * search for the URB , The pipe could be either IN or OUT so there is	 * only one URB list 	 */	while((urb!=NULL) && (urb_req != urb)) {		prev_urb = urb;		urb = urb->next;	}	/* 	 * found URB, then Un link it from the list	 */	if(urb) {		urb->status = PDC_URB_COMPLETE;		if(prev_urb)	prev_urb->next = urb->next;		else pipe->urb = urb->next;	}	spin_unlock_irqrestore(&pdc_rdwr_lock, flags);	return 0;} /* End of pdc_cancel_urb *//* * Pipe operations * @pipe_opr: */int pdc_pipe_operation(struct pdc_pipe_opr   *pipe_opr){	struct pdc_pipe	*pipe;	__u16	status;    struct pdc_dev 		*pdc=usb_devices;	pdc_pipe_handle_t	handle = pipe_opr->handle;	func_debug(("pdc_pipe_control(pipe_opr=%p)\n",pipe_opr))	if(handle < PDC_MAX_PIPES) {		pipe = pdc->ep_pipes + handle;			switch(pipe_opr->opr) {			case PDC_PIPE_STALL:				pdc_command(CMD_STALLEP+handle);				if(handle == EP0OUT) pdc_command(CMD_STALLEP+handle+1);	/* Stall control in also */							break;			case PDC_PIPE_UNSTALL:				pdc_command(CMD_UNSTALLEP+handle);				if(handle == EP0OUT) pdc_command(CMD_UNSTALLEP+handle+1);	/* untall control in also */			 	if(handle > EP0IN) {					if(pipe->ep_desc->ep_dir & PDC_EP_DIR_IN)						tx_data(pdc, handle, 2);					else 						rx_data(pdc, handle);				}				break;			case PDC_GET_PIPE_STATUS:				status = pdc_read16(CMD_READEPSTATUS+handle);				pipe_opr->pipe_status = (status&STATUS_EPSTAL) ? PDC_PIPE_STALL :PDC_PIPE_UNSTALL; 				break;		}		return 0;	}	return -1;} /* End of pdc_pipe_operation() *//*--------------------------------------------------------------* *          Device Controller intialization functions *--------------------------------------------------------------*//* Initialisation of the Peripheral Controller */void pdc_init(struct isp1362_dev	*dev){	func_debug(("pdc_init(dev=%p)\n",dev))	/* set the ISP1362 Device controller Hardware Configuration */	isp1362_set_hw_config(dev);	/* Set DMA mode (no dma) */	pdc_write16(CMD_WRITEDMACONFIG,0);	/*bledia Disable all interrupts */	pdc_write32(CMD_WRITEIRQENABLE,0);	/* Set default address */	pdc_write16(CMD_WRITEADDRESS,0);		return;} /* End of pdc_init *//* Actually connect to the bus */void pdc_connect(void){	/* Set device address & enable */	pdc_write16(CMD_WRITEADDRESS,ADDRESS_DEVEN|0);	/* Enable interrupts */	pdc_write32(CMD_WRITEIRQENABLE,IE_EP0OUT|IE_EP0IN|IE_RST|IE_SUSP);	/* Connect to the bus */	pdc_write16(CMD_WRITEMODE,MODE_SOFTCT|MODE_INTENA);	return;} /* End of pdc_connect *//*---------------------------------------------------------------------* *                   ISP1362 HOSAL interface functions                 * *---------------------------------------------------------------------*/struct isp1362_driver	pdc_driver = {	name:		"usb-pdc",	index:		ISP1362_DC,	probe:		pdc_probe,	remove:		pdc_remove,};/* Device initialisation */int pdc_probe (struct isp1362_dev	*dev) {    struct pdc_dev *pdc=usb_devices;	int result, i;	struct pdc_pipe	*pipe;	func_debug(("pdc_probe(dev=%p)\n",dev))	/* Grab the IO resources */	result = isp1362_check_io_region(dev);	if(result < 0) {		detail_debug(("%s IO resources are not free\n","isp1362-pdc"))		return result;	}	isp1362_request_io_region(dev);	pdc->dev = dev;	isp1362_dc_dev = dev;	for(i=0; i< PDC_MAX_PIPES;i++) {		pipe = pdc->ep_pipes + i;		pipe->urb = NULL;		pipe->txrx_idle = 1;		pipe->ep_state = PDC_PIPE_UNCONFIG;		pipe->ep_desc = NULL;	}	/* Configure the default end points */	/* Configure the control OUT pipe */	pipe = pdc->ep_pipes;	pipe->ep_desc = &pdc_ctrl_ep_desc[0];	pipe->ep_desc->ep_num = 0;	pipe->ep_desc->ep_dir = PDC_EP_DIR_OUT;	pipe->ep_desc->attributes = PDC_EP_CONTROL;	pipe->ep_desc->max_pkt_size = 64;	pipe->ep_state = PDC_PIPE_CONFIG;	/* configure the control IN pipe */	pipe = pdc->ep_pipes + 1;	pipe->ep_desc = &pdc_ctrl_ep_desc[1];	pipe->ep_desc->ep_num = 0;	pipe->ep_desc->ep_dir = PDC_EP_DIR_IN;	pipe->ep_desc->attributes = PDC_EP_CONTROL;	pipe->ep_desc->max_pkt_size = 64;	pipe->ep_state = PDC_PIPE_CONFIG;	pdc_bus_init(pdc);	/* Do chip setup */	pdc_init(dev);	/* Claim USB IRQ */	result=isp1362_request_irq(pdc_isr,dev,pdc);	/* Got it ok? */	if (result < 0) {		detail_debug((KERN_ERR "usb-pdc:Can't get USB device IRQ %d.\n", dev->irq))		return result;	}	detail_debug(("usb-pdc:device IRQ is initialised, Irq is  %04x\n",dev->irq))	/* If there are pending IRQs, process them as we can only	   detect edges */#ifndef CONFIG_USB_HCDC_OTG	/* All ready! */	pdc_connect();#endif /* CONFIG_USB_HCDC_OTG */	dev->driver_data = pdc;	detail_debug(("pdc:Philips USB device driver in INIT.\n"))	return 0;} /* End of pdc_probe */void pdc_remove (struct isp1362_dev	*dev) {    struct pdc_dev *pdc=(struct pdc_dev*)dev->driver_data;	func_debug(("pdc_remove(dev=%p)\n",dev))	pdc_bus_deinit();	/* Go off bus */	pdc_write16(CMD_WRITEADDRESS,0);	/* Turn off IRQs */	pdc_write32(CMD_WRITEIRQENABLE,0);	/* Global IRQ disable & turn off softconnect */	pdc_write16(CMD_WRITEMODE,0);	/* Free IRQ */	isp1362_free_irq(dev,pdc);	isp1362_release_io_region(dev);	/* release IO space */	pdc->dev = NULL;	isp1362_dc_dev = NULL;	pdc->ep_pipes = pdc_eps;} /* End of pdc_remove *//* * This is module init function * This function registers the PDC driver to ISP1362 HOSAL driver * which in turn calls the probe function when the dev is found */static int __init pdc_module_init (void) {	struct pdc_dev  *pdc = usb_devices;	func_debug(("pdc_module_init(void)\n"))	pdc->dev = NULL;	pdc->ep_pipes = pdc_eps;	isp1362_dc_dev = NULL;	return isp1362_register_driver(&pdc_driver);} /* End of pdc_module_init *//* * This is module cleanup function * Unregister from isp1362 HOSAL layer which in turn calls  * Close function */static void __exit pdc_module_cleanup (void) {		func_debug(("pdc_module_cleanup (void)\n"))	return isp1362_unregister_driver(&pdc_driver);} /* End of pdc_module_cleanup */module_init (pdc_module_init);module_exit (pdc_module_cleanup);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_AUTHOR(DRIVER_AUTHOR);

⌨️ 快捷键说明

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