[PATCH 5/9] usbip: vhci-hcd: Set the vhci structure up to work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch enables the new vhci structure. Its lock protects
both the USB2 hub and the shared USB3 hub.

Signed-off-by: Yuyang Du <yuyang.du@xxxxxxxxx>
---
 drivers/usb/usbip/vhci.h       |   2 -
 drivers/usb/usbip/vhci_hcd.c   | 206 ++++++++++++++++++++++++-----------------
 drivers/usb/usbip/vhci_rx.c    |  16 ++--
 drivers/usb/usbip/vhci_sysfs.c |  26 ++++--
 4 files changed, 145 insertions(+), 105 deletions(-)

diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h
index 62ee537..8a979fc 100644
--- a/drivers/usb/usbip/vhci.h
+++ b/drivers/usb/usbip/vhci.h
@@ -100,8 +100,6 @@ struct vhci {
 struct vhci_hcd {
 	struct vhci *vhci;
 
-	spinlock_t lock;
-
 	u32 port_status[VHCI_HC_PORTS];
 
 	unsigned resuming:1;
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index 2bc77ee..8cfba1d 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -123,7 +123,8 @@ static void dump_port_status_diff(u32 prev_status, u32 new_status)
 
 void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed)
 {
-	struct vhci_hcd	*vhci = vdev_to_vhci_hcd(vdev);
+	struct vhci_hcd	*vhci_hcd = vdev_to_vhci_hcd(vdev);
+	struct vhci *vhci = vhci_hcd->vhci;
 	int		rhport = vdev->rhport;
 	u32		status;
 	unsigned long	flags;
@@ -132,7 +133,7 @@ void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed)
 
 	spin_lock_irqsave(&vhci->lock, flags);
 
-	status = vhci->port_status[rhport];
+	status = vhci_hcd->port_status[rhport];
 
 	status |= USB_PORT_STAT_CONNECTION | (1 << USB_PORT_FEAT_C_CONNECTION);
 
@@ -147,16 +148,17 @@ void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed)
 		break;
 	}
 
-	vhci->port_status[rhport] = status;
+	vhci_hcd->port_status[rhport] = status;
 
 	spin_unlock_irqrestore(&vhci->lock, flags);
 
-	usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci));
+	usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci_hcd));
 }
 
 static void rh_port_disconnect(struct vhci_device *vdev)
 {
-	struct vhci_hcd	*vhci = vdev_to_vhci_hcd(vdev);
+	struct vhci_hcd	*vhci_hcd = vdev_to_vhci_hcd(vdev);
+	struct vhci *vhci = vhci_hcd->vhci;
 	int		rhport = vdev->rhport;
 	u32		status;
 	unsigned long	flags;
@@ -165,15 +167,15 @@ static void rh_port_disconnect(struct vhci_device *vdev)
 
 	spin_lock_irqsave(&vhci->lock, flags);
 
-	status = vhci->port_status[rhport];
+	status = vhci_hcd->port_status[rhport];
 
 	status &= ~USB_PORT_STAT_CONNECTION;
 	status |= (1 << USB_PORT_FEAT_C_CONNECTION);
 
-	vhci->port_status[rhport] = status;
+	vhci_hcd->port_status[rhport] = status;
 
 	spin_unlock_irqrestore(&vhci->lock, flags);
-	usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci));
+	usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci_hcd));
 }
 
 #define PORT_C_MASK				\
