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

📄 hc_sl811_rh.c

📁 Cy3662在Linux下的驱程开发
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (usb_pipeint(pipe)) 
    {
        hci->rh.urb =  urb;
	hci->rh.send = 1;
	hci->rh.interval = urb->interval;
	rh_init_int_timer(urb);
	urb->status = cc_to_error (TD_CC_NOERROR);
		
	return 0;
    }

    bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
    wValue        = le16_to_cpu (cmd->value);
    wIndex        = le16_to_cpu (cmd->index);
    wLength       = le16_to_cpu (cmd->length);

    DBG ("rh_submit_urb, req = %d(%x) len=%d", bmRType_bReq,
		bmRType_bReq, wLength);

    switch (bmRType_bReq) 
    {
	/* Request Destination:
	   without flags: Device, 
	   RH_INTERFACE: interface, 
	   RH_ENDPOINT: endpoint,
	   RH_CLASS means HUB here, 
	   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here 
	*/
  
        case RH_GET_STATUS: 				 		
	    *(__u16 *) data_buf = cpu_to_le16 (1); OK (2);
	
        case RH_GET_STATUS | RH_INTERFACE: 	 		
	    *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
	
  	case RH_GET_STATUS | RH_ENDPOINT:	 		
	    *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);   
	
 	case RH_GET_STATUS | RH_CLASS: 				
  	    *(__u32 *) data_buf = cpu_to_le32 (0); OK (4);
	
 	case RH_GET_STATUS | RH_OTHER | RH_CLASS: 	
	    *(__u32 *) data_buf = cpu_to_le32 (getPortStatusAndChange(hci)); 
            OK (4);

	case RH_CLEAR_FEATURE | RH_ENDPOINT:  
	    switch (wValue) 
            {
		case (RH_ENDPOINT_STALL): OK (0);
	    }
	    break;

	case RH_CLEAR_FEATURE | RH_CLASS:
	    switch (wValue) 
            {
		case RH_C_HUB_LOCAL_POWER:
		    OK(0);
		
                case (RH_C_HUB_OVER_CURRENT): 
		    /* Over Current Not Implemented */
		    OK (0);
	    }
	    break;
		
	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
	    switch (wValue) 
            {
		case (RH_PORT_ENABLE): 			
                    clrPortStatus (hci, PORT_ENABLE_STAT);
		    OK (0);
		
                case (RH_PORT_SUSPEND):			
                    clrPortStatus (hci, PORT_SUSPEND_STAT);
		    OK (0);
		
		case (RH_PORT_POWER):			
                    clrPortStatus (hci, PORT_POWER_STAT);
	            OK (0);
		
		case (RH_C_PORT_CONNECTION):	
                    clrPortChange (hci, PORT_CONNECT_STAT);
  	            OK (0);
		
		case (RH_C_PORT_ENABLE):		
                    clrPortChange (hci, PORT_ENABLE_STAT);
	  	    OK (0);
		
		case (RH_C_PORT_SUSPEND):		
                    clrPortChange (hci, PORT_SUSPEND_STAT);
	            OK (0);
		
		case (RH_C_PORT_OVER_CURRENT):	
                    clrPortChange (hci, PORT_OVER_CURRENT_STAT);
		    OK (0);
		
		case (RH_C_PORT_RESET):			
                    clrPortChange (hci, PORT_RESET_STAT);
		    OK (0); 
		}
		break;
 
	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
	    switch (wValue) 
            {
		case (RH_PORT_SUSPEND):			
                    setPortStatus(hci, PORT_SUSPEND_STAT);
		    OK (0); 
		
		case (RH_PORT_RESET): 
                    setPortStatus(hci, PORT_RESET_STAT);
                    // USBReset(hci);
                    clrPortChange (hci, PORT_CONNECT_CHANGE 
                                   | PORT_ENABLE_CHANGE | PORT_SUSPEND_CHANGE 
                                   | PORT_OVER_CURRENT_CHANGE);
                    setPortChange(hci, PORT_RESET_CHANGE);
                    clrPortStatus(hci, PORT_RESET_STAT);
                    setPortStatus(hci, PORT_ENABLE_STAT);
                                                
		    OK (0);
		
                case (RH_PORT_POWER):			
                    setPortStatus(hci, PORT_POWER_STAT);
		    OK (0); 
		
                case (RH_PORT_ENABLE): 
                    setPortStatus(hci, PORT_ENABLE_STAT);
		    OK (0);
		}
		break;

	case RH_SET_ADDRESS: hci->rh.devnum = wValue; OK(0);

	case RH_GET_DESCRIPTOR:
	    DBGVERBOSE ("rh_submit_urb: RH_GET_DESCRIPTOR, wValue = 0x%x\n", 
                        wValue);
	    switch ((wValue & 0xff00) >> 8) 
            {
		case (0x01): /* device descriptor */
		    len = min (leni, min (sizeof (root_hub_dev_des), wLength));
		    data_buf = root_hub_dev_des; OK(len);
		
                case (0x02): /* configuration descriptor */
		    len = min (leni, min (sizeof (root_hub_config_des), 
                               wLength));
		    data_buf = root_hub_config_des; OK(len);
		
                case (0x03): /* string descriptors */
		    len = usb_root_hub_string (wValue & 0xff,(int)(long) 0, 
                                               "SL811HS", data, wLength);
		    if (len > 0) 
                    {
		        data_buf = data;
			OK (min (leni, len));
		    }
		
		default: 
		    status = SL11H_STATMASK_STALL;
	    }
	    break;
		
	case RH_GET_DESCRIPTOR | RH_CLASS:
	    data_buf [0] = 9;		// min length;
	    data_buf [1] = 0x29;
	    data_buf [2] = 1;		// # of downstream port
	    data_buf [3] = 0;
	    datab [1] = 0;
	    data_buf [5] = 50;		// 100 ms for port reset
	    data_buf [7] = 0xfc;        // which port is attachable
	    if (data_buf [2] < 7) 
            {
	        data_buf [8] = 0xff;
	    } 
            else 
            {
	    }
				
	    len = min (leni, min (data_buf [0], wLength));
	    OK (len);
	
 
	case RH_GET_CONFIGURATION: 	
	    *(__u8 *) data_buf = 0x01; 
	    OK (1);

	case RH_SET_CONFIGURATION: 	
	    OK (0);

	default: 
	    DBGERR ("unsupported root hub command");
	    status = SL11H_STATMASK_STALL;
    }
	
    len = min(len, leni);
    if (data != data_buf)
        memcpy (data, data_buf, len);
    urb->actual_length = len;
    urb->status = cc_to_error (status);

    urb->hcpriv = NULL;
    urb->dev = NULL;
    if (urb->complete)
    {
    	urb->complete (urb);
    }
	
    return 0;
}

