All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] PVUSB update and bugfix: frontend part
@ 2009-10-07  7:27 Noboru Iwamatsu
  2009-10-08  1:28 ` Masaki Kanno
  0 siblings, 1 reply; 3+ messages in thread
From: Noboru Iwamatsu @ 2009-10-07  7:27 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 60 bytes --]

Signed-off-by: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>


[-- Attachment #2: usbfront-v2.patch --]
[-- Type: text/plain, Size: 36704 bytes --]

diff -r 4ac3e1d6605c -r 3be939975ad6 drivers/xen/usbfront/usbfront-dbg.c
--- a/drivers/xen/usbfront/usbfront-dbg.c	Tue Sep 29 11:23:06 2009 +0100
+++ b/drivers/xen/usbfront/usbfront-dbg.c	Tue Oct 06 15:18:27 2009 +0900
@@ -60,7 +60,7 @@
 
 	spin_lock_irqsave(&info->lock, flags);
 
-	temp = scnprintf (next, size,
+	temp = scnprintf(next, size,
 			"bus %s, device %s\n"
 			"%s\n"
 			"xenhcd, hcd state %d\n",
@@ -74,7 +74,8 @@
 #ifdef XENHCD_STATS
 	temp = scnprintf(next, size,
 		"complete %ld unlink %ld ring_full %ld\n",
-		info->stats.complete, info->stats.unlink, info->stats.ring_full);
+		info->stats.complete, info->stats.unlink,
+		info->stats.ring_full);
 	size -= temp;
 	next += temp;
 #endif
diff -r 4ac3e1d6605c -r 3be939975ad6 drivers/xen/usbfront/usbfront-hcd.c
--- a/drivers/xen/usbfront/usbfront-hcd.c	Tue Sep 29 11:23:06 2009 +0100
+++ b/drivers/xen/usbfront/usbfront-hcd.c	Tue Oct 06 15:18:27 2009 +0900
@@ -54,7 +54,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&info->lock, flags);
-	if (HC_IS_RUNNING(info_to_hcd(info)->state)) {
+	if (likely(HC_IS_RUNNING(info_to_hcd(info)->state))) {
 		timer_action_done(info, TIMER_RING_WATCHDOG);
 		xenhcd_giveback_unlinked_urbs(info);
 		xenhcd_kick_pending_urbs(info);
@@ -70,9 +70,10 @@
 	struct usbfront_info *info = hcd_to_info(hcd);
 
 	spin_lock_init(&info->lock);
-	INIT_LIST_HEAD(&info->pending_urbs);
-	INIT_LIST_HEAD(&info->inprogress_urbs);
-	INIT_LIST_HEAD(&info->unlinked_urbs);
+	INIT_LIST_HEAD(&info->pending_submit_list);
+	INIT_LIST_HEAD(&info->pending_unlink_list);
+	INIT_LIST_HEAD(&info->in_progress_list);
+	INIT_LIST_HEAD(&info->giveback_waiting_list);
 	init_timer(&info->watchdog);
 	info->watchdog.function = xenhcd_watchdog;
 	info->watchdog.data = (unsigned long) info;
@@ -101,70 +102,14 @@
 	del_timer_sync(&info->watchdog);
 	remove_debug_file(info);
 	spin_lock_irq(&info->lock);
-	/*
-	 * TODO: port power off, cancel all urbs.
-	 */
-
-	if (HC_IS_RUNNING(hcd->state))
-		hcd->state = HC_STATE_HALT;
+	/* cancel all urbs */
+	hcd->state = HC_STATE_HALT;
+	xenhcd_cancel_all_enqueued_urbs(info);
+	xenhcd_giveback_unlinked_urbs(info);
 	spin_unlock_irq(&info->lock);
 }
 
 /*
- * TODO: incomplete suspend/resume functions!
- */
-#if 0
-#ifdef CONFIG_PM
-/*
- * suspend running HC
- */
-static int xenhcd_suspend(struct usb_hcd *hcd, pm_message_t message)
-{
-	struct usbfront_info *info = hcd_to_info(hcd);
-	unsigned long flags;
-	int ret = 0;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (hcd->state != HC_STATE_SUSPENDED) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/*
-	 * TODO:
-	 * 	canceling all transfer, clear all hc queue,
-	 * 	stop kthread,
-	 */
-
-	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-done:
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	return ret;
-}
-
-/*
- * resume HC
- */
-static int xenhcd_resume(struct usb_hcd *hcd)
-{
-	struct usbfront_info *info = hcd_to_info(hcd);
-	int ret = -EINVAL;
-
-	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
-	/*
-	 * TODO:
-	 * 	re-init HC.
-	 * 	resume all roothub ports.
-	 */
-
-	return ret;
-}
-#endif
-#endif
-
-/*
  * called as .urb_enqueue()
  * non-error returns are promise to giveback the urb later
  */
@@ -197,11 +142,6 @@
 
 /*
  * called as .urb_dequeue()
- *
- * just mark the urb as unlinked
- * if the urb is in pending_urbs, move to unlinked_urbs
- * TODO:
- * 	canceling the urb transfer in backend
  */
 static int xenhcd_urb_dequeue(struct usb_hcd *hcd,
 				    struct urb *urb)
@@ -234,46 +174,54 @@
 	return 0;
 }
 
-/*
- * TODO:
- * suspend/resume whole hcd and roothub
- */
 static const char hcd_name[] = "xen_hcd";
 
-struct hc_driver usbfront_hc_driver = {
+struct hc_driver xen_usb20_hc_driver = {
 	.description = hcd_name,
-	.product_desc = DRIVER_DESC,
+	.product_desc = "Xen USB2.0 Virtual Host Controller",
 	.hcd_priv_size = sizeof(struct usbfront_info),
 	.flags = HCD_USB2,
 
-	/*
-	 * basic HC lifecycle operations
-	 */
+	/* basic HC lifecycle operations */
 	.reset = xenhcd_setup,
 	.start = xenhcd_run,
 	.stop = xenhcd_stop,
-#if 0
-#ifdef CONFIG_PM
-	.suspend = xenhcd_suspend,
-	.resume = xenhcd_resume,
-#endif
-#endif
-	/*
-	 * managing urb I/O
-	 */
+
+	/* managing urb I/O */
 	.urb_enqueue = xenhcd_urb_enqueue,
 	.urb_dequeue = xenhcd_urb_dequeue,
 	.get_frame_number = xenhcd_get_frame,
 
-	/*
-	 * root hub operations
-	 */
+	/* root hub operations */
 	.hub_status_data = xenhcd_hub_status_data,
 	.hub_control = xenhcd_hub_control,
-#if 0
 #ifdef CONFIG_PM
 	.bus_suspend = xenhcd_bus_suspend,
 	.bus_resume = xenhcd_bus_resume,
 #endif
+};
+
+struct hc_driver xen_usb11_hc_driver = {
+	.description = hcd_name,
+	.product_desc = "Xen USB1.1 Virtual Host Controller",
+	.hcd_priv_size = sizeof(struct usbfront_info),
+	.flags = HCD_USB11,
+
+	/* basic HC lifecycle operations */
+	.reset = xenhcd_setup,
+	.start = xenhcd_run,
+	.stop = xenhcd_stop,
+
+	/* managing urb I/O */
+	.urb_enqueue = xenhcd_urb_enqueue,
+	.urb_dequeue = xenhcd_urb_dequeue,
+	.get_frame_number = xenhcd_get_frame,
+
+	/* root hub operations */
+	.hub_status_data = xenhcd_hub_status_data,
+	.hub_control = xenhcd_hub_control,
+#ifdef CONFIG_PM
+	.bus_suspend = xenhcd_bus_suspend,
+	.bus_resume = xenhcd_bus_resume,
 #endif
 };
diff -r 4ac3e1d6605c -r 3be939975ad6 drivers/xen/usbfront/usbfront-hub.c
--- a/drivers/xen/usbfront/usbfront-hub.c	Tue Sep 29 11:23:06 2009 +0100
+++ b/drivers/xen/usbfront/usbfront-hub.c	Tue Oct 06 15:18:27 2009 +0900
@@ -50,15 +50,16 @@
 {
 	int port;
 
-	port = portnum -1;
+	port = portnum - 1;
 	if (info->ports[port].status & USB_PORT_STAT_POWER) {
 		switch (info->devices[port].speed) {
 		case USB_SPEED_UNKNOWN:
-			info->ports[port].status &= ~(USB_PORT_STAT_CONNECTION |
-							USB_PORT_STAT_ENABLE |
-							USB_PORT_STAT_LOW_SPEED |
-							USB_PORT_STAT_HIGH_SPEED |
-							USB_PORT_STAT_SUSPEND);
+			info->ports[port].status &=
+				~(USB_PORT_STAT_CONNECTION |
+					USB_PORT_STAT_ENABLE |
+					USB_PORT_STAT_LOW_SPEED |
+					USB_PORT_STAT_HIGH_SPEED |
+					USB_PORT_STAT_SUSPEND);
 			break;
 		case USB_SPEED_LOW:
 			info->ports[port].status |= USB_PORT_STAT_CONNECTION;
@@ -86,6 +87,9 @@
 {
 	int port;
 
+	if (portnum < 1 || portnum > info->rh_numports)
+		return; /* invalid port number */
+
 	port = portnum - 1;
 	if (info->devices[port].speed != speed) {
 		switch (speed) {
@@ -107,30 +111,6 @@
 	}
 }
 
-void rhport_disconnect(struct usbfront_info *info, int portnum)
-{
-	rhport_connect(info, portnum, USB_SPEED_UNKNOWN);
-}
-
-void xenhcd_rhport_state_change(struct usbfront_info *info,
-				int portnum, enum usb_device_speed speed)
-{
-	int changed = 0;
-	unsigned long flags;
-
-	if (portnum < 1 || portnum > info->rh_numports)
-		return; /* invalid port number */
-
-	spin_lock_irqsave(&info->lock, flags);
-	rhport_connect(info, portnum, speed);
-	if (info->ports[portnum-1].c_connection)
-		changed = 1;
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	if (changed)
-		usb_hcd_poll_rh_status(info_to_hcd(info));
-}
-
 /*
  * SetPortFeature(PORT_SUSPENDED)
  */
@@ -214,7 +194,7 @@
 {
 	int port;
 
-	port = portnum -1;
+	port = portnum - 1;
 	info->ports[port].status &= ~(USB_PORT_STAT_ENABLE
 					| USB_PORT_STAT_LOW_SPEED
 					| USB_PORT_STAT_HIGH_SPEED);
@@ -227,57 +207,51 @@
 	info->ports[port].timeout = jiffies + msecs_to_jiffies(10);
 }
 
-#if 0
 #ifdef CONFIG_PM
 static int xenhcd_bus_suspend(struct usb_hcd *hcd)
 {
 	struct usbfront_info *info = hcd_to_info(hcd);
+	int ret = 0;
 	int i, ports;
 
 	ports = info->rh_numports;
 
 	spin_lock_irq(&info->lock);
-
-	if (HC_IS_RUNNING(hcd->state)) {
-		/*
-		 * TODO:
-		 * clean queue,
-		 * stop all transfers,
-		 * ...
-		 */
-		hcd->state = HC_STATE_QUIESCING;
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &info->flags))
+		ret = -ESHUTDOWN;
+	else if (!info->dead) {
+		/* suspend any active ports*/
+		for (i = 1; i <= ports; i++)
+			rhport_suspend(info, i);
 	}
-
-	/* suspend any active ports*/
-	for (i = 1; i <= ports; i++) {
-		rhport_suspend(info, i);
-	}
+	spin_unlock_irq(&info->lock);
 
 	del_timer_sync(&info->watchdog);
 
-	spin_unlock_irq(&info->lock);
-
-	return 0;
+	return ret;
 }
 
 static int xenhcd_bus_resume(struct usb_hcd *hcd)
 {
 	struct usbfront_info *info = hcd_to_info(hcd);
+	int ret = 0;
 	int i, ports;
 
 	ports = info->rh_numports;
 
 	spin_lock_irq(&info->lock);
-	/* resume any suspended ports*/
-	for (i = 1; i <= ports; i++) {
-		rhport_resume(info, i);
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &info->flags))
+		ret = -ESHUTDOWN;
+	else if (!info->dead) {
+		/* resume any suspended ports*/
+		for (i = 1; i <= ports; i++)
+			rhport_resume(info, i);
 	}
-	hcd->state = HC_STATE_RUNNING;
 	spin_unlock_irq(&info->lock);
-	return 0;
+
+	return ret;
 }
 #endif
-#endif
 
 static void xenhcd_hub_descriptor(struct usbfront_info *info,
 				  struct usb_hub_descriptor *desc)
@@ -295,8 +269,8 @@
 	desc->bDescLength = 7 + 2 * temp;
 
 	/* bitmaps for DeviceRemovable and PortPwrCtrlMask */
-	memset (&desc->bitmap[0], 0, temp);
-	memset (&desc->bitmap[temp], 0xff, temp);
+	memset(&desc->bitmap[0], 0, temp);
+	memset(&desc->bitmap[temp], 0xff, temp);
 
 	/* per-port over current reporting and no power switching */
 	temp = 0x000a;
@@ -380,11 +354,6 @@
 	int i;
 	int changed = 0;
 
-#ifdef USBFRONT_DEBUG
-	WPRINTK("xenusb_hub_control(typeReq %x wValue %x wIndex %x)\n",
-	       typeReq, wValue, wIndex);
-#endif
-
 	spin_lock_irqsave(&info->lock, flags);
 	switch (typeReq) {
 	case ClearHubFeature:
@@ -394,7 +363,7 @@
 		if (!wIndex || wIndex > ports)
 			goto error;
 
-		switch(wValue) {
+		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
 			rhport_resume(info, wIndex);
 			break;
@@ -414,7 +383,7 @@
 		break;
 	case GetHubDescriptor:
 		xenhcd_hub_descriptor(info,
-				      (struct usb_hub_descriptor*) buf);
+				      (struct usb_hub_descriptor *) buf);
 		break;
 	case GetHubStatus:
 		/* always local power supply good and no over-current exists. */
@@ -444,7 +413,7 @@
 				info->devices[wIndex].status = USB_STATE_DEFAULT;
 			}
 
-			switch(info->devices[wIndex].speed) {
+			switch (info->devices[wIndex].speed) {
 			case USB_SPEED_LOW:
 				info->ports[wIndex].status |= USB_PORT_STAT_LOW_SPEED;
 				break;
@@ -466,7 +435,7 @@
 		if (!wIndex || wIndex > ports)
 			goto error;
 
-		switch(wValue) {
+		switch (wValue) {
 		case USB_PORT_FEAT_POWER:
 			rhport_power_on(info, wIndex);
 			break;
@@ -477,9 +446,8 @@
 			rhport_suspend(info, wIndex);
 			break;
 		default:
-			if ((info->ports[wIndex-1].status & USB_PORT_STAT_POWER) != 0) {
+			if ((info->ports[wIndex-1].status & USB_PORT_STAT_POWER) != 0)
 				info->ports[wIndex-1].status |= (1 << wValue);
-			}
 		}
 		break;
 
@@ -491,9 +459,8 @@
 
 	/* check status for each port */
 	for (i = 0; i < ports; i++) {
-		if (info->ports[i].status & PORT_C_MASK) {
+		if (info->ports[i].status & PORT_C_MASK)
 			changed = 1;
-		}
 	}
 	if (changed)
 		usb_hcd_poll_rh_status(hcd);
diff -r 4ac3e1d6605c -r 3be939975ad6 drivers/xen/usbfront/usbfront-q.c
--- a/drivers/xen/usbfront/usbfront-q.c	Tue Sep 29 11:23:06 2009 +0100
+++ b/drivers/xen/usbfront/usbfront-q.c	Tue Oct 06 15:18:27 2009 +0900
@@ -50,13 +50,13 @@
 	struct urb_priv *urbp;
 
 	urbp = kmem_cache_zalloc(xenhcd_urbp_cachep, GFP_ATOMIC);
-	if (!urbp) {
+	if (!urbp)
 		return NULL;
-	}
 
 	urbp->urb = urb;
 	urb->hcpriv = urbp;
 	urbp->req_id = ~0;
+	urbp->unlink_req_id = ~0;
 	INIT_LIST_HEAD(&urbp->list);
 
 	return urbp;
@@ -73,7 +73,7 @@
 {
 	unsigned long free;
 	free = info->shadow_free;
-	BUG_ON(free > USB_RING_SIZE);
+	BUG_ON(free >= USB_URB_RING_SIZE);
 	info->shadow_free = info->shadow[free].req.id;
 	info->shadow[free].req.id = (unsigned int)0x0fff; /* debug */
 	return free;
@@ -90,7 +90,7 @@
 static inline int count_pages(void *addr, int length)
 {
 	unsigned long start = (unsigned long) addr >> PAGE_SHIFT;
-	unsigned long end = (unsigned long) (addr + length + PAGE_SIZE -1) >> PAGE_SHIFT;
+	unsigned long end = (unsigned long) (addr + length + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	return end - start;
 }
 
@@ -108,7 +108,7 @@
 
 	len = length;
 
-	for(i = 0;i < nr_pages;i++){
+	for (i = 0; i < nr_pages; i++) {
 		BUG_ON(!len);
 
 		page = virt_to_page(addr);
@@ -116,7 +116,7 @@
 		offset = offset_in_page(addr);
 
 		bytes = PAGE_SIZE - offset;
-		if(bytes > len)
+		if (bytes > len)
 			bytes = len;
 
 		ref = gnttab_claim_grant_reference(gref_head);
@@ -132,7 +132,7 @@
 }
 
 static int map_urb_for_request(struct usbfront_info *info, struct urb *urb,
-		usbif_request_t *req)
+		usbif_urb_request_t *req)
 {
 	grant_ref_t gref_head;
 	int nr_buff_pages = 0;
@@ -175,14 +175,12 @@
 		req->u.isoc.start_frame = urb->start_frame;
 		req->u.isoc.number_of_packets = urb->number_of_packets;
 		req->u.isoc.nr_frame_desc_segs = nr_isodesc_pages;
-		/*
-		 * urb->number_of_packets must be > 0
-		 */
+		/* urb->number_of_packets must be > 0 */
 		if (unlikely(urb->number_of_packets <= 0))
 			BUG();
 		xenhcd_gnttab_map(info, &urb->iso_frame_desc[0],
-				sizeof(struct usb_iso_packet_descriptor) * urb->number_of_packets,
-				&gref_head, &req->seg[nr_buff_pages], nr_isodesc_pages, 0);
+			sizeof(struct usb_iso_packet_descriptor) * urb->number_of_packets,
+			&gref_head, &req->seg[nr_buff_pages], nr_isodesc_pages, 0);
 		gnttab_free_grant_references(gref_head);
 		break;
 	case PIPE_INTERRUPT:
@@ -213,9 +211,12 @@
 
 	for (i = 0; i < nr_segs; i++)
 		gnttab_end_foreign_access(shadow->req.seg[i].gref, 0UL);
+
+	shadow->req.nr_buffer_segs = 0;
+	shadow->req.u.isoc.nr_frame_desc_segs = 0;
 }
 
-static void xenhcd_giveback_urb(struct usbfront_info *info, struct urb *urb)
+static void xenhcd_giveback_urb(struct usbfront_info *info, struct urb *urb, int status)
 __releases(info->lock)
 __acquires(info->lock)
 {
@@ -228,6 +229,9 @@
 	case -ENOENT:
 		COUNT(info->stats.unlink);
 		break;
+	case -EINPROGRESS:
+		urb->status = status;
+		/* falling through */
 	default:
 		COUNT(info->stats.complete);
 	}
@@ -238,28 +242,35 @@
 
 static inline int xenhcd_do_request(struct usbfront_info *info, struct urb_priv *urbp)
 {
-	usbif_request_t *ring_req;
+	usbif_urb_request_t *req;
 	struct urb *urb = urbp->urb;
 	uint16_t id;
 	int notify;
 	int ret = 0;
 
-	ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
+	req = RING_GET_REQUEST(&info->urb_ring, info->urb_ring.req_prod_pvt);
 	id = get_id_from_freelist(info);
-	ring_req->id = id;
+	req->id = id;
 
-	ret = map_urb_for_request(info, urb, ring_req);
-	if (ret < 0) {
-		add_id_to_freelist(info, id);
-		return ret;
+	if (unlikely(urbp->unlinked)) {
+		req->u.unlink.unlink_id = urbp->req_id;
+		req->pipe = usbif_setunlink_pipe(usbif_setportnum_pipe(
+				urb->pipe, urb->dev->portnum));
+		urbp->unlink_req_id = id;
+	} else {
+		ret = map_urb_for_request(info, urb, req);
+		if (ret < 0) {
+			add_id_to_freelist(info, id);
+			return ret;
+		}
+		urbp->req_id = id;
 	}
 
-	info->ring.req_prod_pvt++;
+	info->urb_ring.req_prod_pvt++;
 	info->shadow[id].urb = urb;
-	info->shadow[id].req = *ring_req;
-	urbp->req_id = id;
+	info->shadow[id].req = *req;
 
-	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->ring, notify);
+	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->urb_ring, notify);
 	if (notify)
 		notify_remote_via_irq(info->irq);
 
@@ -271,19 +282,19 @@
 	struct urb_priv *urbp;
 	int ret;
 
-	while (!list_empty(&info->pending_urbs)) {
-		if (RING_FULL(&info->ring)) {
+	while (!list_empty(&info->pending_submit_list)) {
+		if (RING_FULL(&info->urb_ring)) {
 			COUNT(info->stats.ring_full);
 			timer_action(info, TIMER_RING_WATCHDOG);
 			goto done;
 		}
 
-		urbp = list_entry(info->pending_urbs.next, struct urb_priv, list);
+		urbp = list_entry(info->pending_submit_list.next, struct urb_priv, list);
 		ret = xenhcd_do_request(info, urbp);
 		if (ret == 0)
-			list_move_tail(&urbp->list, &info->inprogress_urbs);
+			list_move_tail(&urbp->list, &info->in_progress_list);
 		else
-			xenhcd_giveback_urb(info, urbp->urb);
+			xenhcd_giveback_urb(info, urbp->urb, -ESHUTDOWN);
 	}
 	timer_action_done(info, TIMER_SCAN_PENDING_URBS);
 
@@ -291,12 +302,41 @@
 	return;
 }
 
+/*
+ * caller must lock info->lock
+ */
+static void xenhcd_cancel_all_enqueued_urbs(struct usbfront_info *info)
+{
+	struct urb_priv *urbp, *tmp;
+
+	list_for_each_entry_safe(urbp, tmp, &info->in_progress_list, list) {
+		if (!urbp->unlinked) {
+			xenhcd_gnttab_done(&info->shadow[urbp->req_id]);
+			barrier();
+			if (urbp->urb->status == -EINPROGRESS)	/* not dequeued */
+				xenhcd_giveback_urb(info, urbp->urb, -ESHUTDOWN);
+			else					/* dequeued */
+				xenhcd_giveback_urb(info, urbp->urb, urbp->urb->status);
+		}
+		info->shadow[urbp->req_id].urb = NULL;
+	}
+
+	list_for_each_entry_safe(urbp, tmp, &info->pending_submit_list, list) {
+		xenhcd_giveback_urb(info, urbp->urb, -ESHUTDOWN);
+	}
+
+	return;
+}
+
+/*
+ * caller must lock info->lock
+ */
 static void xenhcd_giveback_unlinked_urbs(struct usbfront_info *info)
 {
 	struct urb_priv *urbp, *tmp;
 
-	list_for_each_entry_safe(urbp, tmp, &info->unlinked_urbs, list) {
-		xenhcd_giveback_urb(info, urbp->urb);
+	list_for_each_entry_safe(urbp, tmp, &info->giveback_waiting_list, list) {
+		xenhcd_giveback_urb(info, urbp->urb, urbp->urb->status);
 	}
 }
 
@@ -304,22 +344,22 @@
 {
 	int ret = 0;
 
-	if (RING_FULL(&info->ring)) {
-		list_add_tail(&urbp->list, &info->pending_urbs);
+	if (RING_FULL(&info->urb_ring)) {
+		list_add_tail(&urbp->list, &info->pending_submit_list);
 		COUNT(info->stats.ring_full);
 		timer_action(info, TIMER_RING_WATCHDOG);
 		goto done;
 	}
 
-	if (!list_empty(&info->pending_urbs)) {
-		list_add_tail(&urbp->list, &info->pending_urbs);
+	if (!list_empty(&info->pending_submit_list)) {
+		list_add_tail(&urbp->list, &info->pending_submit_list);
 		timer_action(info, TIMER_SCAN_PENDING_URBS);
 		goto done;
 	}
 
 	ret = xenhcd_do_request(info, urbp);
 	if (ret == 0)
-		list_add_tail(&urbp->list, &info->inprogress_urbs);
+		list_add_tail(&urbp->list, &info->in_progress_list);
 
 done:
 	return ret;
@@ -327,26 +367,47 @@
 
 static int xenhcd_unlink_urb(struct usbfront_info *info, struct urb_priv *urbp)
 {
+	int ret = 0;
+
+	/* already unlinked? */
 	if (urbp->unlinked)
 		return -EBUSY;
+
 	urbp->unlinked = 1;
 
-	/* if the urb is in pending_urbs */
+	/* the urb is still in pending_submit queue */
 	if (urbp->req_id == ~0) {
-		list_move_tail(&urbp->list, &info->unlinked_urbs);
+		list_move_tail(&urbp->list, &info->giveback_waiting_list);
 		timer_action(info, TIMER_SCAN_PENDING_URBS);
+		goto done;
 	}
 
-	/* TODO: send cancel request to backend */
+	/* send unlink request to backend */
+	if (RING_FULL(&info->urb_ring)) {
+		list_move_tail(&urbp->list, &info->pending_unlink_list);
+		COUNT(info->stats.ring_full);
+		timer_action(info, TIMER_RING_WATCHDOG);
+		goto done;
+	}
 
-	return 0;
+	if (!list_empty(&info->pending_unlink_list)) {
+		list_move_tail(&urbp->list, &info->pending_unlink_list);
+		timer_action(info, TIMER_SCAN_PENDING_URBS);
+		goto done;
+	}
+
+	ret = xenhcd_do_request(info, urbp);
+	if (ret == 0)
+		list_move_tail(&urbp->list, &info->in_progress_list);
+
+done:
+	return ret;
 }
 
-static int xenhcd_end_submit_urb(struct usbfront_info *info)
+static int xenhcd_urb_request_done(struct usbfront_info *info)
 {
-	usbif_response_t *ring_res;
+	usbif_urb_response_t *res;
 	struct urb *urb;
-	struct urb_priv *urbp;
 
 	RING_IDX i, rp;
 	uint16_t id;
@@ -354,33 +415,35 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&info->lock, flags);
-	rp = info->ring.sring->rsp_prod;
+
+	rp = info->urb_ring.sring->rsp_prod;
 	rmb(); /* ensure we see queued responses up to "rp" */
 
-	for (i = info->ring.rsp_cons; i != rp; i++) {
-		ring_res = RING_GET_RESPONSE(&info->ring, i);
-		id = ring_res->id;
-		xenhcd_gnttab_done(&info->shadow[id]);
-		urb = info->shadow[id].urb;
-		barrier();
+	for (i = info->urb_ring.rsp_cons; i != rp; i++) {
+		res = RING_GET_RESPONSE(&info->urb_ring, i);
+		id = res->id;
+
+		if (likely(usbif_pipesubmit(info->shadow[id].req.pipe))) {
+			xenhcd_gnttab_done(&info->shadow[id]);
+			urb = info->shadow[id].urb;
+			barrier();
+			if (likely(urb)) {
+				urb->actual_length = res->actual_length;
+				urb->error_count = res->error_count;
+				urb->start_frame = res->start_frame;
+				barrier();
+				xenhcd_giveback_urb(info, urb, res->status);
+			}
+		}
+
 		add_id_to_freelist(info, id);
+	}
+	info->urb_ring.rsp_cons = i;
 
-		urbp = (struct urb_priv *)urb->hcpriv;
-		if (likely(!urbp->unlinked)) {
-			urb->status = ring_res->status;
-			urb->actual_length = ring_res->actual_length;
-			urb->error_count = ring_res->error_count;
-			urb->start_frame = ring_res->start_frame;
-		}
-		barrier();
-		xenhcd_giveback_urb(info, urb);
-	}
-	info->ring.rsp_cons = i;
-
-	if (i != info->ring.req_prod_pvt)
-		RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
+	if (i != info->urb_ring.req_prod_pvt)
+		RING_FINAL_CHECK_FOR_RESPONSES(&info->urb_ring, more_to_do);
 	else
-		info->ring.sring->rsp_event = i + 1;
+		info->urb_ring.sring->rsp_event = i + 1;
 
 	spin_unlock_irqrestore(&info->lock, flags);
 
@@ -389,6 +452,61 @@
 	return more_to_do;
 }
 
+static int xenhcd_conn_notify(struct usbfront_info *info)
+{
+	usbif_conn_response_t *res;
+	usbif_conn_request_t *req;
+	RING_IDX rc, rp;
+	uint16_t id;
+	uint8_t portnum, speed;
+	int more_to_do = 0;
+	int notify;
+	int port_changed = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&info->lock, flags);
+
+	rc = info->conn_ring.rsp_cons;
+	rp = info->conn_ring.sring->rsp_prod;
+	rmb(); /* ensure we see queued responses up to "rp" */
+
+	while (rc != rp) {
+		res = RING_GET_RESPONSE(&info->conn_ring, rc);
+		id = res->id;
+		portnum = res->portnum;
+		speed = res->speed;
+		info->conn_ring.rsp_cons = ++rc;
+
+		rhport_connect(info, portnum, speed);
+		if (info->ports[portnum-1].c_connection)
+			port_changed = 1;
+
+		barrier();
+
+		req = RING_GET_REQUEST(&info->conn_ring, info->conn_ring.req_prod_pvt);
+		req->id = id;
+		info->conn_ring.req_prod_pvt++;
+	}
+
+	if (rc != info->conn_ring.req_prod_pvt)
+		RING_FINAL_CHECK_FOR_RESPONSES(&info->conn_ring, more_to_do);
+	else
+		info->conn_ring.sring->rsp_event = rc + 1;
+
+	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->conn_ring, notify);
+	if (notify)
+		notify_remote_via_irq(info->irq);
+
+	spin_unlock_irqrestore(&info->lock, flags);
+
+	if (port_changed)
+		usb_hcd_poll_rh_status(info_to_hcd(info));
+
+	cond_resched();
+
+	return more_to_do;
+}
+
 int xenhcd_schedule(void *arg)
 {
 	struct usbfront_info *info = (struct usbfront_info *) arg;
@@ -400,7 +518,10 @@
 		info->waiting_resp = 0;
 		smp_mb();
 
-		if (xenhcd_end_submit_urb(info))
+		if (xenhcd_urb_request_done(info))
+			info->waiting_resp = 1;
+
+		if (xenhcd_conn_notify(info))
 			info->waiting_resp = 1;
 	}
 
diff -r 4ac3e1d6605c -r 3be939975ad6 drivers/xen/usbfront/usbfront.h
--- a/drivers/xen/usbfront/usbfront.h	Tue Sep 29 11:23:06 2009 +0100
+++ b/drivers/xen/usbfront/usbfront.h	Tue Oct 06 15:18:27 2009 +0900
@@ -66,8 +66,6 @@
 #include "../../usb/core/hcd.h"
 #include "../../usb/core/hub.h"
 
-#define DRIVER_DESC "Xen USB2.0 Virtual Host Controller driver (usbfront)"
-
 static inline struct usbfront_info *hcd_to_info(struct usb_hcd *hcd)
 {
 	return (struct usbfront_info *) (hcd->hcd_priv);
@@ -75,17 +73,16 @@
 
 static inline struct usb_hcd *info_to_hcd(struct usbfront_info *info)
 {
-	return container_of ((void *) info, struct usb_hcd, hcd_priv);
+	return container_of((void *) info, struct usb_hcd, hcd_priv);
 }
 
-/*
- * Private per-URB data
- */
+/* Private per-URB data */
 struct urb_priv {
 	struct list_head list;
 	struct urb *urb;
-	int req_id;	/* RING_REQUEST id */
-	unsigned unlinked:1; /* dequeued urb just marked */
+	int req_id;	/* RING_REQUEST id for submitting */
+	int unlink_req_id; /* RING_REQUEST id for unlinking */
+	unsigned unlinked:1; /* dequeued marker */
 };
 
 /* virtual roothub port status */
@@ -105,7 +102,7 @@
 
 /* RING request shadow */
 struct usb_shadow {
-	usbif_request_t req;
+	usbif_urb_request_t req;
 	struct urb *urb;
 };
 
@@ -117,62 +114,46 @@
 };
 
 struct usbfront_info {
-	/*
-	 * Virtual Host Controller has 3 queues.
-	 *
-	 * pending_urbs:
-	 * 	If xenhcd_urb_enqueue() called in RING_FULL state,
-	 * 	the enqueued urbs are added to this queue, and waits
-	 * 	to be sent to the backend.
-	 *
-	 * inprogress_urbs:
-	 * 	After xenhcd_urb_enqueue() called and RING_REQUEST sent,
-	 * 	the urbs are added to this queue and waits for RING_RESPONSE.
-	 *
-	 * unlinked_urbs:
-	 *	When xenhcd_urb_dequeue() called, if the dequeued urb is
-	 *	listed in pending_urbs, that urb is moved to this queue
-	 *	and waits to be given back to the USB core.
-	 */
-	struct list_head pending_urbs;
-	struct list_head inprogress_urbs;
-	struct list_head unlinked_urbs;
+	/* Virtual Host Controller has 4 urb queues */
+	struct list_head pending_submit_list;
+	struct list_head pending_unlink_list;
+	struct list_head in_progress_list;
+	struct list_head giveback_waiting_list;
+
 	spinlock_t lock;
 
-	/*
-	 * timer function that kick pending_urbs and unlink_urbs.
-	 */
+	/* timer that kick pending and giveback waiting urbs */
+	struct timer_list watchdog;
 	unsigned long actions;
-	struct timer_list watchdog;
 
-	/*
-	 * Virtual roothub:
-	 * Emulates the hub ports and the attached devices status.
-	 * USB_MAXCHILDREN is defined (16) in include/linux/usb.h
-	 */
+	/* virtual root hub */
 	int rh_numports;
 	struct rhport_status ports[USB_MAXCHILDREN];
 	struct vdevice_status devices[USB_MAXCHILDREN];
 
+	/* Xen related staff */
+	struct xenbus_device *xbdev;
+	int urb_ring_ref;
+	int conn_ring_ref;
+	usbif_urb_front_ring_t urb_ring;
+	usbif_conn_front_ring_t conn_ring;
+
+	unsigned int irq; /* event channel */
+	struct usb_shadow shadow[USB_URB_RING_SIZE];
+	unsigned long shadow_free;
+
+	/* RING_RESPONSE thread */
+	struct task_struct *kthread;
+	wait_queue_head_t wq;
+	unsigned int waiting_resp;
+
+	/* xmit statistics */
 #ifdef XENHCD_STATS
 	struct xenhcd_stats stats;
 #define COUNT(x) do { (x)++; } while (0)
 #else
 #define COUNT(x) do {} while (0)
 #endif
-
-	/* Xen related staff */
-	struct xenbus_device *xbdev;
-	int ring_ref;
-	usbif_front_ring_t ring;
-	unsigned int irq;
-	struct usb_shadow shadow[USB_RING_SIZE];
-	unsigned long shadow_free;
-
-	/* RING_RESPONSE thread */
-	struct task_struct *kthread;
-	wait_queue_head_t wq;
-	unsigned int waiting_resp;
 };
 
 #define XENHCD_RING_JIFFIES (HZ/200)
@@ -199,7 +180,7 @@
 	if (!test_and_set_bit(action, &info->actions)) {
 		unsigned long t;
 
-		switch(action) {
+		switch (action) {
 		case TIMER_RING_WATCHDOG:
 			t = XENHCD_RING_JIFFIES;
 			break;
@@ -211,6 +192,12 @@
 	}
 }
 
+extern struct kmem_cache *xenhcd_urbp_cachep;
+extern struct hc_driver xen_usb20_hc_driver;
+extern struct hc_driver xen_usb11_hc_driver;
 irqreturn_t xenhcd_int(int irq, void *dev_id, struct pt_regs *ptregs);
+void xenhcd_rhport_state_change(struct usbfront_info *info,
+				int port, enum usb_device_speed speed);
+int xenhcd_schedule(void *arg);
 
 #endif /* __XEN_USBFRONT_H__ */
diff -r 4ac3e1d6605c -r 3be939975ad6 drivers/xen/usbfront/xenbus.c
--- a/drivers/xen/usbfront/xenbus.c	Tue Sep 29 11:23:06 2009 +0100
+++ b/drivers/xen/usbfront/xenbus.c	Tue Oct 06 15:18:27 2009 +0900
@@ -45,50 +45,70 @@
 
 #include "usbfront.h"
 
-extern struct hc_driver usbfront_hc_driver;
-extern struct kmem_cache *xenhcd_urbp_cachep;
-extern void xenhcd_rhport_state_change(struct usbfront_info *info,
-					int port, enum usb_device_speed speed);
-extern int xenhcd_schedule(void *arg);
-
 #define GRANT_INVALID_REF 0
 
-static void usbif_free(struct usbfront_info *info)
+static void destroy_rings(struct usbfront_info *info)
 {
-	if (info->ring_ref != GRANT_INVALID_REF) {
-		gnttab_end_foreign_access(info->ring_ref,
-					  (unsigned long)info->ring.sring);
-		info->ring_ref = GRANT_INVALID_REF;
-		info->ring.sring = NULL;
-	}
 	if (info->irq)
 		unbind_from_irqhandler(info->irq, info);
 	info->irq = 0;
+
+	if (info->urb_ring_ref != GRANT_INVALID_REF) {
+		gnttab_end_foreign_access(info->urb_ring_ref,
+					  (unsigned long)info->urb_ring.sring);
+		info->urb_ring_ref = GRANT_INVALID_REF;
+	}
+	info->urb_ring.sring = NULL;
+
+	if (info->conn_ring_ref != GRANT_INVALID_REF) {
+		gnttab_end_foreign_access(info->conn_ring_ref,
+					  (unsigned long)info->conn_ring.sring);
+		info->conn_ring_ref = GRANT_INVALID_REF;
+	}
+	info->conn_ring.sring = NULL;
 }
 
-static int setup_usbring(struct xenbus_device *dev,
+static int setup_rings(struct xenbus_device *dev,
 			   struct usbfront_info *info)
 {
-	usbif_sring_t *sring;
+	usbif_urb_sring_t *urb_sring;
+	usbif_conn_sring_t *conn_sring;
 	int err;
 
-	info->ring_ref= GRANT_INVALID_REF;
+	info->urb_ring_ref = GRANT_INVALID_REF;
+	info->conn_ring_ref = GRANT_INVALID_REF;
 
-	sring = (usbif_sring_t *)get_zeroed_page(GFP_NOIO|__GFP_HIGH);
-	if (!sring) {
-		xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
+	urb_sring = (usbif_urb_sring_t *)get_zeroed_page(GFP_NOIO|__GFP_HIGH);
+	if (!urb_sring) {
+		xenbus_dev_fatal(dev, -ENOMEM, "allocating urb ring");
 		return -ENOMEM;
 	}
-	SHARED_RING_INIT(sring);
-	FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
+	SHARED_RING_INIT(urb_sring);
+	FRONT_RING_INIT(&info->urb_ring, urb_sring, PAGE_SIZE);
 
-	err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
+	err = xenbus_grant_ring(dev, virt_to_mfn(info->urb_ring.sring));
 	if (err < 0) {
-		free_page((unsigned long)sring);
-		info->ring.sring = NULL;
+		free_page((unsigned long)urb_sring);
+		info->urb_ring.sring = NULL;
 		goto fail;
 	}
-	info->ring_ref = err;
+	info->urb_ring_ref = err;
+
+	conn_sring = (usbif_conn_sring_t *)get_zeroed_page(GFP_NOIO|__GFP_HIGH);
+	if (!conn_sring) {
+		xenbus_dev_fatal(dev, -ENOMEM, "allocating conn ring");
+		return -ENOMEM;
+	}
+	SHARED_RING_INIT(conn_sring);
+	FRONT_RING_INIT(&info->conn_ring, conn_sring, PAGE_SIZE);
+
+	err = xenbus_grant_ring(dev, virt_to_mfn(info->conn_ring.sring));
+	if (err < 0) {
+		free_page((unsigned long)conn_sring);
+		info->conn_ring.sring = NULL;
+		goto fail;
+	}
+	info->conn_ring_ref = err;
 
 	err = bind_listening_port_to_irqhandler(
 		dev->otherend_id, xenhcd_int, SA_SAMPLE_RANDOM, "usbif", info);
@@ -101,7 +121,7 @@
 
 	return 0;
 fail:
-	usbif_free(info);
+	destroy_rings(info);
 	return err;
 }
 
@@ -112,7 +132,7 @@
 	struct xenbus_transaction xbt;
 	int err;
 
-	err = setup_usbring(dev, info);
+	err = setup_rings(dev, info);
 	if (err)
 		goto out;
 
@@ -123,10 +143,17 @@
 		goto destroy_ring;
 	}
 
-	err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u",
-			    info->ring_ref);
+	err = xenbus_printf(xbt, dev->nodename, "urb-ring-ref", "%u",
+			    info->urb_ring_ref);
 	if (err) {
-		message = "writing ring-ref";
+		message = "writing urb-ring-ref";
+		goto abort_transaction;
+	}
+
+	err = xenbus_printf(xbt, dev->nodename, "conn-ring-ref", "%u",
+			    info->conn_ring_ref);
+	if (err) {
+		message = "writing conn-ring-ref";
 		goto abort_transaction;
 	}
 
@@ -145,8 +172,6 @@
 		goto destroy_ring;
 	}
 
-	xenbus_switch_state(dev, XenbusStateInitialised);
-
 	return 0;
 
 abort_transaction:
@@ -154,17 +179,45 @@
 	xenbus_dev_fatal(dev, err, "%s", message);
 
 destroy_ring:
-	usbif_free(info);
+	destroy_rings(info);
 
 out:
 	return err;
 }
 
+static int connect(struct xenbus_device *dev)
+{
+	struct usbfront_info *info = dev->dev.driver_data;
+
+	usbif_conn_request_t *req;
+	int i, idx, err;
+	int notify;
+
+	err = talk_to_backend(dev, info);
+	if (err)
+		return err;
+
+	/* prepare ring for hotplug notification */
+	for (idx = 0, i = 0; i < USB_CONN_RING_SIZE; i++) {
+		req = RING_GET_REQUEST(&info->conn_ring, idx);
+		req->id = idx;
+		idx++;
+	}
+	info->conn_ring.req_prod_pvt = idx;
+
+	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->conn_ring, notify);
+	if (notify)
+		notify_remote_via_irq(info->irq);
+
+	return 0;
+}
+
 static struct usb_hcd *create_hcd(struct xenbus_device *dev)
 {
 	int i;
 	int err = 0;
 	int num_ports;
+	int usb_ver;
 	struct usb_hcd *hcd = NULL;
 	struct usbfront_info *info = NULL;
 
@@ -179,20 +232,38 @@
 		return ERR_PTR(-EINVAL);
 	}
 
-	hcd = usb_create_hcd(&usbfront_hc_driver, &dev->dev, dev->dev.bus_id);
+	err = xenbus_scanf(XBT_NIL, dev->otherend,
+					"usb-ver", "%d", &usb_ver);
+	if (err != 1) {
+		xenbus_dev_fatal(dev, err, "reading usb-ver");
+		return ERR_PTR(-EINVAL);
+	}
+	switch (usb_ver) {
+	case USB_VER_USB11:
+		hcd = usb_create_hcd(&xen_usb11_hc_driver, &dev->dev, dev->dev.bus_id);
+		break;
+	case USB_VER_USB20:
+		hcd = usb_create_hcd(&xen_usb20_hc_driver, &dev->dev, dev->dev.bus_id);
+		break;
+	default:
+		xenbus_dev_fatal(dev, err, "invalid usb-ver");
+		return ERR_PTR(-EINVAL);
+	}
 	if (!hcd) {
-		xenbus_dev_fatal(dev, err, "fail to allocate USB host controller");
+		xenbus_dev_fatal(dev, err,
+				"fail to allocate USB host controller");
 		return ERR_PTR(-ENOMEM);
 	}
+
 	info = hcd_to_info(hcd);
 	info->xbdev = dev;
 	info->rh_numports = num_ports;
 
-	for (i = 0; i < USB_RING_SIZE; i++) {
-		info->shadow[i].req.id = i+1;
+	for (i = 0; i < USB_URB_RING_SIZE; i++) {
+		info->shadow[i].req.id = i + 1;
 		info->shadow[i].urb = NULL;
 	}
-	info->shadow[USB_RING_SIZE-1].req.id = 0x0fff;
+	info->shadow[USB_URB_RING_SIZE-1].req.id = 0x0fff;
 
 	return hcd;
 }
@@ -211,7 +282,8 @@
 	hcd = create_hcd(dev);
 	if (IS_ERR(hcd)) {
 		err = PTR_ERR(hcd);
-		xenbus_dev_fatal(dev, err, "fail to create usb host controller");
+		xenbus_dev_fatal(dev, err,
+				"fail to create usb host controller");
 		goto fail;
 	}
 
@@ -220,22 +292,19 @@
 
 	err = usb_add_hcd(hcd, 0, 0);
 	if (err != 0) {
-		xenbus_dev_fatal(dev, err, "fail to adding USB host controller");
+		xenbus_dev_fatal(dev, err,
+				"fail to adding USB host controller");
 		goto fail;
 	}
 
 	init_waitqueue_head(&info->wq);
 	snprintf(name, TASK_COMM_LEN, "xenhcd.%d", hcd->self.busnum);
 	info->kthread = kthread_run(xenhcd_schedule, info, name);
-        if (IS_ERR(info->kthread)) {
-                err = PTR_ERR(info->kthread);
-                info->kthread = NULL;
-                goto fail;
-        }
-
-	err = talk_to_backend(dev, info);
-	if (err)
+	if (IS_ERR(info->kthread)) {
+		err = PTR_ERR(info->kthread);
+		info->kthread = NULL;
 		goto fail;
+	}
 
 	return 0;
 
@@ -245,58 +314,41 @@
 	return err;
 }
 
-/*
- * 0=disconnected, 1=low_speed, 2=full_speed, 3=high_speed
- */
-static void usbfront_do_hotplug(struct usbfront_info *info)
+static void usbfront_disconnect(struct xenbus_device *dev)
 {
-	char port_str[8];
-	int i;
-	int err;
-	int state;
+	struct usbfront_info *info = dev->dev.driver_data;
+	struct usb_hcd *hcd = info_to_hcd(info);
 
-	for (i = 1; i <= info->rh_numports; i++) {
-		sprintf(port_str, "port-%d", i);
-		err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
-					port_str, "%d", &state);
-		if (err == 1)
-			xenhcd_rhport_state_change(info, i, state);
+	usb_remove_hcd(hcd);
+	if (info->kthread) {
+		kthread_stop(info->kthread);
+		info->kthread = NULL;
 	}
+	xenbus_frontend_closed(dev);
 }
 
 static void backend_changed(struct xenbus_device *dev,
 				     enum xenbus_state backend_state)
 {
-	struct usbfront_info *info = dev->dev.driver_data;
-
 	switch (backend_state) {
 	case XenbusStateInitialising:
-	case XenbusStateInitWait:
 	case XenbusStateInitialised:
+	case XenbusStateConnected:
+	case XenbusStateReconfiguring:
+	case XenbusStateReconfigured:
 	case XenbusStateUnknown:
 	case XenbusStateClosed:
 		break;
 
-	case XenbusStateConnected:
-		if (dev->state == XenbusStateConnected)
+	case XenbusStateInitWait:
+		if (dev->state != XenbusStateInitialising)
 			break;
-		if (dev->state == XenbusStateInitialised)
-			usbfront_do_hotplug(info);
+		connect(dev);
 		xenbus_switch_state(dev, XenbusStateConnected);
 		break;
 
 	case XenbusStateClosing:
-		xenbus_frontend_closed(dev);
-		break;
-
-	case XenbusStateReconfiguring:
-		if (dev->state == XenbusStateConnected)
-			xenbus_switch_state(dev, XenbusStateReconfiguring);
-		break;
-
-	case XenbusStateReconfigured:
-		usbfront_do_hotplug(info);
-		xenbus_switch_state(dev, XenbusStateConnected);
+		usbfront_disconnect(dev);
 		break;
 
 	default:
@@ -311,12 +363,7 @@
 	struct usbfront_info *info = dev->dev.driver_data;
 	struct usb_hcd *hcd = info_to_hcd(info);
 
-	usb_remove_hcd(hcd);
-	if (info->kthread) {
-		kthread_stop(info->kthread);
-		info->kthread = NULL;
-	}
-	usbif_free(info);
+	destroy_rings(info);
 	usb_put_hcd(hcd);
 
 	return 0;
@@ -361,5 +408,5 @@
 module_exit(usbfront_exit);
 
 MODULE_AUTHOR("");
-MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_DESCRIPTION("Xen USB Virtual Host Controller driver (usbfront)");
 MODULE_LICENSE("Dual BSD/GPL");

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/3] PVUSB update and bugfix: frontend part
  2009-10-07  7:27 [PATCH 1/3] PVUSB update and bugfix: frontend part Noboru Iwamatsu
@ 2009-10-08  1:28 ` Masaki Kanno
  2009-10-08  4:41   ` Noboru Iwamatsu
  0 siblings, 1 reply; 3+ messages in thread
From: Masaki Kanno @ 2009-10-08  1:28 UTC (permalink / raw)
  To: Noboru Iwamatsu, xen-devel

Hi Iwamatsu,

I encountered the following error.

In file included from /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hcd.c:48:
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c: In function ‘xenhcd_bus_suspend’:
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:220: error: ‘struct usbfront_info’ has no member named ‘flags’
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:220: error: ‘struct usbfront_info’ has no member named ‘flags’
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:222: error: ‘struct usbfront_info’ has no member named ‘dead’
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c: In function ‘xenhcd_bus_resume’:
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:243: error: ‘struct usbfront_info’ has no member named ‘flags’
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:243: error: ‘struct usbfront_info’ has no member named ‘flags’
/xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:245: error: ‘struct usbfront_info’ has no member named ‘dead’
make[9]: *** [drivers/xen/usbfront/usbfront-hcd.o] Error 1
make[8]: *** [drivers/xen/usbfront] Error 2
make[7]: *** [drivers/xen] Error 2
make[6]: *** [drivers] Error 2
make[5]: *** [modules] Error 2
make[4]: *** [modules] Error 2
make[4]: Leaving directory `/xen/xen-unstable.hg/build-linux-2.6.18-xen_x86_32'
make[3]: *** [build] Error 1
make[3]: Leaving directory `/xen/xen-unstable.hg'
make[2]: *** [linux-2.6-xen-install] Error 2
make[2]: Leaving directory `/xen/xen-unstable.hg'
make[1]: *** [install-kernels] Error 1
make[1]: Leaving directory `/xen/xen-unstable.hg'
make: *** [world] Error 2

Best regards,
 Kan

Wed, 07 Oct 2009 16:27:49 +0900, Noboru Iwamatsu wrote:

>Signed-off-by: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
>
>
>-------------------------------text/plain-------------------------------
>_______________________________________________
>Xen-devel mailing list
>Xen-devel@lists.xensource.com
>http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/3] PVUSB update and bugfix: frontend part
  2009-10-08  1:28 ` Masaki Kanno