@@ -196,17 +198,15 @@ static void rh_port_disconnect(struct vhci_device *vdev)
  */
 static int vhci_hub_status(struct usb_hcd *hcd, char *buf)
 {
-	struct vhci_hcd	*vhci;
-	int		retval;
+	struct vhci_hcd	*vhci_hcd = hcd_to_vhci_hcd(hcd);
+	struct vhci *vhci = vhci_hcd->vhci;
+	int		retval = DIV_ROUND_UP(VHCI_HC_PORTS + 1, 8);
 	int		rhport;
 	int		changed = 0;
 	unsigned long	flags;
 
-	retval = DIV_ROUND_UP(VHCI_HC_PORTS + 1, 8);
 	memset(buf, 0, retval);
 
-	vhci = hcd_to_vhci_hcd(hcd);
-
 	spin_lock_irqsave(&vhci->lock, flags);
 	if (!HCD_HW_ACCESSIBLE(hcd)) {
 		usbip_dbg_vhci_rh("hw accessible flag not on?\n");
@@ -215,7 +215,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf)
 
 	/* check pseudo status register for each port */
 	for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
-		if ((vhci->port_status[rhport] & PORT_C_MASK)) {
+		if ((vhci_hcd->port_status[rhport] & PORT_C_MASK)) {
 			/* The status of a port has been changed, */
 			usbip_dbg_vhci_rh("port %d status changed\n", rhport);
 
@@ -247,7 +247,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc)
 static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			    u16 wIndex, char *buf, u16 wLength)
 {
-	struct vhci_hcd	*dum;
+	struct vhci_hcd	*vhci_hcd;
+	struct vhci	*vhci;
 	int             retval = 0;
 	int		rhport;
 	unsigned long	flags;
@@ -267,13 +268,14 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		pr_err("invalid port number %d\n", wIndex);
 	rhport = ((__u8)(wIndex & 0x00ff)) - 1;
 
-	dum = hcd_to_vhci_hcd(hcd);
+	vhci_hcd = hcd_to_vhci_hcd(hcd);
+	vhci = vhci_hcd->vhci;
 
-	spin_lock_irqsave(&dum->lock, flags);
+	spin_lock_irqsave(&vhci->lock, flags);
 
 	/* store old status and compare now and old later */
 	if (usbip_dbg_flag_vhci_rh) {
-		memcpy(prev_port_status, dum->port_status,
+		memcpy(prev_port_status, vhci_hcd->port_status,
 			sizeof(prev_port_status));
 	}
 
@@ -284,29 +286,29 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	case ClearPortFeature:
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
-			if (dum->port_status[rhport] & USB_PORT_STAT_SUSPEND) {
+			if (vhci_hcd->port_status[rhport] & USB_PORT_STAT_SUSPEND) {
 				/* 20msec signaling */
-				dum->resuming = 1;
-				dum->re_timeout =
+				vhci_hcd->resuming = 1;
+				vhci_hcd->re_timeout =
 					jiffies + msecs_to_jiffies(20);
 			}
 			break;
 		case USB_PORT_FEAT_POWER:
 			usbip_dbg_vhci_rh(
 				" ClearPortFeature: USB_PORT_FEAT_POWER\n");
-			dum->port_status[rhport] = 0;
-			dum->resuming = 0;
+			vhci_hcd->port_status[rhport] = 0;
+			vhci_hcd->resuming = 0;
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			usbip_dbg_vhci_rh(
 				" ClearPortFeature: USB_PORT_FEAT_C_RESET\n");
-			switch (dum->vdev[rhport].speed) {
+			switch (vhci_hcd->vdev[rhport].speed) {
 			case USB_SPEED_HIGH:
-				dum->port_status[rhport] |=
+				vhci_hcd->port_status[rhport] |=
 					USB_PORT_STAT_HIGH_SPEED;
 				break;
 			case USB_SPEED_LOW:
-				dum->port_status[rhport] |=
+				vhci_hcd->port_status[rhport] |=
 					USB_PORT_STAT_LOW_SPEED;
 				break;
 			default:
@@ -316,7 +318,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		default:
 			usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n",
 					  wValue);
-			dum->port_status[rhport] &= ~(1 << wValue);
+			vhci_hcd->port_status[rhport] &= ~(1 << wValue);
 			break;
 		}
 		break;
@@ -340,36 +342,36 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		/* whoever resets or resumes must GetPortStatus to
 		 * complete it!!
 		 */
-		if (dum->resuming && time_after(jiffies, dum->re_timeout)) {
-			dum->port_status[rhport] |=
+		if (vhci_hcd->resuming && time_after(jiffies, vhci_hcd->re_timeout)) {
+			vhci_hcd->port_status[rhport] |=
 				(1 << USB_PORT_FEAT_C_SUSPEND);
-			dum->port_status[rhport] &=
+			vhci_hcd->port_status[rhport] &=
 				~(1 << USB_PORT_FEAT_SUSPEND);
-			dum->resuming = 0;
-			dum->re_timeout = 0;
+			vhci_hcd->resuming = 0;
+			vhci_hcd->re_timeout = 0;
 		}
 
-		if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) !=
-		    0 && time_after(jiffies, dum->re_timeout)) {
-			dum->port_status[rhport] |=
+		if ((vhci_hcd->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) !=
+		    0 && time_after(jiffies, vhci_hcd->re_timeout)) {
+			vhci_hcd->port_status[rhport] |=
 				(1 << USB_PORT_FEAT_C_RESET);
-			dum->port_status[rhport] &=
+			vhci_hcd->port_status[rhport] &=
 				~(1 << USB_PORT_FEAT_RESET);
-			dum->re_timeout = 0;
+			vhci_hcd->re_timeout = 0;
 
-			if (dum->vdev[rhport].ud.status ==
+			if (vhci_hcd->vdev[rhport].ud.status ==
 			    VDEV_ST_NOTASSIGNED) {
 				usbip_dbg_vhci_rh(
 					" enable rhport %d (status %u)\n",
 					rhport,
-					dum->vdev[rhport].ud.status);
-				dum->port_status[rhport] |=
+					vhci_hcd->vdev[rhport].ud.status);
+				vhci_hcd->port_status[rhport] |=
 					USB_PORT_STAT_ENABLE;
 			}
 		}
-		((__le16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]);
+		((__le16 *) buf)[0] = cpu_to_le16(vhci_hcd->port_status[rhport]);
 		((__le16 *) buf)[1] =
-			cpu_to_le16(dum->port_status[rhport] >> 16);
+			cpu_to_le16(vhci_hcd->port_status[rhport] >> 16);
 
 		usbip_dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0],
 				  ((u16 *)buf)[1]);
@@ -388,21 +390,21 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			usbip_dbg_vhci_rh(
 				" SetPortFeature: USB_PORT_FEAT_RESET\n");
 			/* if it's already running, disconnect first */
-			if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
-				dum->port_status[rhport] &=
+			if (vhci_hcd->port_status[rhport] & USB_PORT_STAT_ENABLE) {
+				vhci_hcd->port_status[rhport] &=
 					~(USB_PORT_STAT_ENABLE |
 					  USB_PORT_STAT_LOW_SPEED |
 					  USB_PORT_STAT_HIGH_SPEED);
 				/* FIXME test that code path! */
 			}
 			/* 50msec reset signaling */
-			dum->re_timeout = jiffies + msecs_to_jiffies(50);
+			vhci_hcd->re_timeout = jiffies + msecs_to_jiffies(50);
 
 			/* FALLTHROUGH */
 		default:
 			usbip_dbg_vhci_rh(" SetPortFeature: default %d\n",
 					  wValue);
-			dum->port_status[rhport] |= (1 << wValue);
+			vhci_hcd->port_status[rhport] |= (1 << wValue);
 			break;
 		}
 		break;
@@ -419,12 +421,12 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		/* Only dump valid port status */
 		if (rhport >= 0) {
 			dump_port_status_diff(prev_port_status[rhport],
-					      dum->port_status[rhport]);
+					      vhci_hcd->port_status[rhport]);
 		}
 	}
 	usbip_dbg_vhci_rh(" bye\n");
 