/***************************************************************************
 * Function Name : rh_unlink_urb
 * 
 * This function unlinks the URB 
 * 
 * Input: urb = USB request block 
 *
 * Return: 0  
 **************************************************************************/

static int rh_unlink_urb (urb_t * urb)
{
    hci_t * hci = urb->dev->bus->hcpriv;
 
    DBGFUNC ("enter rh_unlink_urb\n");
    if (hci->rh.urb == urb) 
    {
	hci->rh.send = 0;
	del_timer (&hci->rh.rh_int_timer);
	hci->rh.urb = NULL;

	urb->hcpriv = NULL;
	usb_dec_dev_use(urb->dev);
	urb->dev = NULL;
	if (urb->transfer_flags & USB_ASYNC_UNLINK) 
        {
	    urb->status = -ECONNRESET;
	    if (urb->complete)
            {
	        urb->complete (urb);
            }
	} 
        else
	    urb->status = -ENOENT;
    }
    return 0;
}

/***************************************************************************
 * Function Name : rh_connect_rh
 * 
 * This function connect the virtual root hub to the USB stack 
 * 
 * Input: urb = USB request block 
 *
 * Return: 0  
 **************************************************************************/
 
static int rh_connect_rh (hci_t * hci) 
{
    struct usb_device  * usb_dev;
 
    hci->rh.devnum = 0;
    usb_dev = usb_alloc_dev (NULL, hci->bus);
    if (!usb_dev)
        return -ENOMEM;
 
    hci->bus->root_hub = usb_dev;
    usb_connect (usb_dev);
    if (usb_new_device (usb_dev) != 0) 
    {
        usb_free_dev (usb_dev);
        return -ENODEV;
    }
 
    return 0;
} 

⌨️ 快捷键说明

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