@ 2009-10-08  4:41   ` Noboru Iwamatsu
  0 siblings, 0 replies; 3+ messages in thread
From: Noboru Iwamatsu @ 2009-10-08  4:41 UTC (permalink / raw)
  To: kanno.masaki; +Cc: xen-devel

Thanks,

> - experimental bus_suspend/bus_resume added to usbfront.

Sorry, I made a mistake to add the testing code.
I'm going to fix soon, and this feature is maybe disabled.

Noboru.

Masaki Kanno wrote:
> Hi Iwamatsu,
> 
> I encountered the following error.
> 
> In file included from /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hcd.c:48:
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c: In function ‘xenhcd_bus_suspend’:
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:220: error: ‘struct usbfront_info’ has no member named ‘flags’
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:220: error: ‘struct usbfront_info’ has no member named ‘flags’
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:222: error: ‘struct usbfront_info’ has no member named ‘dead’
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c: In function ‘xenhcd_bus_resume’:
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:243: error: ‘struct usbfront_info’ has no member named ‘flags’
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:243: error: ‘struct usbfront_info’ has no member named ‘flags’
> /xen/linux-2.6.18-xen.hg/drivers/xen/usbfront/usbfront-hub.c:245: error: ‘struct usbfront_info’ has no member named ‘dead’
> make[9]: *** [drivers/xen/usbfront/usbfront-hcd.o] Error 1
> make[8]: *** [drivers/xen/usbfront] Error 2
> make[7]: *** [drivers/xen] Error 2
> make[6]: *** [drivers] Error 2
> make[5]: *** [modules] Error 2
> make[4]: *** [modules] Error 2
> make[4]: Leaving directory `/xen/xen-unstable.hg/build-linux-2.6.18-xen_x86_32'
> make[3]: *** [build] Error 1
> make[3]: Leaving directory `/xen/xen-unstable.hg'
> make[2]: *** [linux-2.6-xen-install] Error 2
> make[2]: Leaving directory `/xen/xen-unstable.hg'
> make[1]: *** [install-kernels] Error 1
> make[1]: Leaving directory `/xen/xen-unstable.hg'
> make: *** [world] Error 2
> 
> Best regards,
>  Kan
> 
> Wed, 07 Oct 2009 16:27:49 +0900, Noboru Iwamatsu wrote:
> 
>> Signed-off-by: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
>>
>>
>> -------------------------------text/plain-------------------------------
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xensource.com
>> http://lists.xensource.com/xen-devel
> 


-- 
(株)富士通研究所 ITシステム研究所 サーバテクノロジ研究部
岩松 昇 n_iwamatsu@jp.fujitsu.com
Tel: 044-754-2538 / 7106-6372

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-10-08  4:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-07  7:27 [PATCH 1/3] PVUSB update and bugfix: frontend part Noboru Iwamatsu
2009-10-08  1:28 ` Masaki Kanno
2009-10-08  4:41   ` Noboru Iwamatsu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.