-	spin_unlock_irqrestore(&dum->lock, flags);
+	spin_unlock_irqrestore(&vhci->lock, flags);
 
 	return retval;
 }
@@ -432,14 +434,14 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev)
 {
 	struct vhci_priv *priv;
-	struct vhci_hcd *vhci;
+	struct vhci_hcd *vhci_hcd;
 	unsigned long flags;
 
 	if (!vdev) {
 		pr_err("could not get virtual device");
 		return;
 	}
-	vhci = vdev_to_vhci_hcd(vdev);
+	vhci_hcd = vdev_to_vhci_hcd(vdev);
 
 	priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
 	if (!priv) {
@@ -449,7 +451,7 @@ static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev)
 
 	spin_lock_irqsave(&vdev->priv_lock, flags);
 
-	priv->seqnum = atomic_inc_return(&vhci->seqnum);
+	priv->seqnum = atomic_inc_return(&vhci_hcd->seqnum);
 	if (priv->seqnum == 0xffff)
 		dev_info(&urb->dev->dev, "seqnum max\n");
 
@@ -467,7 +469,8 @@ static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev)
 static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 			    gfp_t mem_flags)
 {
-	struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd);
+	struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
+	struct vhci *vhci = vhci_hcd->vhci;
 	struct device *dev = &urb->dev->dev;
 	u8 portnum = urb->dev->portnum;
 	int ret = 0;
@@ -481,7 +484,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 		pr_err("invalid port number %d\n", portnum);
 		return -ENODEV;
 	}
