/* if it's already running, disconnect first */ if (dum->port_status & USB_PORT_STAT_ENABLE) { dum->port_status &= ~(USB_PORT_STAT_ENABLE | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); if (dum->driver) { dev_dbg (udc_dev(dum), "disconnect\n"); stop_activity (dum, dum->driver); }  /* FIXME test that code path! */ } 
/* if it's already enabled, disable */ dum->port_status &= ~(USB_PORT_STAT_ENABLE | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); 
static int dummy_hub_control (	struct usb_hcd	*hcd,	u16		typeReq,	u16		wValue,	u16		wIndex,	char		*buf,	u16		wLength) {	struct dummy	*dum;	int		retval = 0;	unsigned long	flags;	dum = hcd_to_dummy (hcd);	spin_lock_irqsave (&dum->lock, flags);	switch (typeReq) {	case ClearHubFeature:		break;	case ClearPortFeature:		switch (wValue) {		case USB_PORT_FEAT_SUSPEND:			if (dum->port_status & USB_PORT_STAT_SUSPEND) {				/* 20msec resume signaling */				dum->resuming = 1;				dum->re_timeout = jiffies +							msecs_to_jiffies(20);			}			break;		case USB_PORT_FEAT_POWER:			dum->port_status = 0;			dum->resuming = 0;			stop_activity(dum, dum->driver);			break;		default:			dum->port_status &= ~(1 << wValue);		}		break;	case GetHubDescriptor:		hub_descriptor ((struct usb_hub_descriptor *) buf);		break;	case GetHubStatus:		*(u32 *) buf = __constant_cpu_to_le32 (0);		break;	case GetPortStatus:		if (wIndex != 1)			retval = -EPIPE;		/* whoever resets or resumes must GetPortStatus to		 * complete it!!		 */		if (dum->resuming && time_after (jiffies, dum->re_timeout)) {			dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16);			dum->port_status &= ~USB_PORT_STAT_SUSPEND;			dum->resuming = 0;			dum->re_timeout = 0;			if (dum->driver && dum->driver->resume) {				spin_unlock (&dum->lock);				dum->driver->resume (&dum->gadget);				spin_lock (&dum->lock);			}		}		if ((dum->port_status & USB_PORT_STAT_RESET) != 0				&& time_after (jiffies, dum->re_timeout)) {			dum->port_status |= (USB_PORT_STAT_C_RESET << 16);			dum->port_status &= ~USB_PORT_STAT_RESET;			dum->re_timeout = 0;			if (dum->driver) {				dum->port_status |= USB_PORT_STAT_ENABLE;				/* give it the best speed we agree on */				dum->gadget.speed = dum->driver->speed;				dum->gadget.ep0->maxpacket = 64;				switch (dum->gadget.speed) {				case USB_SPEED_HIGH:					dum->port_status |=						USB_PORT_STAT_HIGH_SPEED;					break;				case USB_SPEED_LOW:					dum->gadget.ep0->maxpacket = 8;					dum->port_status |=						USB_PORT_STAT_LOW_SPEED;					break;				default:					dum->gadget.speed = USB_SPEED_FULL;					break;				}			}		}		((u16 *) buf)[0] = cpu_to_le16 (dum->port_status);		((u16 *) buf)[1] = cpu_to_le16 (dum->port_status >> 16);		break;	case SetHubFeature:		retval = -EPIPE;		break;	case SetPortFeature:		switch (wValue) {		case USB_PORT_FEAT_SUSPEND:			if ((dum->port_status & USB_PORT_STAT_SUSPEND)					== 0) {				dum->port_status |= USB_PORT_STAT_SUSPEND;				if (dum->driver && dum->driver->suspend) {					spin_unlock (&dum->lock);					dum->driver->suspend (&dum->gadget);					spin_lock (&dum->lock);					/* HNP would happen here; for now we					 * assume b_bus_req is always true.					 */					if (((1 << USB_DEVICE_B_HNP_ENABLE)							& dum->devstatus) != 0)						dev_dbg (dummy_dev(dum),							"no HNP yet!\n");				}			}			break;		case USB_PORT_FEAT_RESET:			/* if it's already running, disconnect first */			if (dum->port_status & USB_PORT_STAT_ENABLE) {				dum->port_status &= ~(USB_PORT_STAT_ENABLE						| USB_PORT_STAT_LOW_SPEED						| USB_PORT_STAT_HIGH_SPEED);				if (dum->driver) {					dev_dbg (udc_dev(dum),							"disconnect\n");					stop_activity (dum, dum->driver);				}				/* FIXME test that code path! */			}			/* 50msec reset signaling */			dum->re_timeout = jiffies + msecs_to_jiffies(50);			/* FALLTHROUGH */		default:			dum->port_status |= (1 << wValue);		}		break;	default:		dev_dbg (dummy_dev(dum),			"hub control req%04x v%04x i%04x l%d\n",			typeReq, wValue, wIndex, wLength);		/* "protocol stall" on error */		retval = -EPIPE;	}	spin_unlock_irqrestore (&dum->lock, flags);	return retval;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/f1c39fad7d1bbea31744138cd3a532ff346cd4ab/dummy_hcd.c/clean/drivers/usb/gadget/dummy_hcd.c