extern void dpm_runtime_resume(struct device *);  
static void hub_events(void){	struct list_head *tmp;	struct usb_device *hdev;	struct usb_interface *intf;	struct usb_hub *hub;	struct device *hub_dev;	u16 hubstatus;	u16 hubchange;	u16 portstatus;	u16 portchange;	int i, ret;	int connect_change;	/*	 *  We restart the list every time to avoid a deadlock with	 * deleting hubs downstream from this one. This should be	 * safe since we delete the hub from the event list.	 * Not the most efficient, but avoids deadlocks.	 */	while (1) {		/* Grab the first entry at the beginning of the list */		spin_lock_irq(&hub_event_lock);		if (list_empty(&hub_event_list)) {			spin_unlock_irq(&hub_event_lock);			break;		}		tmp = hub_event_list.next;		list_del_init(tmp);		hub = list_entry(tmp, struct usb_hub, event_list);		hdev = hub->hdev;		intf = to_usb_interface(hub->intfdev);		hub_dev = &intf->dev;		i = hub->resume_root_hub;		dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n",				hdev->state, hub->descriptor					? hub->descriptor->bNbrPorts					: 0,				/* NOTE: expects max 15 ports... */				(u16) hub->change_bits[0],				(u16) hub->event_bits[0],				i ? ", resume root" : "");		usb_get_intf(intf);		spin_unlock_irq(&hub_event_lock);		/* Is this is a root hub wanting to reactivate the downstream		 * ports?  If so, be sure the interface resumes even if its		 * stub "device" node was never suspended.		 */		if (i) {			extern void dpm_runtime_resume(struct device *);			dpm_runtime_resume(&hdev->dev);			dpm_runtime_resume(&intf->dev);		}		/* Lock the device, then check to see if we were		 * disconnected while waiting for the lock to succeed. */		if (locktree(hdev) < 0) {			usb_put_intf(intf);			continue;		}		if (hub != usb_get_intfdata(intf))			goto loop;		/* If the hub has died, clean up after it */		if (hdev->state == USB_STATE_NOTATTACHED) {			hub_pre_reset(hub);			goto loop;		}		/* If this is an inactive or suspended hub, do nothing */		if (hub->quiescing)			goto loop;		if (hub->error) {			dev_dbg (hub_dev, "resetting for error %d\n",				hub->error);			ret = usb_reset_device(hdev);			if (ret) {				dev_dbg (hub_dev,					"error resetting hub: %d\n", ret);				goto loop;			}			hub->nerrors = 0;			hub->error = 0;		}		/* deal with port status changes */		for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {			if (test_bit(i, hub->busy_bits))				continue;			connect_change = test_bit(i, hub->change_bits);			if (!test_and_clear_bit(i, hub->event_bits) &&					!connect_change && !hub->activating)				continue;			ret = hub_port_status(hub, i,					&portstatus, &portchange);			if (ret < 0)				continue;			if (hub->activating && !hdev->children[i-1] &&					(portstatus &						USB_PORT_STAT_CONNECTION))				connect_change = 1;			if (portchange & USB_PORT_STAT_C_CONNECTION) {				clear_port_feature(hdev, i,					USB_PORT_FEAT_C_CONNECTION);				connect_change = 1;			}			if (portchange & USB_PORT_STAT_C_ENABLE) {				if (!connect_change)					dev_dbg (hub_dev,						"port %d enable change, "						"status %08x\n",						i, portstatus);				clear_port_feature(hdev, i,					USB_PORT_FEAT_C_ENABLE);				/*				 * EM interference sometimes causes badly				 * shielded USB devices to be shutdown by				 * the hub, this hack enables them again.				 * Works at least with mouse driver. 				 */				if (!(portstatus & USB_PORT_STAT_ENABLE)				    && !connect_change				    && hdev->children[i-1]) {					dev_err (hub_dev,					    "port %i "					    "disabled by hub (EMI?), "					    "re-enabling...\n",						i);					connect_change = 1;				}			}			if (portchange & USB_PORT_STAT_C_SUSPEND) {				clear_port_feature(hdev, i,					USB_PORT_FEAT_C_SUSPEND);				if (hdev->children[i-1]) {					ret = remote_wakeup(hdev->							children[i-1]);					if (ret < 0)						connect_change = 1;				} else {					ret = -ENODEV;					hub_port_disable(hub, i, 1);				}				dev_dbg (hub_dev,					"resume on port %d, status %d\n",					i, ret);			}						if (portchange & USB_PORT_STAT_C_OVERCURRENT) {				dev_err (hub_dev,					"over-current change on port %d\n",					i);				clear_port_feature(hdev, i,					USB_PORT_FEAT_C_OVER_CURRENT);				hub_power_on(hub);			}			if (portchange & USB_PORT_STAT_C_RESET) {				dev_dbg (hub_dev,					"reset change on port %d\n",					i);				clear_port_feature(hdev, i,					USB_PORT_FEAT_C_RESET);			}			if (connect_change)				hub_port_connect_change(hub, i,						portstatus, portchange);		} /* end for i */		/* deal with hub status changes */		if (test_and_clear_bit(0, hub->event_bits) == 0)			;	/* do nothing */		else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)			dev_err (hub_dev, "get_hub_status failed\n");		else {			if (hubchange & HUB_CHANGE_LOCAL_POWER) {				dev_dbg (hub_dev, "power change\n");				clear_hub_feature(hdev, C_HUB_LOCAL_POWER);			}			if (hubchange & HUB_CHANGE_OVERCURRENT) {				dev_dbg (hub_dev, "overcurrent change\n");				msleep(500);	/* Cool down */				clear_hub_feature(hdev, C_HUB_OVER_CURRENT);                        	hub_power_on(hub);			}		}		hub->activating = 0;		/* If this is a root hub, tell the HCD it's okay to		 * re-enable port-change interrupts now. */		if (!hdev->parent)			usb_enable_root_hub_irq(hdev->bus);loop:		usb_unlock_device(hdev);		usb_put_intf(intf);        } /* end while (1) */}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/9a7834d06d553d02cc6e659e94772f69a8b5367f/hub.c/buggy/drivers/usb/core/hub.c