-	vdev = &vhci->vdev[portnum-1];
+	vdev = &vhci_hcd->vdev[portnum-1];
 
 	/* patch to usb_sg_init() is in 2.5.60 */
 	BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length);
@@ -634,7 +637,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
  */
 static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 {
-	struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd);
+	struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
+	struct vhci *vhci = vhci_hcd->vhci;
 	struct vhci_priv *priv;
 	struct vhci_device *vdev;
 	unsigned long flags;
@@ -685,7 +689,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 		usb_hcd_unlink_urb_from_ep(hcd, urb);
 
 		spin_unlock_irqrestore(&vhci->lock, flags);
-		usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci), urb, urb->status);
+		usb_hcd_giveback_urb(hcd, urb, urb->status);
 		spin_lock_irqsave(&vhci->lock, flags);
 
 	} else {
@@ -703,7 +707,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 			return -ENOMEM;
 		}
 
-		unlink->seqnum = atomic_inc_return(&vhci->seqnum);
+		unlink->seqnum = atomic_inc_return(&vhci_hcd->seqnum);
 		if (unlink->seqnum == 0xffff)
 			pr_info("seqnum max\n");
 
@@ -727,8 +731,9 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 
 static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
 {
-	struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev);
-	struct usb_hcd *hcd = vhci_hcd_to_hcd(vhci);
+	struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
+	struct usb_hcd *hcd = vhci_hcd_to_hcd(vhci_hcd);
+	struct vhci *vhci = vhci_hcd->vhci;
 	struct vhci_unlink *unlink, *tmp;
 	unsigned long flags;
 
@@ -912,29 +917,47 @@ static int hcd_name_to_id(const char *name)
 	return val;
 }
 
+static int vhci_setup(struct usb_hcd *hcd)
+{
+	struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller));
+	hcd->self.sg_tablesize = ~0;
+
+	vhci->vhci_hcd_hs = hcd_to_vhci_hcd(hcd);
+	vhci->vhci_hcd_hs->vhci = vhci;
+	hcd->speed = HCD_USB2;
+	hcd->self.root_hub->speed = USB_SPEED_HIGH;
+
+	return 0;
+}
+
 static int vhci_start(struct usb_hcd *hcd)
 {
-	struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd);
+	struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
 	int id, rhport;
-	int err = 0;
+	int err;
 
 	usbip_dbg_vhci_hc("enter vhci_start\n");
 
+	spin_lock_init(&vhci_hcd->vhci->lock);
+
 	/* initialize private data of usb_hcd */
 
 	for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
+		struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
 
 		vhci_device_init(vdev);
 		vdev->rhport = rhport;
 	}
 
-	atomic_set(&vhci->seqnum, 0);
-	spin_lock_init(&vhci->lock);
+	atomic_set(&vhci_hcd->seqnum, 0);
 
 	hcd->power_budget = 0; /* no limit */
 	hcd->uses_new_polling = 1;
 
+#ifdef CONFIG_USB_OTG
+	hcd->self.otg_port = 1;
+#endif
+
 	id = hcd_name_to_id(hcd_name(hcd));
 	if (id < 0) {
 		pr_err("invalid vhci name %s\n", hcd_name(hcd));
@@ -962,7 +985,7 @@ static int vhci_start(struct usb_hcd *hcd)
 
 static void vhci_stop(struct usb_hcd *hcd)
 {
-	struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd);
+	struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
 	int id, rhport;
 
 	usbip_dbg_vhci_hc("stop VHCI controller\n");
@@ -976,7 +999,7 @@ static void vhci_stop(struct usb_hcd *hcd)
 
 	/* 2. shutdown all the ports of vhci_hcd */
 	for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
-		struct vhci_device *vdev = &vhci->vdev[rhport];
+		struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
 
 		usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED);
 		usbip_stop_eh(&vdev->ud);
@@ -994,7 +1017,7 @@ static int vhci_get_frame_number(struct usb_hcd *hcd)
 /* FIXME: suspend/resume */
 static int vhci_bus_suspend(struct usb_hcd *hcd)
 {
-	struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd);
+	struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller));
 	unsigned long flags;
 
 	dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
@@ -1008,7 +1031,7 @@ static int vhci_bus_suspend(struct usb_hcd *hcd)
 
 static int vhci_bus_resume(struct usb_hcd *hcd)
 {
-	struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd);
+	struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller));
 	int rc = 0;
 	unsigned long flags;
 
