On 12/26/2016 12:18 AM, Nobuo Iwata wrote: > Modification for dynamic device registration and unregistration. Why is this necessary? Could make your change logs concise with important details on why a change is needed and the functionality it adds. This change log is way too long and doesn't summarize the changes. Please note that the information in the cover-letter doesn't go into this commit. It helps to have a clear change log so it is easier for me to review the patch. thanks, -- Shuah > > 1. kernel config > > Following parameters are added. > > USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host > controller. The default is 8 - same as current VHCI_NPORTS. > USBIP_VHCI_MAX_HCS: Muximum number of USB/IP virtual host controllers. > The default is 1. > USBIP_VHCI_INIT_HCS: Initial number of USB/IP virtual host controllers. > The default is 1. > Static number of devices: USBIP_VHCI_NR_HCS is removed with this patch. > > 2. view from sysfs > > Sysfs structure is changed as following. > > BEFORE this patchset: > /sys/devices/platform > +-- vhci > +-- status > +-- attach > +-- detach > +-- usbip_debug > > AFTER: example for CONFIG_USBIP_INIT_HCS=2 CONFIG_USBIP_MAX_HCS=4 > At the beginning > /sys/devices/platform > +-- vhci > | +-- nports > | +-- status > | +-- status.1 > | +-- status.2 > | +-- status.3 > | +-- attach > | +-- detach > | +-- usbip_debug > +-- vhci.1 > > The status files are shown to the maximum number of devices. Port > status in status.2 and status.3 represents as free but corresponding > devices are not yes registered. > When all ports in status and status.1 are used, userspace tool requests > 'attach' to a port in status.2 then vhci.2 will be registred. The limit > is defined with USBIP_VHCI_MAX_NCS. > > By preparing muximum number of status files, there's no need to > introduce additional operations for userspace tool. > > When number of free ports becomes more than USBIP_VHCI_HC_PORTS * > VHCI_FREE_HCS(2), a free controller other than the first one will be > unregistered. It will be invoked by 'detach' operation and other error > situations which ports are released. > > Signed-off-by: Nobuo Iwata <nobuo.iwata@xxxxxxxxxxxxxxx> > --- > drivers/usb/usbip/Kconfig | 17 ++- > drivers/usb/usbip/vhci.h | 36 ++++- > drivers/usb/usbip/vhci_hcd.c | 250 ++++++++++++++++++++++++++++----- > drivers/usb/usbip/vhci_rx.c | 10 +- > drivers/usb/usbip/vhci_sysfs.c | 46 +++--- > drivers/usb/usbip/vhci_tx.c | 6 +- > 6 files changed, 291 insertions(+), 74 deletions(-) > > diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig > index eeefa29..42d8979 100644 > --- a/drivers/usb/usbip/Kconfig > +++ b/drivers/usb/usbip/Kconfig > @@ -35,8 +35,8 @@ config USBIP_VHCI_HC_PORTS > host controller driver, this defines number of ports per > USB/IP virtual host controller. > > -config USBIP_VHCI_NR_HCS > - int "Number of USB/IP virtual host controllers" > +config USBIP_VHCI_MAX_HCS > + int "Maximum number of USB/IP virtual host controllers" > range 1 128 > default 1 > depends on USBIP_VHCI_HCD > @@ -44,7 +44,18 @@ config USBIP_VHCI_NR_HCS > To increase number of ports available for USB/IP virtual > host controller driver, this defines number of USB/IP > virtual host controllers as if adding physical host > - controllers. > + controllers. This defines the maximum number. > + > +config USBIP_VHCI_INIT_HCS > + int "Initial number of USB/IP virtual host controllers" > + range 1 USBIP_VHCI_MAX_HCS > + default 1 > + depends on USBIP_VHCI_MAX_HCS > + ---help--- > + To increase number of ports available for USB/IP virtual > + host controller driver, this defines number of USB/IP > + virtual host controllers as if adding physical host > + controllers. This defines the number at initializing. > > config USBIP_HOST > tristate "Host driver" > diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h > index 88b71c4..ba893a7 100644 > --- a/drivers/usb/usbip/vhci.h > +++ b/drivers/usb/usbip/vhci.h > @@ -51,6 +51,9 @@ struct vhci_device { > > /* vhci_tx thread sleeps for this queue */ > wait_queue_head_t waitq_tx; > + > + /* denotes port is in-use */ > + atomic_t using_port; > }; > > /* urb->hcpriv, use container_of() */ > @@ -79,12 +82,21 @@ struct vhci_unlink { > #define VHCI_HC_PORTS 8 > #endif > > -#ifdef CONFIG_USBIP_VHCI_NR_HCS > -#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS > +#ifdef CONFIG_USBIP_VHCI_MAX_HCS > +#define VHCI_MAX_HCS CONFIG_USBIP_VHCI_MAX_HCS > +#else > +#define VHCI_MAX_HCS 1 > +#endif > + > +#ifdef CONFIG_USBIP_VHCI_INIT_HCS > +#define VHCI_INIT_HCS CONFIG_USBIP_VHCI_INIT_HCS > #else > -#define VHCI_NR_HCS 1 > +#define VHCI_INIT_HCS 1 > #endif > > +/* VHCI_FREE_HCS * VHCI_HC_PORTS: ports to keep free at unregister */ > +#define VHCI_FREE_HCS 2 > + > #define MAX_STATUS_NAME 16 > > /* for usb_bus.hcpriv */ > @@ -98,6 +110,8 @@ struct vhci_hcd { > > atomic_t seqnum; > > + unsigned int using_ports; > + > /* > * NOTE: > * wIndex shows the port number and begins from 1. > @@ -106,12 +120,18 @@ struct vhci_hcd { > struct vhci_device vdev[VHCI_HC_PORTS]; > }; > > +extern int vhci_max_controllers; > +extern int vhci_init_controllers; > extern int vhci_num_controllers; > extern struct platform_device **vhci_pdevs; > extern struct attribute_group vhci_attr_group; > > /* vhci_hcd.c */ > void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed); > +int vhci_get_device(__u32 pdev_nr, __u32 rhport, > + struct vhci_hcd **vhci, struct vhci_device **vdev); > +void vhci_put_device(struct vhci_device *vdev); > +void vhci_event_add(struct usbip_device *ud, unsigned long event); > > /* vhci_sysfs.c */ > int vhci_init_attr_group(void); > @@ -160,4 +180,14 @@ static inline struct vhci_hcd *vdev_to_vhci(struct vhci_device *vdev) > (void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); > } > > +static inline int pdev_id2nr(int id) > +{ > + return (id < 0) ? 0 : id; > +} > + > +static inline int pdev_nr2id(int nr) > +{ > + return (nr == 0) ? -1 : nr; > +} > + > #endif /* __USBIP_VHCI_H */ > diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c > index c4724fb..4a0f1ae 100644 > --- a/drivers/usb/usbip/vhci_hcd.c > +++ b/drivers/usb/usbip/vhci_hcd.c > @@ -57,10 +57,22 @@ static int vhci_get_frame_number(struct usb_hcd *hcd); > static const char driver_name[] = "vhci_hcd"; > static const char driver_desc[] = "USB/IP Virtual Host Controller"; > > -int vhci_num_controllers = VHCI_NR_HCS; > +int vhci_max_controllers = VHCI_MAX_HCS; > +int vhci_init_controllers = VHCI_INIT_HCS; > +int vhci_num_controllers; > > +static spinlock_t pdevs_lock; > struct platform_device **vhci_pdevs; > > +static spinlock_t using_ports_lock; > +static unsigned int vhci_using_ports; > + > +static int pdevs_init_completed; > +static atomic_t pdevs_init_count; > + > +static wait_queue_head_t pdevs_waitq; > +static int pdev_nr_started; > + > static const char * const bit_desc[] = { > "CONNECTION", /*0*/ > "ENABLE", /*1*/ > @@ -439,7 +451,7 @@ static struct vhci_device *get_vdev(struct usb_device *udev) > if (!udev) > return NULL; > > - for (pdev_nr = 0; pdev_nr < vhci_num_controllers; pdev_nr++) { > + for (pdev_nr = 0; pdev_nr < vhci_max_controllers; pdev_nr++) { > pdev = *(vhci_pdevs + pdev_nr); > if (pdev == NULL) > continue; > @@ -471,7 +483,7 @@ static void vhci_tx_urb(struct urb *urb) > > priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); > if (!priv) { > - usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); > + vhci_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); > return; > } > > @@ -727,7 +739,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) > if (!unlink) { > spin_unlock(&vdev->priv_lock); > spin_unlock_irqrestore(&vhci->lock, flags); > - usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); > + vhci_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); > return -ENOMEM; > } > > @@ -868,7 +880,6 @@ static void vhci_shutdown_connection(struct usbip_device *ud) > pr_info("disconnect device\n"); > } > > - > static void vhci_device_reset(struct usbip_device *ud) > { > struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); > @@ -889,15 +900,20 @@ static void vhci_device_reset(struct usbip_device *ud) > ud->status = VDEV_ST_NULL; > > spin_unlock_irqrestore(&ud->lock, flags); > + > + vhci_put_device(vdev); > } > > static void vhci_device_unusable(struct usbip_device *ud) > { > + struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); > unsigned long flags; > > spin_lock_irqsave(&ud->lock, flags); > ud->status = VDEV_ST_ERROR; > spin_unlock_irqrestore(&ud->lock, flags); > + > + vhci_put_device(vdev); > } > > static void vhci_device_init(struct vhci_device *vdev) > @@ -907,6 +923,7 @@ static void vhci_device_init(struct vhci_device *vdev) > vdev->ud.side = USBIP_VHCI; > vdev->ud.status = VDEV_ST_NULL; > spin_lock_init(&vdev->ud.lock); > + atomic_set(&vdev->using_port, 0); > > INIT_LIST_HEAD(&vdev->priv_rx); > INIT_LIST_HEAD(&vdev->priv_tx); > @@ -923,7 +940,7 @@ static void vhci_device_init(struct vhci_device *vdev) > usbip_start_eh(&vdev->ud); > } > > -static int hcd_name_to_id(const char *name) > +static int hcd_name_to_pdev_nr(const char *name) > { > char *c; > long val; > @@ -943,7 +960,7 @@ static int hcd_name_to_id(const char *name) > static int vhci_start(struct usb_hcd *hcd) > { > struct vhci_hcd *vhci = hcd_to_vhci(hcd); > - int id, rhport; > + int pdev_nr, rhport; > int err = 0; > > usbip_dbg_vhci_hc("enter vhci_start\n"); > @@ -959,18 +976,19 @@ static int vhci_start(struct usb_hcd *hcd) > > atomic_set(&vhci->seqnum, 0); > spin_lock_init(&vhci->lock); > + vhci->using_ports = 0; > > hcd->power_budget = 0; /* no limit */ > hcd->uses_new_polling = 1; > > - id = hcd_name_to_id(hcd_name(hcd)); > - if (id < 0) { > + pdev_nr = hcd_name_to_pdev_nr(hcd_name(hcd)); > + if (pdev_nr < 0) { > pr_err("invalid vhci name %s\n", hcd_name(hcd)); > return -EINVAL; > } > > /* vhci_hcd is now ready to be controlled through sysfs */ > - if (id == 0) { > + if (pdev_nr == 0) { > err = vhci_init_attr_group(); > if (err) { > pr_err("init attr group\n"); > @@ -985,19 +1003,26 @@ static int vhci_start(struct usb_hcd *hcd) > pr_info("created sysfs %s\n", hcd_name(hcd)); > } > > + if (atomic_dec_and_test(&pdevs_init_count)) > + pdevs_init_completed = 1; > + if (pdevs_init_completed) > + atomic_set(&pdevs_init_count, -1); > + pdev_nr_started = pdev_nr; > + wake_up(&pdevs_waitq); > + > return 0; > } > > static void vhci_stop(struct usb_hcd *hcd) > { > struct vhci_hcd *vhci = hcd_to_vhci(hcd); > - int id, rhport; > + int pdev_nr, rhport; > > usbip_dbg_vhci_hc("stop VHCI controller\n"); > > /* 1. remove the userland interface of vhci_hcd */ > - id = hcd_name_to_id(hcd_name(hcd)); > - if (id == 0) { > + pdev_nr = hcd_name_to_pdev_nr(hcd_name(hcd)); > + if (pdev_nr == 0) { > sysfs_remove_group(&hcd_dev(hcd)->kobj, &vhci_attr_group); > vhci_finish_attr_group(); > } > @@ -1006,7 +1031,7 @@ static void vhci_stop(struct usb_hcd *hcd) > for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { > struct vhci_device *vdev = &vhci->vdev[rhport]; > > - usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED); > + vhci_event_add(&vdev->ud, VDEV_EVENT_REMOVED); > usbip_stop_eh(&vdev->ud); > } > } > @@ -1201,49 +1226,198 @@ static struct platform_driver vhci_driver = { > }, > }; > > -static int add_platform_device(int id) > +static int __add_platform_device(int pdev_nr) > { > struct platform_device *pdev; > - int dev_nr; > - > - if (id == 0) > - dev_nr = -1; > - else > - dev_nr = id; > + int id = pdev_nr2id(pdev_nr); > > - pdev = platform_device_register_simple(driver_name, dev_nr, NULL, 0); > - if (IS_ERR(pdev)) > + pdev = platform_device_register_simple(driver_name, id, NULL, 0); > + if (IS_ERR(pdev)) { > + pr_err("failed to register pdev\n"); > return PTR_ERR(pdev); > + } > > - *(vhci_pdevs + id) = pdev; > + *(vhci_pdevs + pdev_nr) = pdev; > + ++vhci_num_controllers; > return 0; > } > > +static void __del_platform_device(int pdev_nr) > +{ > + struct platform_device *pdev = *(vhci_pdevs + pdev_nr); > + > + if (!pdev) > + return; > + > + usbip_dbg_vhci_rh("deleting pdev %d\n", pdev_nr); > + *(vhci_pdevs + pdev_nr) = NULL; > + vhci_num_controllers--; > + platform_device_unregister(pdev); > +} > + > +static void __del_platform_devices(void) > +{ > + int i; > + > + for (i = 0; i < vhci_max_controllers; i++) > + __del_platform_device(i); > + sysfs_remove_link(&platform_bus.kobj, driver_name); > +} > + > static void del_platform_devices(void) > { > + spin_lock(&pdevs_lock); > + __del_platform_devices(); > + spin_unlock(&pdevs_lock); > +} > + > +static void __vhci_get_device(struct platform_device *pdev, __u32 rhport, > + struct vhci_hcd **vhci, struct vhci_device **vdev) > +{ > + struct usb_hcd *hcd; > + unsigned long flags; > + > + spin_lock_irqsave(&using_ports_lock, flags); > + hcd = platform_get_drvdata(pdev); > + *vhci = hcd_to_vhci(hcd); > + *vdev = &((*vhci)->vdev[rhport]); > + vhci_using_ports++; > + ((*vhci)->using_ports)++; > + atomic_set(&((*vdev)->using_port), 1); > + spin_unlock_irqrestore(&using_ports_lock, flags); > +} > + > +int vhci_get_device(__u32 pdev_nr, __u32 rhport, > + struct vhci_hcd **vhci, struct vhci_device **vdev) > +{ > struct platform_device *pdev; > - int i; > + unsigned long flags; > + int ret; > + > + if (wait_event_interruptible(pdevs_waitq, pdevs_init_completed)) > + return -ERESTARTSYS; > > - for (i = 0; i < vhci_num_controllers; i++) { > - pdev = *(vhci_pdevs + i); > - if (pdev != NULL) > - platform_device_unregister(pdev); > - *(vhci_pdevs + i) = NULL; > + spin_lock_irqsave(&pdevs_lock, flags); > + > + pdev = *(vhci_pdevs + pdev_nr); > + if (pdev) { > + __vhci_get_device(pdev, rhport, vhci, vdev); > + spin_unlock_irqrestore(&pdevs_lock, flags); > + return 0; > } > - sysfs_remove_link(&platform_bus.kobj, driver_name); > + > + pdev_nr_started = -1; > + > + ret = __add_platform_device(pdev_nr); > + if (ret) { > + spin_unlock_irqrestore(&pdevs_lock, flags); > + return ret; > + } > + > + usbip_dbg_vhci_rh("waiting pdev started %d\n", pdev_nr); > + if (wait_event_interruptible(pdevs_waitq, > + pdev_nr_started == pdev_nr)) { > + spin_unlock_irqrestore(&pdevs_lock, flags); > + return -ERESTARTSYS; > + } > + usbip_dbg_vhci_rh("end of waiting pdev started %d\n", pdev_nr); > + > + pdev = *(vhci_pdevs + pdev_nr); > + __vhci_get_device(pdev, rhport, vhci, vdev); > + > + spin_unlock_irqrestore(&pdevs_lock, flags); > + > + return 0; > +} > + > +void vhci_put_device(struct vhci_device *vdev) > +{ > + struct vhci_hcd *vhci; > + unsigned long flags; > + > + if (!atomic_dec_and_test(&vdev->using_port)) > + return; > + > + spin_lock_irqsave(&using_ports_lock, flags); > + vhci = vdev_to_vhci(vdev); > + (vhci->using_ports)--; > + vhci_using_ports--; > + spin_unlock_irqrestore(&using_ports_lock, flags); > +} > + > +static int __try_del_platform_device(void) > +{ > + int pdev_nr; > + struct platform_device *pdev; > + struct vhci_hcd *vhci; > + > + for (pdev_nr = (vhci_max_controllers - 1); pdev_nr > 0; pdev_nr--) { > + pdev = *(vhci_pdevs + pdev_nr); > + if (!pdev) > + continue; > + vhci = hcd_to_vhci(platform_get_drvdata(pdev)); > + if (!vhci->using_ports) { > + __del_platform_device(pdev_nr); > + return 1; > + } > + } > + return 0; > +} > + > +static void try_del_platform_device(void) > +{ > + unsigned long flags; > + unsigned int free_ports; > + > + if (!spin_trylock_irqsave(&pdevs_lock, flags)) { > + usbip_dbg_vhci_rh("recursive call or exitting\n"); > + return; > + } > + usbip_dbg_vhci_rh("trying del pdev\n"); > + > + if (vhci_num_controllers > vhci_init_controllers) { > + free_ports = (vhci_num_controllers * VHCI_HC_PORTS) > + - vhci_using_ports; > + usbip_dbg_vhci_rh("%d free ports in %d hcs\n", > + free_ports, vhci_num_controllers); > + /* free_pots will be decremented with this event */ > + if (free_ports >= (VHCI_HC_PORTS * VHCI_FREE_HCS)) > + __try_del_platform_device(); > + } > + > + spin_unlock_irqrestore(&pdevs_lock, flags); > +} > + > +void vhci_event_add(struct usbip_device *ud, unsigned long event) > +{ > + usbip_dbg_vhci_rh("adding event %lu\n", event); > + > + if (event != VDEV_EVENT_REMOVED && !usbip_in_eh(current)) > + try_del_platform_device(); > + > + usbip_event_add(ud, event); > } > > static int __init vhci_hcd_init(void) > { > - int i, ret; > + int pdev_nr, ret; > > if (usb_disabled()) > return -ENODEV; > > - if (vhci_num_controllers < 1) > - vhci_num_controllers = 1; > + if (vhci_max_controllers < 1) > + vhci_max_controllers = 1; > + if (vhci_init_controllers < 1) > + vhci_init_controllers = 1; > + if (vhci_init_controllers > vhci_max_controllers) > + vhci_init_controllers = vhci_max_controllers; > > - vhci_pdevs = kcalloc(vhci_num_controllers, sizeof(void *), GFP_KERNEL); > + spin_lock_init(&pdevs_lock); > + spin_lock_init(&using_ports_lock); > + init_waitqueue_head(&pdevs_waitq); > + atomic_set(&pdevs_init_count, vhci_init_controllers); > + > + vhci_pdevs = kcalloc(vhci_max_controllers, sizeof(void *), GFP_KERNEL); > if (vhci_pdevs == NULL) > return -ENOMEM; > > @@ -1251,8 +1425,8 @@ static int __init vhci_hcd_init(void) > if (ret) > goto err_driver_register; > > - for (i = 0; i < vhci_num_controllers; i++) { > - ret = add_platform_device(i); > + for (pdev_nr = 0; pdev_nr < vhci_init_controllers; pdev_nr++) { > + ret = __add_platform_device(pdev_nr); > if (ret) > goto err_platform_device_register; > } > @@ -1261,7 +1435,7 @@ static int __init vhci_hcd_init(void) > return ret; > > err_platform_device_register: > - del_platform_devices(); > + __del_platform_devices(); > platform_driver_unregister(&vhci_driver); > err_driver_register: > kfree(vhci_pdevs); > diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c > index fc2d319..bea43f7 100644 > --- a/drivers/usb/usbip/vhci_rx.c > +++ b/drivers/usb/usbip/vhci_rx.c > @@ -83,7 +83,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, > pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); > pr_info("max seqnum %d\n", > atomic_read(&vhci->seqnum)); > - usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); > + vhci_event_add(ud, VDEV_EVENT_ERROR_TCP); > return; > } > > @@ -222,18 +222,18 @@ static void vhci_rx_pdu(struct usbip_device *ud) > } else if (ret != -ERESTARTSYS) > pr_info("xmit failed %d\n", ret); > > - usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); > + vhci_event_add(ud, VDEV_EVENT_ERROR_TCP); > return; > } > if (ret == 0) { > pr_info("connection closed"); > - usbip_event_add(ud, VDEV_EVENT_DOWN); > + vhci_event_add(ud, VDEV_EVENT_DOWN); > return; > } > if (ret != sizeof(pdu)) { > pr_err("received pdu size is %d, should be %d\n", ret, > (unsigned int)sizeof(pdu)); > - usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); > + vhci_event_add(ud, VDEV_EVENT_ERROR_TCP); > return; > } > > @@ -253,7 +253,7 @@ static void vhci_rx_pdu(struct usbip_device *ud) > /* NOT REACHED */ > pr_err("unknown pdu %u\n", pdu.base.command); > usbip_dump_header(&pdu); > - usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); > + vhci_event_add(ud, VDEV_EVENT_ERROR_TCP); > break; > } > } > diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c > index 5d4be4b..589bcc8 100644 > --- a/drivers/usb/usbip/vhci_sysfs.c > +++ b/drivers/usb/usbip/vhci_sysfs.c > @@ -30,15 +30,15 @@ > /* TODO: refine locking ?*/ > > /* Sysfs entry to show port status */ > -static ssize_t status_show_vhci(int pdev_nr, char *out) > +static ssize_t status_show_vhci(int pdev_nr, struct platform_device *pdev, > + char *out) > { > - struct platform_device *pdev = *(vhci_pdevs + pdev_nr); > struct vhci_hcd *vhci; > char *s = out; > int i = 0; > unsigned long flags; > > - if (!pdev || !out) { > + if (!out) { > usbip_dbg_vhci_sysfs("show status error\n"); > return 0; > } > @@ -86,7 +86,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out) > return out - s; > } > > -static ssize_t status_show_not_ready(int pdev_nr, char *out) > +static ssize_t status_show_idle(int pdev_nr, char *out) > { > char *s = out; > int i = 0; > @@ -94,7 +94,7 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out) > for (i = 0; i < VHCI_HC_PORTS; i++) { > out += sprintf(out, "%04u %03u ", > (pdev_nr * VHCI_HC_PORTS) + i, > - VDEV_ST_NOTASSIGNED); > + VDEV_ST_NULL); > out += sprintf(out, "000 00000000 0000000000000000 0-0"); > out += sprintf(out, "\n"); > } > @@ -123,15 +123,20 @@ static ssize_t status_show(struct device *dev, > { > char *s = out; > int pdev_nr; > + struct platform_device *pdev = NULL; > > out += sprintf(out, > "port sta spd dev socket local_busid\n"); > > pdev_nr = status_name_to_id(attr->attr.name); > if (pdev_nr < 0) > - out += status_show_not_ready(pdev_nr, out); > + return 0; > + > + pdev = *(vhci_pdevs + pdev_nr); > + if (pdev) > + out += status_show_vhci(pdev_nr, pdev, out); > else > - out += status_show_vhci(pdev_nr, out); > + out += status_show_idle(pdev_nr, out); > > return out - s; > } > @@ -141,7 +146,7 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr, > { > char *s = out; > > - out += sprintf(out, "%d\n", VHCI_HC_PORTS * vhci_num_controllers); > + out += sprintf(out, "%d\n", VHCI_HC_PORTS * vhci_max_controllers); > return out - s; > } > static DEVICE_ATTR_RO(nports); > @@ -172,14 +177,14 @@ static int vhci_port_disconnect(struct vhci_hcd *vhci, __u32 rhport) > spin_unlock(&vdev->ud.lock); > spin_unlock_irqrestore(&vhci->lock, flags); > > - usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); > + vhci_event_add(&vdev->ud, VDEV_EVENT_DOWN); > > return 0; > } > > static int valid_port(__u32 pdev_nr, __u32 rhport) > { > - if (pdev_nr >= vhci_num_controllers) { > + if (pdev_nr >= vhci_max_controllers) { > pr_err("pdev %u\n", pdev_nr); > return 0; > } > @@ -261,7 +266,6 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, > struct socket *socket; > 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_device *vdev; > int err; > @@ -287,18 +291,15 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, > if (!valid_args(pdev_nr, rhport, speed)) > return -EINVAL; > > - hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr)); > - if (hcd == NULL) { > - dev_err(dev, "port %d is not ready\n", port); > + if (vhci_get_device(pdev_nr, rhport, &vhci, &vdev)) > return -EAGAIN; > - } > - vhci = hcd_to_vhci(hcd); > - vdev = &vhci->vdev[rhport]; > > /* Extract socket from fd. */ > socket = sockfd_lookup(sockfd, &err); > - if (!socket) > + if (!socket) { > + vhci_put_device(vdev); > return -EINVAL; > + } > > /* now need lock until setting vdev status as used */ > > @@ -312,6 +313,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, > spin_unlock_irqrestore(&vhci->lock, flags); > > sockfd_put(socket); > + vhci_put_device(vdev); > > dev_err(dev, "port %d already used\n", rhport); > /* > @@ -372,12 +374,12 @@ static int init_status_attrs(void) > { > int id; > > - status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr), > + status_attrs = kcalloc(vhci_max_controllers, sizeof(struct status_attr), > GFP_KERNEL); > if (status_attrs == NULL) > return -ENOMEM; > > - for (id = 0; id < vhci_num_controllers; id++) > + for (id = 0; id < vhci_max_controllers; id++) > set_status_attr(id); > > return 0; > @@ -397,7 +399,7 @@ int vhci_init_attr_group(void) > struct attribute **attrs; > int ret, i; > > - attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *), > + attrs = kcalloc((vhci_max_controllers + 5), sizeof(struct attribute *), > GFP_KERNEL); > if (attrs == NULL) > return -ENOMEM; > @@ -411,7 +413,7 @@ int vhci_init_attr_group(void) > *(attrs + 1) = &dev_attr_detach.attr; > *(attrs + 2) = &dev_attr_attach.attr; > *(attrs + 3) = &dev_attr_usbip_debug.attr; > - for (i = 0; i < vhci_num_controllers; i++) > + for (i = 0; i < vhci_max_controllers; i++) > *(attrs + i + 4) = &((status_attrs + i)->attr.attr); > vhci_attr_group.attrs = attrs; > return 0; > diff --git a/drivers/usb/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c > index 3e7878f..94f9c0a 100644 > --- a/drivers/usb/usbip/vhci_tx.c > +++ b/drivers/usb/usbip/vhci_tx.c > @@ -106,7 +106,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) > > iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len); > if (!iso_buffer) { > - usbip_event_add(&vdev->ud, > + vhci_event_add(&vdev->ud, > SDEV_EVENT_ERROR_MALLOC); > return -1; > } > @@ -121,7 +121,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) > pr_err("sendmsg failed!, ret=%d for %zd\n", ret, > txsize); > kfree(iso_buffer); > - usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); > + vhci_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); > return -1; > } > > @@ -190,7 +190,7 @@ static int vhci_send_cmd_unlink(struct vhci_device *vdev) > if (ret != txsize) { > pr_err("sendmsg failed!, ret=%d for %zd\n", ret, > txsize); > - usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); > + vhci_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); > return -1; > } > > -- 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