📄 hc_sl811_rh.c
字号:
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 + -