@@ -1037,6 +1060,7 @@ static struct hc_driver vhci_hc_driver = {
 
 	.flags		= HCD_USB2,
 
+	.reset		= vhci_setup,
 	.start		= vhci_start,
 	.stop		= vhci_stop,
 
@@ -1053,7 +1077,8 @@ static struct hc_driver vhci_hc_driver = {
 
 static int vhci_hcd_probe(struct platform_device *pdev)
 {
-	struct usb_hcd		*hcd;
+	struct vhci		*vhci;
+	struct usb_hcd		*hcd_hs;
 	int			ret;
 
 	usbip_dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
@@ -1062,43 +1087,45 @@ static int vhci_hcd_probe(struct platform_device *pdev)
 	 * Allocate and initialize hcd.
 	 * Our private data is also allocated automatically.
 	 */
-	hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, dev_name(&pdev->dev));
-	if (!hcd) {
+	hcd_hs = usb_create_hcd(&vhci_hc_driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd_hs) {
 		pr_err("create hcd failed\n");
 		return -ENOMEM;
 	}
-	hcd->has_tt = 1;
+	hcd_hs->has_tt = 1;
 
 	/*
 	 * Finish generic HCD structure initialization and register.
 	 * Call the driver's reset() and start() routines.
 	 */
-	ret = usb_add_hcd(hcd, 0, 0);
+	ret = usb_add_hcd(hcd_hs, 0, 0);
 	if (ret != 0) {
-		pr_err("usb_add_hcd failed %d\n", ret);
-		usb_put_hcd(hcd);
-		return ret;
+		pr_err("usb_add_hcd hs failed %d\n", ret);
+		goto put_usb2_hcd;
 	}
 
 	usbip_dbg_vhci_hc("bye\n");
 	return 0;
+
+put_usb2_hcd:
+	usb_put_hcd(hcd_hs);
+	vhci->vhci_hcd_hs = NULL;
+	return ret;
 }
 
 static int vhci_hcd_remove(struct platform_device *pdev)
 {
-	struct usb_hcd	*hcd;
-
-	hcd = platform_get_drvdata(pdev);
-	if (!hcd)
-		return 0;
+	struct vhci *vhci = *((void **)dev_get_platdata(&pdev->dev));
 
 	/*
 	 * Disconnects the root hub,
 	 * then reverses the effects of usb_add_hcd(),
 	 * invoking the HCD's stop() methods.
 	 */
-	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
+	usb_remove_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs));
+	usb_put_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs));
+
+	vhci->vhci_hcd_hs = NULL;
 
 	return 0;
 }
@@ -1109,22 +1136,27 @@ static int vhci_hcd_remove(struct platform_device *pdev)
 static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct usb_hcd *hcd;
-	struct vhci_hcd *vhci;
-	int rhport;
+	struct vhci *vhci;
+	int rhport = 0;
 	int connected = 0;
 	int ret = 0;
 	unsigned long flags;
 
+	dev_dbg(&pdev->dev, "%s\n", __func__);
+
 	hcd = platform_get_drvdata(pdev);
 	if (!hcd)
 		return 0;
-	vhci = hcd_to_vhci_hcd(hcd);
+
+	vhci = *((void **)dev_get_platdata(hcd->self.controller));
 
 	spin_lock_irqsave(&vhci->lock, flags);
 
-	for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++)
-		if (vhci->port_status[rhport] & USB_PORT_STAT_CONNECTION)
+	for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
+		if (vhci->vhci_hcd_hs->port_status[rhport] &
+		    USB_PORT_STAT_CONNECTION)
 			connected += 1;
+	}
 
 	spin_unlock_irqrestore(&vhci->lock, flags);
 
diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c
index 85abe89..ef2f2d5 100644
--- a/drivers/usb/usbip/vhci_rx.c
+++ b/drivers/usb/usbip/vhci_rx.c
@@ -70,7 +70,8 @@ struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
 static void vhci_recv_ret_submit(struct vhci_device *vdev,
 				 struct usbip_header *pdu)
 {
-	struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev);
+	struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
+	struct vhci *vhci = vhci_hcd->vhci;
 	struct usbip_device *ud = &vdev->ud;
 	struct urb *urb;
 	unsigned long flags;
