wLength, urb->status); 
wLength, status); 
static int rh_call_control (struct usb_hcd *hcd, struct urb *urb){	struct usb_ctrlrequest *cmd; 	u16		typeReq, wValue, wIndex, wLength;	u8		*ubuf = urb->transfer_buffer;	u8		tbuf [sizeof (struct usb_hub_descriptor)];	const u8	*bufp = tbuf;	int		len = 0;	int		patch_wakeup = 0;	unsigned long	flags;	int		status = 0;	int		n;	cmd = (struct usb_ctrlrequest *) urb->setup_packet;	typeReq  = (cmd->bRequestType << 8) | cmd->bRequest;	wValue   = le16_to_cpu (cmd->wValue);	wIndex   = le16_to_cpu (cmd->wIndex);	wLength  = le16_to_cpu (cmd->wLength);	if (wLength > urb->transfer_buffer_length)		goto error;	urb->actual_length = 0;	switch (typeReq) {	/* DEVICE REQUESTS */	case DeviceRequest | USB_REQ_GET_STATUS:		tbuf [0] = (hcd->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP)				| (1 << USB_DEVICE_SELF_POWERED);		tbuf [1] = 0;		len = 2;		break;	case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:		if (wValue == USB_DEVICE_REMOTE_WAKEUP)			hcd->remote_wakeup = 0;		else			goto error;		break;	case DeviceOutRequest | USB_REQ_SET_FEATURE:		if (hcd->can_wakeup && wValue == USB_DEVICE_REMOTE_WAKEUP)			hcd->remote_wakeup = 1;		else			goto error;		break;	case DeviceRequest | USB_REQ_GET_CONFIGURATION:		tbuf [0] = 1;		len = 1;			/* FALLTHROUGH */	case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:		break;	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:		switch (wValue & 0xff00) {		case USB_DT_DEVICE << 8:			if (hcd->driver->flags & HCD_USB2)				bufp = usb2_rh_dev_descriptor;			else if (hcd->driver->flags & HCD_USB11)				bufp = usb11_rh_dev_descriptor;			else				goto error;			len = 18;			break;		case USB_DT_CONFIG << 8:			if (hcd->driver->flags & HCD_USB2) {				bufp = hs_rh_config_descriptor;				len = sizeof hs_rh_config_descriptor;			} else {				bufp = fs_rh_config_descriptor;				len = sizeof fs_rh_config_descriptor;			}			if (hcd->can_wakeup)				patch_wakeup = 1;			break;		case USB_DT_STRING << 8:			n = rh_string (wValue & 0xff, hcd, ubuf, wLength);			if (n < 0)				goto error;			urb->actual_length = n;			break;		default:			goto error;		}		break;	case DeviceRequest | USB_REQ_GET_INTERFACE:		tbuf [0] = 0;		len = 1;			/* FALLTHROUGH */	case DeviceOutRequest | USB_REQ_SET_INTERFACE:		break;	case DeviceOutRequest | USB_REQ_SET_ADDRESS:		// wValue == urb->dev->devaddr		dev_dbg (hcd->self.controller, "root hub device address %d\n",			wValue);		break;	/* INTERFACE REQUESTS (no defined feature/status flags) */	/* ENDPOINT REQUESTS */	case EndpointRequest | USB_REQ_GET_STATUS:		// ENDPOINT_HALT flag		tbuf [0] = 0;		tbuf [1] = 0;		len = 2;			/* FALLTHROUGH */	case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:	case EndpointOutRequest | USB_REQ_SET_FEATURE:		dev_dbg (hcd->self.controller, "no endpoint features yet\n");		break;	/* CLASS REQUESTS (and errors) */	default:		/* non-generic request */		if (HC_IS_SUSPENDED (hcd->state))			status = -EAGAIN;		else {			switch (typeReq) {			case GetHubStatus:			case GetPortStatus:				len = 4;				break;			case GetHubDescriptor:				len = sizeof (struct usb_hub_descriptor);				break;			}			status = hcd->driver->hub_control (hcd,				typeReq, wValue, wIndex,				tbuf, wLength);		}		break;error:		/* "protocol stall" on error */		status = -EPIPE;	}	if (status) {		len = 0;		if (status != -EPIPE) {			dev_dbg (hcd->self.controller,				"CTRL: TypeReq=0x%x val=0x%x "				"idx=0x%x len=%d ==> %d\n",				typeReq, wValue, wIndex,				wLength, urb->status);		}	}	if (len) {		if (urb->transfer_buffer_length < len)			len = urb->transfer_buffer_length;		urb->actual_length = len;		// always USB_DIR_IN, toward host		memcpy (ubuf, bufp, len);		/* report whether RH hardware supports remote wakeup */		if (patch_wakeup &&				len > offsetof (struct usb_config_descriptor,						bmAttributes))			((struct usb_config_descriptor *)ubuf)->bmAttributes				|= USB_CONFIG_ATT_WAKEUP;	}	/* any errors get returned through the urb completion */	local_irq_save (flags);	spin_lock (&urb->lock);	if (urb->status == -EINPROGRESS)		urb->status = status;	spin_unlock (&urb->lock);	usb_hcd_giveback_urb (hcd, urb, NULL);	local_irq_restore (flags);	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/b13296c6617f22e8c0174a7af32780617db0e680/hcd.c/clean/drivers/usb/core/hcd.c