u16			w_index = ctrl->wIndex; u16			w_value = ctrl->wValue; u16			w_length = ctrl->wLength; 
u16			w_index = le16_to_cpu(ctrl->wIndex); u16			w_value = le16_to_cpu(ctrl->wValue); u16			w_length = le16_to_cpu(ctrl->wLength); 
zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl){	struct zero_dev		*dev = get_gadget_data (gadget);	struct usb_request	*req = dev->req;	int			value = -EOPNOTSUPP;	u16			w_index = ctrl->wIndex;	u16			w_value = ctrl->wValue;	u16			w_length = ctrl->wLength;	/* usually this stores reply data in the pre-allocated ep0 buffer,	 * but config change events will reconfigure hardware.	 */	req->zero = 0;	switch (ctrl->bRequest) {	case USB_REQ_GET_DESCRIPTOR:		if (ctrl->bRequestType != USB_DIR_IN)			goto unknown;		switch (w_value >> 8) {		case USB_DT_DEVICE:			value = min (w_length, (u16) sizeof device_desc);			memcpy (req->buf, &device_desc, value);			break;#ifdef CONFIG_USB_GADGET_DUALSPEED		case USB_DT_DEVICE_QUALIFIER:			if (!gadget->is_dualspeed)				break;			value = min (w_length, (u16) sizeof dev_qualifier);			memcpy (req->buf, &dev_qualifier, value);			break;		case USB_DT_OTHER_SPEED_CONFIG:			if (!gadget->is_dualspeed)				break;			// FALLTHROUGH#endif /* CONFIG_USB_GADGET_DUALSPEED */		case USB_DT_CONFIG:			value = config_buf (gadget, req->buf,					w_value >> 8,					w_value & 0xff);			if (value >= 0)				value = min (w_length, (u16) value);			break;		case USB_DT_STRING:			/* wIndex == language code.			 * this driver only handles one language, you can			 * add string tables for other languages, using			 * any UTF-8 characters			 */			value = usb_gadget_get_string (&stringtab,					w_value & 0xff, req->buf);			if (value >= 0)				value = min (w_length, (u16) value);			break;		}		break;	/* currently two configs, two speeds */	case USB_REQ_SET_CONFIGURATION:		if (ctrl->bRequestType != 0)			goto unknown;		if (gadget->a_hnp_support)			DBG (dev, "HNP available\n");		else if (gadget->a_alt_hnp_support)			DBG (dev, "HNP needs a different root port\n");		else			VDBG (dev, "HNP inactive\n");		spin_lock (&dev->lock);		value = zero_set_config (dev, w_value, GFP_ATOMIC);		spin_unlock (&dev->lock);		break;	case USB_REQ_GET_CONFIGURATION:		if (ctrl->bRequestType != USB_DIR_IN)			goto unknown;		*(u8 *)req->buf = dev->config;		value = min (w_length, (u16) 1);		break;	/* until we add altsetting support, or other interfaces,	 * only 0/0 are possible.  pxa2xx only supports 0/0 (poorly)	 * and already killed pending endpoint I/O.	 */	case USB_REQ_SET_INTERFACE:		if (ctrl->bRequestType != USB_RECIP_INTERFACE)			goto unknown;		spin_lock (&dev->lock);		if (dev->config && w_index == 0 && w_value == 0) {			u8		config = dev->config;			/* resets interface configuration, forgets about			 * previous transaction state (queued bufs, etc)			 * and re-inits endpoint state (toggle etc)			 * no response queued, just zero status == success.			 * if we had more than one interface we couldn't			 * use this "reset the config" shortcut.			 */			zero_reset_config (dev);			zero_set_config (dev, config, GFP_ATOMIC);			value = 0;		}		spin_unlock (&dev->lock);		break;	case USB_REQ_GET_INTERFACE:		if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))			goto unknown;		if (!dev->config)			break;		if (w_index != 0) {			value = -EDOM;			break;		}		*(u8 *)req->buf = 0;		value = min (w_length, (u16) 1);		break;	/*	 * These are the same vendor-specific requests supported by	 * Intel's USB 2.0 compliance test devices.  We exceed that	 * device spec by allowing multiple-packet requests.	 */	case 0x5b:	/* control WRITE test -- fill the buffer */		if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))			goto unknown;		if (w_value || w_index)			break;		/* just read that many bytes into the buffer */		if (w_length > USB_BUFSIZ)			break;		value = w_length;		break;	case 0x5c:	/* control READ test -- return the buffer */		if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))			goto unknown;		if (w_value || w_index)			break;		/* expect those bytes are still in the buffer; send back */		if (w_length > USB_BUFSIZ				|| w_length != req->length)			break;		value = w_length;		break;	default:unknown:		VDBG (dev,			"unknown control req%02x.%02x v%04x i%04x l%d\n",			ctrl->bRequestType, ctrl->bRequest,			w_value, w_index, w_length);	}	/* respond with data transfer before status phase? */	if (value >= 0) {		req->length = value;		req->zero = value < w_length;		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);		if (value < 0) {			DBG (dev, "ep_queue --> %d\n", value);			req->status = 0;			zero_setup_complete (gadget->ep0, req);		}	}	/* device either stalls (value < 0) or reports success */	return value;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/1bbc169621cbe502b9143a27eb12802a0f1d43a0/zero.c/buggy/drivers/usb/gadget/zero.c