hc_sl811_rh.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 584 行 · 第 1/2 页

C
584
字号
{	struct usb_device *usb_dev = urb->dev;	hci_t *hci = usb_dev->bus->hcpriv;	unsigned int pipe = urb->pipe;	struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) 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");	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->bRequestType | (cmd->bRequest << 8);	wValue = le16_to_cpu (cmd->wValue);	wIndex = le16_to_cpu (cmd->wIndex);	wLength = le16_to_cpu (cmd->wLength);	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 ((__u16)sizeof (root_hub_dev_des), wLength));			data_buf = root_hub_dev_des;			OK (len);		case (0x02):	/* configuration descriptor */			len = min (leni, min ((__u16)sizeof (root_hub_config_des), wLength));			data_buf = root_hub_config_des;			OK (len);		case (0x03):	/* string descriptors */			len = 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 ((__u16)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, NULL);	}	return 0;}/*************************************************************************** * Function Name : rh_unlink_urb *  * This function unlinks the URB  *  * Input: urb = USB request block  * * Return: 0   **************************************************************************/static int rh_unlink_urb (struct urb * 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_put_dev (urb->dev);		urb->dev = NULL;		if (urb->transfer_flags & URB_ASYNC_UNLINK) {			urb->status = -ECONNRESET;			if (urb->complete) {				urb->complete (urb, NULL);			}		} 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;	int retval;	hci->rh.devnum = 0;	usb_dev = usb_alloc_dev (NULL, hci->bus, 0);	if (!usb_dev)		return -ENOMEM;	usb_dev->devnum = 1;	usb_dev->bus->devnum_next = usb_dev->devnum + 1;	set_bit (usb_dev->devnum, usb_dev->bus->devmap.devicemap);	down (&usb_bus_list_lock);	hci->bus->root_hub = usb_dev;	retval = usb_new_device (usb_dev);	if (retval != 0)		hci->bus->root_hub = NULL;	up (&usb_bus_list_lock);	if (retval != 0) {		usb_put_dev (usb_dev);		return -ENODEV;	}	return 0;}

⌨️ 快捷键说明

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