@@ -82,7 +83,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 	if (!urb) {
 		pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
 		pr_info("max seqnum %d\n",
-			atomic_read(&vhci->seqnum));
+			atomic_read(&vhci_hcd->seqnum));
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
 		return;
 	}
@@ -107,10 +108,10 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 	usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
 
 	spin_lock_irqsave(&vhci->lock, flags);
-	usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci), urb);
+	usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb);
 	spin_unlock_irqrestore(&vhci->lock, flags);
 
-	usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci), urb, urb->status);
+	usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci_hcd), urb, urb->status);
 
 	usbip_dbg_vhci_rx("Leave\n");
 }
@@ -143,7 +144,8 @@ static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
 static void vhci_recv_ret_unlink(struct vhci_device *vdev,
 				 struct usbip_header *pdu)
 {
-	struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev);
+	struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
+	struct vhci *vhci = vhci_hcd->vhci;
 	struct vhci_unlink *unlink;
 	struct urb *urb;
 	unsigned long flags;
@@ -177,10 +179,10 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
 		pr_info("urb->status %d\n", urb->status);
 
 		spin_lock_irqsave(&vhci->lock, flags);
-		usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci), urb);
+		usb_hcd_unlink_urb_from_ep(vhci_hcd_to_hcd(vhci_hcd), urb);
 		spin_unlock_irqrestore(&vhci->lock, flags);
 
-		usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci), urb, urb->status);
+		usb_hcd_giveback_urb(vhci_hcd_to_hcd(vhci_hcd), urb, urb->status);
 	}
 
 	kfree(unlink);
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index 07f0d37..63e10a4 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -33,9 +33,11 @@
 static ssize_t status_show_vhci(int pdev_nr, char *out)
 {
 	struct platform_device *pdev = vhcis[pdev_nr].pdev;
-	struct vhci_hcd *vhci;
+	struct vhci *vhci;
+	struct usb_hcd *hcd;
+	struct vhci_hcd *vhci_hcd;
 	char *s = out;
-	int i = 0;
+	int i;
 	unsigned long flags;
 
 	if (!pdev || !out) {
@@ -43,7 +45,9 @@ static ssize_t status_show_vhci(int pdev_nr, char *out)
 		return 0;
 	}
 
-	vhci = hcd_to_vhci_hcd(platform_get_drvdata(pdev));
+	hcd = platform_get_drvdata(pdev);
+	vhci_hcd = hcd_to_vhci_hcd(hcd);
+	vhci = vhci_hcd->vhci;
 
 	spin_lock_irqsave(&vhci->lock, flags);
 
@@ -58,7 +62,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out)
 	 * port number and its peer IP address.
 	 */
 	for (i = 0; i < VHCI_HC_PORTS; i++) {
-		struct vhci_device *vdev = &vhci->vdev[i];
+		struct vhci_device *vdev = &vhci_hcd->vdev[i];
 
 		spin_lock(&vdev->ud.lock);
 		out += sprintf(out, "%04u %03u ",
@@ -147,9 +151,10 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR_RO(nports);
 
 /* Sysfs entry to shutdown a virtual connection */
-static int vhci_port_disconnect(struct vhci_hcd *vhci, __u32 rhport)
+static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, __u32 rhport)
 {
-	struct vhci_device *vdev = &vhci->vdev[rhport];
+	struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
+	struct vhci *vhci = vhci_hcd->vhci;
 	unsigned long flags;
 
 	usbip_dbg_vhci_sysfs("enter\n");
@@ -262,8 +267,9 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
 	int sockfd = 0;
 	__u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0;
 	struct usb_hcd *hcd;
-	struct vhci_hcd *vhci;
+	struct vhci_hcd *vhci_hcd;
 	struct vhci_device *vdev;
+	struct vhci *vhci;
 	int err;
 	unsigned long flags;
 
@@ -292,8 +298,10 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
 		dev_err(dev, "port %d is not ready\n", port);
 		return -EAGAIN;
 	}
-	vhci = hcd_to_vhci_hcd(hcd);
-	vdev = &vhci->vdev[rhport];
+
+	vhci_hcd = hcd_to_vhci_hcd(hcd);
+	vhci = vhci_hcd->vhci;
+	vdev = &vhci_hcd->vdev[rhport];
 
 	/* Extract socket from fd. */
 	socket = sockfd_lookup(sockfd, &err);
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux