u16			wIndex = ctrl->wIndex; u16			wValue = ctrl->wValue; u16			wLength = ctrl->wLength; 
u16			wIndex = (__force u16) ctrl->wIndex; u16			wValue = (__force u16) ctrl->wValue; u16			wLength = (__force u16) ctrl->wLength; 
eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl){	struct eth_dev		*dev = get_gadget_data (gadget);	struct usb_request	*req = dev->req;	int			value = -EOPNOTSUPP;	u16			wIndex = ctrl->wIndex;	u16			wValue = ctrl->wValue;	u16			wLength = ctrl->wLength;	/* descriptors just go into the pre-allocated ep0 buffer,	 * while config change events may enable network traffic.	 */	req->complete = eth_setup_complete;	switch (ctrl->bRequest) {	case USB_REQ_GET_DESCRIPTOR:		if (ctrl->bRequestType != USB_DIR_IN)			break;		switch (wValue >> 8) {		case USB_DT_DEVICE:			value = min (wLength, (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 (wLength, (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->speed, req->buf,					wValue >> 8,					wValue & 0xff,					gadget->is_otg);			if (value >= 0)				value = min (wLength, (u16) value);			break;		case USB_DT_STRING:			value = usb_gadget_get_string (&stringtab,					wValue & 0xff, req->buf);			if (value >= 0)				value = min (wLength, (u16) value);			break;		}		break;	case USB_REQ_SET_CONFIGURATION:		if (ctrl->bRequestType != 0)			break;		if (gadget->a_hnp_support)			DEBUG (dev, "HNP available\n");		else if (gadget->a_alt_hnp_support)			DEBUG (dev, "HNP needs a different root port\n");		spin_lock (&dev->lock);		value = eth_set_config (dev, wValue, GFP_ATOMIC);		spin_unlock (&dev->lock);		break;	case USB_REQ_GET_CONFIGURATION:		if (ctrl->bRequestType != USB_DIR_IN)			break;		*(u8 *)req->buf = dev->config;		value = min (wLength, (u16) 1);		break;	case USB_REQ_SET_INTERFACE:		if (ctrl->bRequestType != USB_RECIP_INTERFACE				|| !dev->config				|| wIndex > 1)			break;		if (!dev->cdc && wIndex != 0)			break;		spin_lock (&dev->lock);		/* PXA hardware partially handles SET_INTERFACE;		 * we need to kluge around that interference.		 */		if (gadget_is_pxa (gadget)) {			value = eth_set_config (dev, DEV_CONFIG_VALUE,						GFP_ATOMIC);			goto done_set_intf;		}#ifdef DEV_CONFIG_CDC		switch (wIndex) {		case 0:		/* control/master intf */			if (wValue != 0)				break;			if (dev->status) {				usb_ep_disable (dev->status_ep);				usb_ep_enable (dev->status_ep, dev->status);			}			value = 0;			break;		case 1:		/* data intf */			if (wValue > 1)				break;			usb_ep_disable (dev->in_ep);			usb_ep_disable (dev->out_ep);			/* CDC requires the data transfers not be done from			 * the default interface setting ... also, setting			 * the non-default interface clears filters etc.			 */			if (wValue == 1) {				usb_ep_enable (dev->in_ep, dev->in);				usb_ep_enable (dev->out_ep, dev->out);				dev->cdc_filter = DEFAULT_FILTER;				netif_carrier_on (dev->net);				if (dev->status)					issue_start_status (dev);				if (netif_running (dev->net)) {					spin_unlock (&dev->lock);					eth_start (dev, GFP_ATOMIC);					spin_lock (&dev->lock);				}			} else {				netif_stop_queue (dev->net);				netif_carrier_off (dev->net);			}			value = 0;			break;		}#else		/* FIXME this is wrong, as is the assumption that		 * all non-PXA hardware talks real CDC ...		 */		dev_warn (&gadget->dev, "set_interface ignored!\n");#endif /* DEV_CONFIG_CDC */done_set_intf:		spin_unlock (&dev->lock);		break;	case USB_REQ_GET_INTERFACE:		if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)				|| !dev->config				|| wIndex > 1)			break;		if (!(dev->cdc || dev->rndis) && wIndex != 0)			break;		/* for CDC, iff carrier is on, data interface is active. */		if (dev->rndis || wIndex != 1)			*(u8 *)req->buf = 0;		else			*(u8 *)req->buf = netif_carrier_ok (dev->net) ? 1 : 0;		value = min (wLength, (u16) 1);		break;#ifdef DEV_CONFIG_CDC	case USB_CDC_SET_ETHERNET_PACKET_FILTER:		/* see 6.2.30: no data, wIndex = interface,		 * wValue = packet filter bitmap		 */		if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)				|| !dev->cdc				|| dev->rndis				|| wLength != 0				|| wIndex > 1)			break;		DEBUG (dev, "packet filter %02x\n", wValue);		dev->cdc_filter = wValue;		value = 0;		break;	/* and potentially:	 * case USB_CDC_SET_ETHERNET_MULTICAST_FILTERS:	 * case USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER:	 * case USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER:	 * case USB_CDC_GET_ETHERNET_STATISTIC:	 */#endif /* DEV_CONFIG_CDC */#ifdef CONFIG_USB_ETH_RNDIS			/* RNDIS uses the CDC command encapsulation mechanism to implement	 * an RPC scheme, with much getting/setting of attributes by OID.	 */	case USB_CDC_SEND_ENCAPSULATED_COMMAND:		if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)				|| !dev->rndis				|| wLength > USB_BUFSIZ				|| wValue				|| rndis_control_intf.bInterfaceNumber					!= wIndex)			break;		/* read the request, then process it */		value = wLength;		req->complete = rndis_command_complete;		/* later, rndis_control_ack () sends a notification */		break;			case USB_CDC_GET_ENCAPSULATED_RESPONSE:		if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)					== ctrl->bRequestType				&& dev->rndis				// && wLength >= 0x0400				&& !wValue				&& rndis_control_intf.bInterfaceNumber					== wIndex) {			u8 *buf;			/* return the result */			buf = rndis_get_next_response (dev->rndis_config,						       &value);			if (buf) {				memcpy (req->buf, buf, value);				req->complete = rndis_response_complete;				rndis_free_response(dev->rndis_config, buf);			}			/* else stalls ... spec says to avoid that */		}		break;#endif	/* RNDIS */	default:		VDEBUG (dev,			"unknown control req%02x.%02x v%04x i%04x l%d\n",			ctrl->bRequestType, ctrl->bRequest,			wValue, wIndex, wLength);	}	/* respond with data transfer before status phase? */	if (value >= 0) {		req->length = value;		req->zero = value < wLength				&& (value % gadget->ep0->maxpacket) == 0;		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);		if (value < 0) {			DEBUG (dev, "ep_queue --> %d\n", value);			req->status = 0;			eth_setup_complete (gadget->ep0, req);		}	}	/* host either stalls (value < 0) or reports success */	return value;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/6cdee106e7571751ecc0e9f96606322f88b64a8d/ether.c/buggy/drivers/usb/gadget/ether.c