usbip: vhci-hcd: Set the vhci structure up to work
authorYuyang Du <yuyang.du@intel.com>
Thu, 8 Jun 2017 05:04:09 +0000 (13:04 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Jun 2017 08:51:10 +0000 (10:51 +0200)
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@intel.com>
Acked-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/usbip/vhci.h
drivers/usb/usbip/vhci_hcd.c
drivers/usb/usbip/vhci_rx.c
drivers/usb/usbip/vhci_sysfs.c

index 62ee537b44c8af8fbdd53d7c424e8b650f50257a..8a979fc00ac1d165cf3c0be4557bd09247d34d6e 100644 (file)
@@ -100,8 +100,6 @@ struct vhci {
 struct vhci_hcd {
        struct vhci *vhci;
 
-       spinlock_t lock;
-
        u32 port_status[VHCI_HC_PORTS];
 
        unsigned resuming:1;
index 893a5dedd0e58e85805cecbb609c7832216f6d78..c96dd44ff1629e1d9cdbe9eea08dc5220cedd0d2 100644 (file)
@@ -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);
 
@@ -252,7 +252,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;
@@ -272,13 +273,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));
        }
 
@@ -289,29 +291,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:
@@ -321,7 +323,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;
@@ -345,36 +347,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]);
@@ -393,21 +395,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;
@@ -424,12 +426,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;
 }
@@ -437,14 +439,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) {
@@ -454,7 +456,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");
 
@@ -472,7 +474,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;
@@ -486,7 +489,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);
@@ -639,7 +642,8 @@ no_need_unlink:
  */
 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;
@@ -690,7 +694,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 {
@@ -708,7 +712,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");
 
@@ -732,8 +736,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;
 
@@ -917,29 +922,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));
@@ -967,7 +990,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");
@@ -981,7 +1004,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);
@@ -999,7 +1022,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__);
@@ -1013,7 +1036,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;
 
@@ -1042,6 +1065,7 @@ static struct hc_driver vhci_hc_driver = {
 
        .flags          = HCD_USB2,
 
+       .reset          = vhci_setup,
        .start          = vhci_start,
        .stop           = vhci_stop,
 
@@ -1058,7 +1082,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);
@@ -1067,43 +1092,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;
 }
@@ -1114,22 +1141,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);
 
index 85abe898d7bd47e76c17b39b8e922ed09ea138c7..ef2f2d5ca6b2f94400ccc9268440cc6991a9d371 100644 (file)
@@ -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);
index 07f0d3789a8c09c36eaa61ac87e0f04a6319dd29..63e10a4ffeec8810e8ecf551a37bc69cc9e4992e 100644 (file)
 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);