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

📄 hc_sl811_rh.c~

📁 基于linux嵌入式操作系统,sl811芯片的usb驱动源代码以及例子和Makefile.
💻 C~
📖 第 1 页 / 共 2 页
字号:
/*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* * SL811HS virtual root hub *   * based on usb-ohci.c by R. Weissgaerber et al. *-------------------------------------------------------------------------* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *-------------------------------------------------------------------------*/#ifdef DEBUG#undef DEBUG#endifstatic __u32 getPortStatusAndChange(hci_t *hci);static void setPortStatus(hci_t *hci, __u16 bitPos);static void setPortChange(hci_t *hci, __u16 bitPos);static void clrPortStatus(hci_t *hci, __u16 bitPos);static void clrPortChange(hci_t *hci, __u16 bitPos);static int USBReset(hci_t *hci);static int cc_to_error (int cc);/*-------------------------------------------------------------------------* * Virtual Root Hub  *-------------------------------------------------------------------------*/ /* Device descriptor */static __u8 root_hub_dev_des[] ={	0x12,       /*  __u8  bLength; */	0x01,       /*  __u8  bDescriptorType; Device */	0x10,	    /*  __u16 bcdUSB; v1.1 */	0x01,	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */	0x00,	    /*  __u8  bDeviceSubClass; */	0x00,       /*  __u8  bDeviceProtocol; */	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */	0x00,       /*  __u16 idVendor; */	0x00,	0x00,       /*  __u16 idProduct; */ 	0x00,	0x00,       /*  __u16 bcdDevice; */ 	0x00,	0x00,       /*  __u8  iManufacturer; */	0x02,       /*  __u8  iProduct; */	0x01,       /*  __u8  iSerialNumber; */	0x01        /*  __u8  bNumConfigurations; */};/* Configuration descriptor */static __u8 root_hub_config_des[] ={	0x09,       /*  __u8  bLength; */	0x02,       /*  __u8  bDescriptorType; Configuration */	0x19,       /*  __u16 wTotalLength; */	0x00,	0x01,       /*  __u8  bNumInterfaces; */	0x01,       /*  __u8  bConfigurationValue; */	0x00,       /*  __u8  iConfiguration; */	0x40,       /*  __u8  bmAttributes;                     Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup,                     4..0: resvd */	0x00,       /*  __u8  MaxPower; */      	/* interface */	  	0x09,       /*  __u8  if_bLength; */	0x04,       /*  __u8  if_bDescriptorType; Interface */	0x00,       /*  __u8  if_bInterfaceNumber; */	0x00,       /*  __u8  if_bAlternateSetting; */	0x01,       /*  __u8  if_bNumEndpoints; */	0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */	0x00,       /*  __u8  if_bInterfaceSubClass; */	0x00,       /*  __u8  if_bInterfaceProtocol; */	0x00,       /*  __u8  if_iInterface; */     	/* endpoint */	0x07,       /*  __u8  ep_bLength; */	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */ 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */ 	0x02,       /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ 	0x00,	0xff        /*  __u8  ep_bInterval; 255 ms */};/* Hub class-specific descriptor is constructed dynamically *//*************************************************************************** * Function Name : rh_send_irq *  * This function examine the port change in the virtual root hub. *  * Note: This function assumes only one port exist in the root hub. * * Input:  hci = data structure for the host controller *         rh_data = The pointer to port change data *         rh_len = length of the data in bytes * * Return: length of data   **************************************************************************/static int rh_send_irq (hci_t * hci, void * rh_data, int rh_len){    int num_ports;    int i;    int ret;    int len;    __u8 data[8];		    DBGFUNC ("enter rh_send_irq: \n");    /* Assuming the root hub has one port.  This value need to change if     * there are more than one port for the root hub     */    num_ports = 1; 	    /* The root hub status is not implemented, it basically has two fields:     *     -- Local Power Status     *     -- Over Current Indicator     *     -- Local Power Change     *     -- Over Current Indicator     *     * Right now, It is assume the power is good and no changes      */    *(__u8 *) data = 0;	       ret = *(__u8 *) data;    /* Has the port status change within the root hub: It checks for     *      -- Port Connect Status change     *      -- Port Enable Change     */      for ( i = 0; i < num_ports; i++)     {        *(__u8 *) (data + (i + 1) / 8) |= (((getPortStatusAndChange (hci) >> 16)		    & (PORT_CONNECT_STAT | PORT_ENABLE_STAT)) ? 1: 0) <<                     ((i + 1) % 8);	ret += *(__u8 *) (data + (i + 1) / 8);			/* After the port change is read, it should be reset so the next time 	 * is it doesn't trigger a change again */		    }    len = i/8 + 1;  	    if (ret > 0)     { 	memcpy (rh_data, data, min (len, min (rh_len, sizeof(data))));	return len;    }	    return 0;}/*************************************************************************** * Function Name : rh_int_timer_do *  * This function is called when the timer expires.  It gets the the port  * change data and pass along to the upper protocol. *  * Note:  The virtual root hub interrupt pipe are polled by the timer *        every "interval" ms * * Input:  ptr = ptr to the urb * * Return: none   **************************************************************************/static void rh_int_timer_do (unsigned long ptr){    int len;     urb_t * urb = (urb_t *) ptr;    hci_t * hci = urb->dev->bus->hcpriv;    DBGFUNC ("enter rh_int_timer_do\n");    if(hci->rh.send)     {         len = rh_send_irq (hci, urb->transfer_buffer,                            urb->transfer_buffer_length);	if (len > 0)          {	    urb->actual_length = len;	    if (urb_debug == 2)	        urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe));	    if (urb->complete)            {		urb->complete (urb);            }	}    }    /* re-activate the timer */    rh_init_int_timer (urb);}/*************************************************************************** * Function Name : rh_init_int_timer *  * This function creates a timer that act as interrupt pipe in the * virtual hub.    *  * Note:  The virtual root hub's interrupt pipe are polled by the timer *        every "interval" ms * * Input: urb = USB request block  * * Return: 0   **************************************************************************/static int rh_init_int_timer (urb_t * urb) {    hci_t * hci = urb->dev->bus->hcpriv;    hci->rh.interval = urb->interval;    init_timer (&hci->rh.rh_int_timer);    hci->rh.rh_int_timer.function = rh_int_timer_do;    hci->rh.rh_int_timer.data = (unsigned long) urb;    hci->rh.rh_int_timer.expires = jiffies +                (HZ * (urb->interval < 30? 30: urb->interval)) / 1000;    add_timer (&hci->rh.rh_int_timer);	    return 0;}/*-------------------------------------------------------------------------*//* helper macro */#define OK(x) 			len = (x); break/*************************************************************************** * Function Name : rh_submit_urb *  * This function handles all USB request to the the virtual root hub *  * Input: urb = USB request block  * * Return: 0   **************************************************************************/static int rh_submit_urb (urb_t * urb){    struct usb_device * usb_dev = urb->dev;    hci_t * hci = usb_dev->bus->hcpriv;    unsigned int pipe = urb->pipe;    devrequest * cmd = (devrequest *) urb->setup_packet;    void * data = urb->transfer_buffer;    int leni = urb->transfer_buffer_length;    int len = 0;    int status = TD_CC_NOERROR;    __u32 datab[4];    __u8  * data_buf = (__u8 *) datab;	    __u16 bmRType_bReq;    __u16 wValue;     __u16 wIndex;    __u16 wLength;    DBGFUNC ("enter rh_submit_urb\n");

⌨️ 快捷键说明

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