On 05/18/2017 04:08 AM, Yuyang Du wrote:
> From: Yuyang Du <yuyang...@intel.com>
> 
> 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...@intel.com>

Acked-by: Shuah Khan <shua...@osg.samsung.com>

thanks,
-- Shuah

> ---
>  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);
> 

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

Reply via email to