Re: usbip port number limits
Hi Shuah, On Tue, Nov 28, 2017 at 05:09:18PM -0700, Shuah Khan wrote: > On 11/28/2017 11:32 AM, Shuah Khan wrote: > > On 11/26/2017 06:33 PM, Yuyang Du wrote: > >> Hi Juan, > >> > >> On Fri, Nov 24, 2017 at 12:42:22PM +0100, Juan Zea wrote: > >>>The patch doesn't apply cleanly with the patch command, but given it > >>> is that simple I've changed it myself (I'm telling you just in case we're > >>> missing something). > >>> > >>>The fingerprint reader, usb stick and wacom tablet work :) > >> > >> Good to hear that. > >> > >>> I've also checked the same patch can be applied to kernel master and it > >>> works. So... is that the solution? > >> > >> I'll post a patch later, but before that, Hi, Shuah, does it work > >> for you, on your test notebook? > >> > > > > I am going to test this today and if it is fixes the problem on > > my system. > > > > Hi Yuyang, > > I tried the patch on 4.15-rc1 and looks good to me. Please send a > proper patch to fix this. It need to go into 4.14 stable for sure. Thank you so much. > There are no more 4.13 stable releases at this time. So let's get > this into 4.15 first and them go from there. Sounds good. > I am working on a patch for the other issue Juan reported that prevents > finding a free-port when the first port is usb3. You don't have to worry > about that. Great you take care of it. Hi Juan, Maybe you close the bug: https://bugzilla.kernel.org/show_bug.cgi?id=197867 Thanks, Yuyang -- 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
[PATCH] usbip: Fix USB device hang due to wrong enabling of scatter-gather
The previous USB3 SuperSpeed enabling patches mistakenly enabled URB scatter-gather chaining, which is actually not supported by the VHCI HCD. This patch fixes that. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197867 Fixes: 03cd00d538a6feb ("usbip: vhci-hcd: Set the vhci structure up to work") Reported-by: Juan Zea <juan@qindel.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 713e941..6b3278c 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1098,7 +1098,6 @@ static int hcd_name_to_id(const char *name) static int vhci_setup(struct usb_hcd *hcd) { struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller)); - hcd->self.sg_tablesize = ~0; if (usb_hcd_is_primary_hcd(hcd)) { vhci->vhci_hcd_hs = hcd_to_vhci_hcd(hcd); vhci->vhci_hcd_hs->vhci = vhci; -- 2.7.4 -- 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
Re: usbip port number limits
Hi Juan, On Fri, Nov 24, 2017 at 12:42:22PM +0100, Juan Zea wrote: >The patch doesn't apply cleanly with the patch command, but given it is > that simple I've changed it myself (I'm telling you just in case we're > missing something). > >The fingerprint reader, usb stick and wacom tablet work :) Good to hear that. > I've also checked the same patch can be applied to kernel master and it > works. So... is that the solution? I'll post a patch later, but before that, Hi, Shuah, does it work for you, on your test notebook? Thanks, Yuyang -- 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
Re: usbip port number limits
On Wed, Nov 22, 2017 at 09:38:27AM +0100, Juan Zea wrote: > I don't come up with any more detail... anything I'm missing? Hi Juan, Thank you so much for your patience. Really appreciate it. I came up with the following patch, with which at my side the BUG doesn't happen again with both a (low speed ) mouse and a (high speed) stick attached at the client over localhost server. Would you be able to test it at your side? I applied the patch right on top of the commit b891245bff7958 ("usbip: vhci-hcd: Clean up the code by adding a new macro"). Anyway, the patch is pretty trivial. Thanks, Yuyang -- diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 64c3860..732edaf 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1112,7 +1112,6 @@ static int hcd_name_to_id(const char *name) static int vhci_setup(struct usb_hcd *hcd) { struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller)); - hcd->self.sg_tablesize = ~0; if (usb_hcd_is_primary_hcd(hcd)) { vhci->vhci_hcd_hs = hcd_to_vhci_hcd(hcd); vhci->vhci_hcd_hs->vhci = vhci; -- 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
Re: usbip port number limits
On Tue, Nov 21, 2017 at 07:33:41AM -0700, Shuah Khan wrote: > I have been debugging on 4.12 and this bad commit. Low speed devices can be > attached, but you see the following and then shutdown hangs. Oh, just tested a high speed USB stick, I got the message. I'm working on it. -- 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
Re: usbip port number limits
Hi Juan, On Tue, Nov 21, 2017 at 12:24:01PM +0100, Juan Zea wrote: > Please excuse me... I have reported two different problems in this post, > and I think things are mixing up a bit. My bad. I've found two different > problems: > > 1.- When compiling vhci driver with multiple hubs (in latest kernel), usbip > tool doesn't seem able to "jump" to the second controller. As far as I > understand, it seems to be a problem with high speed devices trying to get > connected to super speed ports. I made a patch for avoiding this situation > which is almost the same as the one you just sent. Both patches work. I can > compile with several hubs of one port, and connect two devices via usbip and > the second gets connected to the second controller (skipping the super speed > port of first controller). > > 2.- The problem is some of these devices don't work, whatsoever controller or > hub compiling configuration I do. A fingerprint reader and also recently > discovered flash usb sticks don't work either. You can connect them with > usbip tool, and they list with lsusb with no problem at all. But when you try > to use them, you get this "kernel BUG at drivers/usb/usbip/vhci_hcd.c:669!" > (by the way, the line number has changed in the latest pull from master I've > just tested, but it's the same line of code). This second problem is the one > I bisected in my last message. And I got to the commit > 03cd00d538a6feb0492cd153edf256ef7d7bd95e, in which both devices stop working. It'd be good if you can give greater detail of the exact (as much info as possible) setting of the fingerprint reader case. > The patch you sent fixes 1 but not 2. And yes, I'm using non-super-speed > devices for testing. This was what I understood. Just want to make sure we are on the same page. > I hope this helped, and sorry for the mess, Yes, it helped. My sincere apologies for the mess I created! Thanks, Yuyang -- 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
Re: usbip port number limits
Hi Shuah, On Tue, Nov 21, 2017 at 07:33:41AM -0700, Shuah Khan wrote: > > Thanks for finding the problem. usb2 devices don't work at all with the > offending commit: 03cd00d538a6feb0492cd153edf256ef7d7bd95e > > I have been debugging on 4.12 and this bad commit. Low speed devices can be > attached, but you see the following and then shutdown hangs. It sounds horrible. I am really trying to understand the situation. I tested and am testing mouses/keyboards, all of them work. Am I missing something? BTW, now I'm testing over localhost. > I don't believe this commit 03cd00d538a6feb0492cd153edf256ef7d7bd95e tested > well on usb2 devices. and this commit is suspect. It is unfortunate > that it wasn't caught during the patch testing, because it is so easy to > run into this. I used one usb2 device and tried to attach over localhost > and with this patch happens every single time. If it is this commit, chances are it should be not hard to fix, as the patches up to this point simply reorganize data structures. > I am looking into reverting this commit as well as the rest of the usb3 work > that is based on this bad commit as this commit introduced serious regression > for usb2 devices. > > I have reverted the patches on 4.15 base and testing it this week. I will have > to do the same for 4.13 as well. > > usb3 work and this rework patch can be tested well and I can take this > into 4.16 or so once it is is tested on all devices including the finger > print reader - I have a laptop to test this use-case. Sounds good. > My apologies for not catching this earlier. My apologies too. > The bug dmesg as follows: > > [ 2223.046019] kernel BUG at drivers/usb/usbip/vhci_hcd.c:704! Make sure we are on the same page. Is the BUG this one: 683 BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); Thanks, Yuyang -- 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
Re: usbip port number limits
On Wed, Nov 15, 2017 at 07:58:24AM -0700, Shuah Khan wrote: > Hi Juan, > > On 11/15/2017 07:43 AM, Juan Zea wrote: > > > >>> Also, will you be able to revert the usb3 commit > >>> 1c9de5bf428612458427943b724bea51abde520a > >>> > >>> and see if any of the problems go away. > >>> > >>> thanks, > >>> -- Shuah > >>> > > > >> I'm on it and will send results later. > > > >> Thanks, > >> Juan > > > > Ok, I'm back. The revert was quite complex, with several conflicts I was > > not able to resolve. So I started testing full checkouts around that series > > of changes by Yuyang. > > I was hoping it will be easier. I was apprehensive it could be a com[ex > revert. :( > > > That led me to bisecting the problem with the fingerprint reader, and the > > culprit is here: > > > > 03cd00d538a6feb0492cd153edf256ef7d7bd95e is the first bad commit > > commit 03cd00d538a6feb0492cd153edf256ef7d7bd95e > > Author: Yuyang Du <yuyang...@intel.com> > > Date: Thu Jun 8 13:04:09 2017 +0800 > > > > usbip: vhci-hcd: Set the vhci structure up to work > > > > 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> > > Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> > > > > :04 04 b7b5c6b16db801c74354bb0d0a247855f64b0829 > > 72524e78d281ebc8d36fa32cb93ed0278e99f880 M drivers > > > > The commit before, fingerprint reader works. Also, multicontroller works > > (no usb3 ports). > > In this bad commit, I get the errors I sent in the previous message. > > > > Thanks for reporting and debugging the problem to isolate the commit. I was > suspecting one of these commit based on the messages you are seeing. > > I will see if I can fix this without doing a huge reverts. > Hi, Sorry for the latency. It seems now the bug is: Nov 14 14:35:29 kernel-tester kernel: [ 229.636543] kernel BUG at drivers/usb/usbip/vhci_hcd.c:683! which is a hard one (you mentioned the lastest kernel is used). Since you didn't post patch, lets first make sure we are on the same page. Could you please try the following patch and see whether the bug still exists? Also, I'm assuming you are using a non-super-speed device. Thanks, Yuyang - diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 9bd2cd7..82367f9 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -328,9 +328,18 @@ int usbip_vhci_refresh_device_list(void) int usbip_vhci_get_free_port(uint32_t speed) { for (int i = 0; i < vhci_driver->nports; i++) { - if (speed == USB_SPEED_SUPER && - vhci_driver->idev[i].hub != HUB_SPEED_SUPER) - continue; + /* +* Make sure hub speed (either SUPER or !SUPER) matches +* device speed +*/ + if (speed == USB_SPEED_SUPER) { + if (vhci_driver->idev[i].hub != HUB_SPEED_SUPER) + continue; + } + else { + if (vhci_driver->idev[i].hub != HUB_SPEED_HIGH) + continue; + } if (vhci_driver->idev[i].status == VDEV_ST_NULL) return vhci_driver->idev[i].port; -- 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
Re: usbip port number limits
On Tue, Nov 14, 2017 at 04:17:33PM -0700, Shuah Khan wrote: > On 11/14/2017 01:36 PM, Shuah Khan wrote: > Hi Yuyang Du, > > I am looking at the USB3 support patch and not finding where > USB_SPEED_LOW is handled. Any reason why dropping support for > that? > Hi Shuah, It's been a while since this patch series. Let me take a look at it as well as the "port number limit" issue and get back to you as soon as possible. Thanks, Yuyang -- 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
[PATCH] usbip: Fix uninitialized variable bug in vhci
The patch 03cd00d538a6: "usbip: vhci-hcd: Set the vhci structure up to work" introduced a bug which uses a vairable without initialization in error handling code. Fix it. Reported-by: Dan Carpenter <dan.carpen...@oracle.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 64c3860..2c4b2fd 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1301,7 +1301,7 @@ static struct hc_driver vhci_hc_driver = { static int vhci_hcd_probe(struct platform_device *pdev) { - struct vhci *vhci; + struct vhci *vhci = *((void **)dev_get_platdata(>dev)); struct usb_hcd *hcd_hs; struct usb_hcd *hcd_ss; int ret; -- 2.7.4 -- 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
Re: [bug report] usbip: vhci-hcd: Set the vhci structure up to work
Sorry. CC related people. On Mon, Jun 26, 2017 at 12:04:54PM +0800, Yuyang Du wrote: > Hi Dan, > > Thanks for the report. A patch to fix the bug follows: > > diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c > index 64c3860..2c4b2fd 100644 > --- a/drivers/usb/usbip/vhci_hcd.c > +++ b/drivers/usb/usbip/vhci_hcd.c > @@ -1301,7 +1301,7 @@ static struct hc_driver vhci_hc_driver = { > > static int vhci_hcd_probe(struct platform_device *pdev) > { > - struct vhci *vhci; > + struct vhci *vhci = *((void > **)dev_get_platdata(>dev)); > struct usb_hcd *hcd_hs; > struct usb_hcd *hcd_ss; > int ret; > > Thanks, > Yuyang > > On Fri, Jun 23, 2017 at 01:46:01PM +0300, Dan Carpenter wrote: > > Hello Yuyang Du, > > > > The patch 03cd00d538a6: "usbip: vhci-hcd: Set the vhci structure up > > to work" from Jun 8, 2017, leads to the following static checker > > warning: > > > > drivers/usb/usbip/vhci_hcd.c:1355 vhci_hcd_probe() > > error: potentially dereferencing uninitialized 'vhci'. > > > > drivers/usb/usbip/vhci_hcd.c > > 1340 ret = usb_add_hcd(hcd_ss, 0, 0); > > 1341 if (ret) { > > 1342 pr_err("usb_add_hcd ss failed %d\n", ret); > > 1343 goto put_usb3_hcd; > > 1344 } > > 1345 > > 1346 usbip_dbg_vhci_hc("bye\n"); > > 1347 return 0; > > 1348 > > 1349 put_usb3_hcd: > > 1350 usb_put_hcd(hcd_ss); > > 1351 remove_usb2_hcd: > > 1352 usb_remove_hcd(hcd_hs); > > 1353 put_usb2_hcd: > > 1354 usb_put_hcd(hcd_hs); > > 1355 vhci->vhci_hcd_hs = NULL; > > ^ > > 1356 vhci->vhci_hcd_ss = NULL; > > ^ > > vhci is never initialized. > > > > 1357 return ret; > > 1358 } > -- > 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 -- 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
Re: [bug report] usbip: vhci-hcd: Set the vhci structure up to work
Hi Dan, Thanks for the report. A patch to fix the bug follows: diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 64c3860..2c4b2fd 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1301,7 +1301,7 @@ static struct hc_driver vhci_hc_driver = { static int vhci_hcd_probe(struct platform_device *pdev) { - struct vhci *vhci; + struct vhci *vhci = *((void **)dev_get_platdata(>dev)); struct usb_hcd *hcd_hs; struct usb_hcd *hcd_ss; int ret; Thanks, Yuyang On Fri, Jun 23, 2017 at 01:46:01PM +0300, Dan Carpenter wrote: > Hello Yuyang Du, > > The patch 03cd00d538a6: "usbip: vhci-hcd: Set the vhci structure up > to work" from Jun 8, 2017, leads to the following static checker > warning: > > drivers/usb/usbip/vhci_hcd.c:1355 vhci_hcd_probe() > error: potentially dereferencing uninitialized 'vhci'. > > drivers/usb/usbip/vhci_hcd.c > 1340 ret = usb_add_hcd(hcd_ss, 0, 0); > 1341 if (ret) { > 1342 pr_err("usb_add_hcd ss failed %d\n", ret); > 1343 goto put_usb3_hcd; > 1344 } > 1345 > 1346 usbip_dbg_vhci_hc("bye\n"); > 1347 return 0; > 1348 > 1349 put_usb3_hcd: > 1350 usb_put_hcd(hcd_ss); > 1351 remove_usb2_hcd: > 1352 usb_remove_hcd(hcd_hs); > 1353 put_usb2_hcd: > 1354 usb_put_hcd(hcd_hs); > 1355 vhci->vhci_hcd_hs = NULL; > ^ > 1356 vhci->vhci_hcd_ss = NULL; > ^ > vhci is never initialized. > > 1357 return ret; > 1358 } -- 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
Re: [PATCH v5 1/4] usb: usbip tool: Check the return of get_nports()
On Tue, Jun 06, 2017 at 09:36:50AM -0600, Shuah Khan wrote: > On 05/22/2017 04:20 AM, Yuyang Du wrote: > > From: Yuyang Du <yuyang...@intel.com> > > > > If we get nonpositive number of ports, there is no sense to > > continue, then fail gracefully. > > > > In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: > > modifications to vhci driver") introduced configurable numbers of > > controllers and ports, but we have a static port number maximum, > > MAXNPORT. If exceeded, the idev array will be overflown. We fix > > it by validating the nports to make sure the port number max is > > not exceeded. > > > > Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> > > Signed-off-by: Yuyang Du <yuyang...@intel.com> > > Acked-by: Shuah Khan <shua...@osg.samsung.com> > > Greg, > > Could you please pick this up. > > thanks, > -- Shuah Thanks a lot, Shuah. Yuyang -- 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
[PATCH v3 7/9] usbip: Add USB_SPEED_SUPER as valid arg
From: Yuyang Du <yuyang...@intel.com> With this patch, USB_SPEED_SUPER is a valid speed when attaching a USB3 SuperSpeed device. Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index cac2319..3ad68ff 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -277,6 +277,7 @@ static int valid_args(__u32 pdev_nr, __u32 rhport, enum usb_device_speed speed) case USB_SPEED_FULL: case USB_SPEED_HIGH: case USB_SPEED_WIRELESS: + case USB_SPEED_SUPER: break; default: pr_err("Failed attach request for unsupported USB speed: %s\n", -- 2.7.4 -- 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
[PATCH v3 5/9] usbip: vhci-hcd: Set the vhci structure up to work
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> --- 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 893a5de..c96dd44 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(>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(>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(>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(>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(>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 ty
[PATCH v3 8/9] usbip: vhci-hcd: Add USB3 port status bits
From: Yuyang Du <yuyang...@intel.com> As USB3 has (slightly) different bit meanings in the port status. Add a new status bit array for USB3. Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci_hcd.c | 56 +++- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index af42a60..64c3860 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -66,7 +66,7 @@ static const char * const bit_desc[] = { "SUSPEND", /*2*/ "OVER_CURRENT", /*3*/ "RESET",/*4*/ - "R5", /*5*/ + "L1", /*5*/ "R6", /*6*/ "R7", /*7*/ "POWER",/*8*/ @@ -82,7 +82,7 @@ static const char * const bit_desc[] = { "C_SUSPEND",/*18*/ "C_OVER_CURRENT", /*19*/ "C_RESET", /*20*/ - "R21", /*21*/ + "C_L1", /*21*/ "R22", /*22*/ "R23", /*23*/ "R24", /*24*/ @@ -95,10 +95,49 @@ static const char * const bit_desc[] = { "R31", /*31*/ }; -static void dump_port_status_diff(u32 prev_status, u32 new_status) +static const char * const bit_desc_ss[] = { + "CONNECTION", /*0*/ + "ENABLE", /*1*/ + "SUSPEND", /*2*/ + "OVER_CURRENT", /*3*/ + "RESET",/*4*/ + "L1", /*5*/ + "R6", /*6*/ + "R7", /*7*/ + "R8", /*8*/ + "POWER",/*9*/ + "HIGHSPEED",/*10*/ + "PORT_TEST",/*11*/ + "INDICATOR",/*12*/ + "R13", /*13*/ + "R14", /*14*/ + "R15", /*15*/ + "C_CONNECTION", /*16*/ + "C_ENABLE", /*17*/ + "C_SUSPEND",/*18*/ + "C_OVER_CURRENT", /*19*/ + "C_RESET", /*20*/ + "C_BH_RESET", /*21*/ + "C_LINK_STATE", /*22*/ + "C_CONFIG_ERROR", /*23*/ + "R24", /*24*/ + "R25", /*25*/ + "R26", /*26*/ + "R27", /*27*/ + "R28", /*28*/ + "R29", /*29*/ + "R30", /*30*/ + "R31", /*31*/ +}; + +static void dump_port_status_diff(u32 prev_status, u32 new_status, bool usb3) { int i = 0; u32 bit = 1; + const char * const *desc = bit_desc; + + if (usb3) + desc = bit_desc_ss; pr_debug("status prev -> new: %08x -> %08x\n", prev_status, new_status); while (bit) { @@ -113,8 +152,12 @@ static void dump_port_status_diff(u32 prev_status, u32 new_status) else change = ' '; - if (prev || new) - pr_debug(" %c%s\n", change, bit_desc[i]); + if (prev || new) { + pr_debug(" %c%s\n", change, desc[i]); + + if (bit == 1) /* USB_PORT_STAT_CONNECTION */ + pr_debug(" %c%s\n", change, "USB_PORT_STAT_SPEED_5GBPS"); + } bit <<= 1; i++; } @@ -568,7 +611,8 @@ 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], - vhci_hcd->port_status[rhport]); + vhci_hcd->port_status[rhport], + hcd->speed == HCD_USB3); } } usbip_dbg_vhci_rh(" bye\n"); -- 2.7.4 -- 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
[PATCH v3 4/9] usbip: vhci-hcd: Rework vhci_hcd_init
From: Yuyang Du <yuyang...@intel.com> A vhci struct is added as the platform-specific data to the vhci platform device, in order to get the vhci by its platform device. This is done in vhci_hcd_init(). Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci_hcd.c | 51 tools/usb/usbip/libsrc/vhci_driver.c | 2 +- tools/usb/usbip/libsrc/vhci_driver.h | 1 + 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index a445d23..893a5de 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1178,24 +1178,6 @@ static struct platform_driver vhci_driver = { }, }; -static int add_platform_device(int id) -{ - struct platform_device *pdev; - int dev_nr; - - if (id == 0) - dev_nr = -1; - else - dev_nr = id; - - pdev = platform_device_register_simple(driver_name, dev_nr, NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - vhcis[id].pdev = pdev; - return 0; -} - static void del_platform_devices(void) { struct platform_device *pdev; @@ -1224,23 +1206,46 @@ static int __init vhci_hcd_init(void) if (vhcis == NULL) return -ENOMEM; + for (i = 0; i < vhci_num_controllers; i++) { + vhcis[i].pdev = platform_device_alloc(driver_name, i); + if (!vhcis[i].pdev) { + i--; + while (i >= 0) + platform_device_put(vhcis[i--].pdev); + ret = -ENOMEM; + goto err_device_alloc; + } + } + for (i = 0; i < vhci_num_controllers; i++) { + void *vhci = [i]; + ret = platform_device_add_data(vhcis[i].pdev, , sizeof(void *)); + if (ret) + goto err_driver_register; + } + ret = platform_driver_register(_driver); if (ret) goto err_driver_register; for (i = 0; i < vhci_num_controllers; i++) { - ret = add_platform_device(i); - if (ret) - goto err_platform_device_register; + ret = platform_device_add(vhcis[i].pdev); + if (ret < 0) { + i--; + while (i >= 0) + platform_device_del(vhcis[i--].pdev); + goto err_add_hcd; + } } pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; -err_platform_device_register: - del_platform_devices(); +err_add_hcd: platform_driver_unregister(_driver); err_driver_register: + for (i = 0; i < vhci_num_controllers; i++) + platform_device_put(vhcis[i].pdev); +err_device_alloc: kfree(vhcis); return ret; } diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index af88447..5b19a32 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -248,7 +248,7 @@ int usbip_vhci_driver_open(void) vhci_driver->hc_device = udev_device_new_from_subsystem_sysname(udev_context, USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); + USBIP_VHCI_DEVICE_NAME); if (!vhci_driver->hc_device) { err("udev_device_new_from_subsystem_sysname failed"); goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 33add14..dfe19c1 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -11,6 +11,7 @@ #include "usbip_common.h" #define USBIP_VHCI_BUS_TYPE "platform" +#define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" #define MAXNPORT 128 struct usbip_imported_device { -- 2.7.4 -- 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
[PATCH v3 9/9] usbip: vhci-hcd: Clean up the code by adding a new macro
From: Yuyang Du <yuyang...@intel.com> Each vhci has 2*VHCI_HC_PORTS ports, in which VHCI_HC_PORTS ports are HighSpeed (or below), and VHCI_HC_PORTS are SuperSpeed. This new macro VHCI_PORTS reflects this configuration. Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci.h | 5 - drivers/usb/usbip/vhci_sysfs.c | 10 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index db28eb5..5cfb59e 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -84,6 +84,9 @@ enum hub_speed { #define VHCI_HC_PORTS 8 #endif +/* Each VHCI has 2 hubs (USB2 and USB3), each has VHCI_HC_PORTS ports */ +#define VHCI_PORTS (VHCI_HC_PORTS*2) + #ifdef CONFIG_USBIP_VHCI_NR_HCS #define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS #else @@ -145,7 +148,7 @@ static inline __u32 port_to_rhport(__u32 port) static inline int port_to_pdev_nr(__u32 port) { - return port / (VHCI_HC_PORTS * 2); + return port / VHCI_PORTS; } static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 3ad68ff..5778b64 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -92,7 +92,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out) spin_lock(>ud.lock); port_show_vhci(, HUB_SPEED_HIGH, - pdev_nr * VHCI_HC_PORTS * 2 + i, vdev); + pdev_nr * VHCI_PORTS + i, vdev); spin_unlock(>ud.lock); } @@ -101,7 +101,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out) spin_lock(>ud.lock); port_show_vhci(, HUB_SPEED_SUPER, - pdev_nr * VHCI_HC_PORTS * 2 + VHCI_HC_PORTS + i, vdev); + pdev_nr * VHCI_PORTS + VHCI_HC_PORTS + i, vdev); spin_unlock(>ud.lock); } @@ -117,7 +117,7 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out) for (i = 0; i < VHCI_HC_PORTS; i++) { out += sprintf(out, "hs %04u %03u ", - (pdev_nr * VHCI_HC_PORTS * 2) + i, + (pdev_nr * VHCI_PORTS) + i, VDEV_ST_NOTASSIGNED); out += sprintf(out, "000 0-0"); out += sprintf(out, "\n"); @@ -125,7 +125,7 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out) for (i = 0; i < VHCI_HC_PORTS; i++) { out += sprintf(out, "ss %04u %03u ", - (pdev_nr * VHCI_HC_PORTS * 2) + VHCI_HC_PORTS + i, + (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i, VDEV_ST_NOTASSIGNED); out += sprintf(out, "000 0-0"); out += sprintf(out, "\n"); @@ -176,7 +176,7 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr, /* * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2. */ - out += sprintf(out, "%d\n", VHCI_HC_PORTS * vhci_num_controllers * 2); + out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); return out - s; } static DEVICE_ATTR_RO(nports); -- 2.7.4 -- 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
[PATCH v3 3/9] usbip: vhci-hcd: Move VHCI platform device into vhci struct
From: Yuyang Du <yuyang...@intel.com> Every VHCI is a platform device, so move the platform_device struct into the VHCI struct. Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci.h | 3 ++- drivers/usb/usbip/vhci_hcd.c | 17 - drivers/usb/usbip/vhci_sysfs.c | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 9959584..62ee537 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -90,6 +90,8 @@ struct vhci_unlink { struct vhci { spinlock_t lock; + struct platform_device *pdev; + struct vhci_hcd *vhci_hcd_hs; struct vhci_hcd *vhci_hcd_ss; }; @@ -116,7 +118,6 @@ struct vhci_hcd { }; extern int vhci_num_controllers; -extern struct platform_device **vhci_pdevs; extern struct vhci *vhcis; extern struct attribute_group vhci_attr_group; diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 863a12d..a445d23 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -58,8 +58,7 @@ static const char driver_name[] = "vhci_hcd"; static const char driver_desc[] = "USB/IP Virtual Host Controller"; int vhci_num_controllers = VHCI_NR_HCS; - -struct platform_device **vhci_pdevs; +struct vhci *vhcis; static const char * const bit_desc[] = { "CONNECTION", /*0*/ @@ -1193,7 +1192,7 @@ static int add_platform_device(int id) if (IS_ERR(pdev)) return PTR_ERR(pdev); - *(vhci_pdevs + id) = pdev; + vhcis[id].pdev = pdev; return 0; } @@ -1203,10 +1202,10 @@ static void del_platform_devices(void) int i; for (i = 0; i < vhci_num_controllers; i++) { - pdev = *(vhci_pdevs + i); + pdev = vhcis[i].pdev; if (pdev != NULL) platform_device_unregister(pdev); - *(vhci_pdevs + i) = NULL; + vhcis[i].pdev = NULL; } sysfs_remove_link(_bus.kobj, driver_name); } @@ -1221,8 +1220,8 @@ static int __init vhci_hcd_init(void) if (vhci_num_controllers < 1) vhci_num_controllers = 1; - vhci_pdevs = kcalloc(vhci_num_controllers, sizeof(void *), GFP_KERNEL); - if (vhci_pdevs == NULL) + vhcis = kcalloc(vhci_num_controllers, sizeof(struct vhci), GFP_KERNEL); + if (vhcis == NULL) return -ENOMEM; ret = platform_driver_register(_driver); @@ -1242,7 +1241,7 @@ static int __init vhci_hcd_init(void) del_platform_devices(); platform_driver_unregister(_driver); err_driver_register: - kfree(vhci_pdevs); + kfree(vhcis); return ret; } @@ -1250,7 +1249,7 @@ static void __exit vhci_hcd_exit(void) { del_platform_devices(); platform_driver_unregister(_driver); - kfree(vhci_pdevs); + kfree(vhcis); } module_init(vhci_hcd_init); diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index d878faa..07f0d37 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -32,7 +32,7 @@ /* Sysfs entry to show port status */ static ssize_t status_show_vhci(int pdev_nr, char *out) { - struct platform_device *pdev = *(vhci_pdevs + pdev_nr); + struct platform_device *pdev = vhcis[pdev_nr].pdev; struct vhci_hcd *vhci; char *s = out; int i = 0; @@ -206,7 +206,7 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr, if (!valid_port(pdev_nr, rhport)) return -EINVAL; - hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr)); + hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); if (hcd == NULL) { dev_err(dev, "port is not ready %u\n", port); return -EAGAIN; @@ -287,7 +287,7 @@ 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)); + hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); if (hcd == NULL) { dev_err(dev, "port %d is not ready\n", port); return -EAGAIN; -- 2.7.4 -- 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
[PATCH v3 6/9] usbip: vhci-hcd: Add USB3 SuperSpeed support
From: Yuyang Du <yuyang...@intel.com> This patch adds a USB3 HCD to an existing USB2 HCD and provides the support of SuperSpeed, in case the device can only be enumerated with SuperSpeed. The bulk of the added code in usb3_bos_desc and hub_control to support SuperSpeed is borrowed from the commit 1cd8fd2887e162ad ("usb: gadget: dummy_hcd: add SuperSpeed support"). With this patch, each vhci will have VHCI_HC_PORTS HighSpeed ports and VHCI_HC_PORTS SuperSpeed ports. Suggested-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci.h | 7 +- drivers/usb/usbip/vhci_hcd.c | 323 --- drivers/usb/usbip/vhci_sysfs.c | 109 tools/usb/usbip/libsrc/vhci_driver.c | 23 ++- tools/usb/usbip/libsrc/vhci_driver.h | 8 +- tools/usb/usbip/src/usbip_attach.c | 3 +- 6 files changed, 370 insertions(+), 103 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 8a979fc..db28eb5 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -72,6 +72,11 @@ struct vhci_unlink { unsigned long unlink_seqnum; }; +enum hub_speed { + HUB_SPEED_HIGH = 0, + HUB_SPEED_SUPER, +}; + /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ #ifdef CONFIG_USBIP_VHCI_HC_PORTS #define VHCI_HC_PORTS CONFIG_USBIP_VHCI_HC_PORTS @@ -140,7 +145,7 @@ static inline __u32 port_to_rhport(__u32 port) static inline int port_to_pdev_nr(__u32 port) { - return port / VHCI_HC_PORTS; + return port / (VHCI_HC_PORTS * 2); } static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index c96dd44..af42a60 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -232,6 +232,40 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) return changed ? retval : 0; } +/* usb 3.0 root hub device descriptor */ +static struct { + struct usb_bos_descriptor bos; + struct usb_ss_cap_descriptor ss_cap; +} __packed usb3_bos_desc = { + + .bos = { + .bLength= USB_DT_BOS_SIZE, + .bDescriptorType= USB_DT_BOS, + .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), + .bNumDeviceCaps = 1, + }, + .ss_cap = { + .bLength= USB_DT_USB_SS_CAP_SIZE, + .bDescriptorType= USB_DT_DEVICE_CAPABILITY, + .bDevCapabilityType = USB_SS_CAP_TYPE, + .wSpeedSupported= cpu_to_le16(USB_5GBPS_OPERATION), + .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), + }, +}; + +static inline void +ss_hub_descriptor(struct usb_hub_descriptor *desc) +{ + memset(desc, 0, sizeof *desc); + desc->bDescriptorType = USB_DT_SS_HUB; + desc->bDescLength = 12; + desc->wHubCharacteristics = cpu_to_le16( + HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); + desc->bNbrPorts = VHCI_HC_PORTS; + desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/ + desc->u.ss.DeviceRemovable = 0x; +} + static inline void hub_descriptor(struct usb_hub_descriptor *desc) { int width; @@ -265,13 +299,15 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, /* * NOTE: -* wIndex shows the port number and begins from 1. +* wIndex (bits 0-7) shows the port number and begins from 1? */ + wIndex = ((__u8)(wIndex & 0x00ff)); usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex); + if (wIndex > VHCI_HC_PORTS) pr_err("invalid port number %d\n", wIndex); - rhport = ((__u8)(wIndex & 0x00ff)) - 1; + rhport = wIndex - 1; vhci_hcd = hcd_to_vhci_hcd(hcd); vhci = vhci_hcd->vhci; @@ -291,34 +327,26 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case ClearPortFeature: switch (wValue) { case USB_PORT_FEAT_SUSPEND: + if (hcd->speed == HCD_USB3) { + pr_err(" ClearPortFeature: USB_PORT_FEAT_SUSPEND req not " + "supported for USB 3.0 roothub\n"); + goto error; + } + usbip_dbg_vhci_rh( + " ClearPortFeature: USB_PORT_FEAT_SUSPEND\n"); if (vhci_hcd->port_status[rhport] & USB_PORT_STAT_SUSPEND) { /* 20
[PATCH v3 1/9] usbip: vhci-hcd: Rename function names to reflect their struct names
From: Yuyang Du <yuyang...@intel.com> These helper function names are renamed to have their full struct names to avoid confusion: - hcd_to_vhci() -> hcd_to_vhci_hcd() - vhci_to_hcd() -> vhci_hcd_to_hcd() - vdev_to_vhci() -> vdev_to_vhci_hcd() Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci.h | 11 +-- drivers/usb/usbip/vhci_hcd.c | 34 +- drivers/usb/usbip/vhci_rx.c| 12 ++-- drivers/usb/usbip/vhci_sysfs.c | 6 +++--- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..bff472f 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -134,7 +134,7 @@ static inline int port_to_pdev_nr(__u32 port) return port / VHCI_HC_PORTS; } -static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) +static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) { return (struct vhci_hcd *) (hcd->hcd_priv); } @@ -149,15 +149,14 @@ static inline const char *hcd_name(struct usb_hcd *hcd) return (hcd)->self.bus_name; } -static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci) +static inline struct usb_hcd *vhci_hcd_to_hcd(struct vhci_hcd *vhci_hcd) { - return container_of((void *) vhci, struct usb_hcd, hcd_priv); + return container_of((void *) vhci_hcd, struct usb_hcd, hcd_priv); } -static inline struct vhci_hcd *vdev_to_vhci(struct vhci_device *vdev) +static inline struct vhci_hcd *vdev_to_vhci_hcd(struct vhci_device *vdev) { - return container_of( - (void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); + return container_of((void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); } #endif /* __USBIP_VHCI_H */ diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 0585078..863a12d 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -124,7 +124,7 @@ 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(vdev); + struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev); int rhport = vdev->rhport; u32 status; unsigned long flags; @@ -152,12 +152,12 @@ void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed) spin_unlock_irqrestore(>lock, flags); - usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); + usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci)); } static void rh_port_disconnect(struct vhci_device *vdev) { - struct vhci_hcd *vhci = vdev_to_vhci(vdev); + struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev); int rhport = vdev->rhport; u32 status; unsigned long flags; @@ -174,7 +174,7 @@ static void rh_port_disconnect(struct vhci_device *vdev) vhci->port_status[rhport] = status; spin_unlock_irqrestore(>lock, flags); - usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); + usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci)); } #define PORT_C_MASK\ @@ -206,7 +206,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) retval = DIV_ROUND_UP(VHCI_HC_PORTS + 1, 8); memset(buf, 0, retval); - vhci = hcd_to_vhci(hcd); + vhci = hcd_to_vhci_hcd(hcd); spin_lock_irqsave(>lock, flags); if (!HCD_HW_ACCESSIBLE(hcd)) { @@ -273,7 +273,7 @@ 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); + dum = hcd_to_vhci_hcd(hcd); spin_lock_irqsave(>lock, flags); @@ -445,7 +445,7 @@ static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) pr_err("could not get virtual device"); return; } - vhci = vdev_to_vhci(vdev); + vhci = vdev_to_vhci_hcd(vdev); priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); if (!priv) { @@ -473,7 +473,7 @@ 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); + struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd); struct device *dev = >dev->dev; u8 portnum = urb->dev->portnum; int ret = 0; @@ -640,7 +640,7 @@ 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); +
[PATCH v3 0/9] usbip: Enable USB3 SuperSpeed
Hi Shuah, SuperSpeed (only) USB devices cannot be shared via usbip. This patch series attempts to fix it. The first 5 patches refactors the existing code to prepare for the SuperSpeed addition. With this series, our SuperSpeed device works fine. Many thanks to Greg and Krzysztof for their patience to answer my non-usb-professional questions, and special thanks to Krzysztof for the pointer to the SuperSpeed patch in dummy_hcd. This series is based on the series: "usb: usbip: Fix ports and port status v6" (https://www.spinics.net/lists/linux-usb/msg155834.html). v3: - Add Acked-bys v2: - Remove set_link_state() since it is not used Regards, Yuyang -- Yuyang Du (9): usbip: vhci-hcd: Rename function names to reflect their struct names usbip: vhci-hcd: Add vhci struct usbip: vhci-hcd: Move VHCI platform device into vhci struct usbip: vhci-hcd: Rework vhci_hcd_init usbip: vhci-hcd: Set the vhci structure up to work usbip: vhci-hcd: Add USB3 SuperSpeed support usbip: Add USB_SPEED_SUPER as valid arg usbip: vhci-hcd: Add USB3 port status bits usbip: vhci-hcd: Clean up the code by adding a new macro drivers/usb/usbip/vhci.h | 36 ++- drivers/usb/usbip/vhci_hcd.c | 605 +-- drivers/usb/usbip/vhci_rx.c | 16 +- drivers/usb/usbip/vhci_sysfs.c | 138 +--- tools/usb/usbip/libsrc/vhci_driver.c | 25 +- tools/usb/usbip/libsrc/vhci_driver.h | 9 +- tools/usb/usbip/src/usbip_attach.c | 3 +- 7 files changed, 601 insertions(+), 231 deletions(-) -- 2.7.4 -- 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
[PATCH v3 2/9] usbip: vhci-hcd: Add vhci struct
From: Yuyang Du <yuyang...@intel.com> In order to support SuperSpeed devices, a USB3 HCD is added to share the USB2 HCD. As a result, a VHCI is composed of two vhci_hcds associated with the two HCDs respectively. So we add another level of abstraction, vhci, and thus this vhci structure. Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci.h | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index bff472f..9959584 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -87,8 +87,17 @@ struct vhci_unlink { #define MAX_STATUS_NAME 16 -/* for usb_bus.hcpriv */ +struct vhci { + spinlock_t lock; + + struct vhci_hcd *vhci_hcd_hs; + struct vhci_hcd *vhci_hcd_ss; +}; + +/* for usb_hcd.hcd_priv[0] */ struct vhci_hcd { + struct vhci *vhci; + spinlock_t lock; u32 port_status[VHCI_HC_PORTS]; @@ -108,6 +117,7 @@ struct vhci_hcd { extern int vhci_num_controllers; extern struct platform_device **vhci_pdevs; +extern struct vhci *vhcis; extern struct attribute_group vhci_attr_group; /* vhci_hcd.c */ -- 2.7.4 -- 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
[PATCH v6 0/4] usb: usbip: Fix ports and port status
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced several bugs relating to the number of ports amd the port status. In addition, a small improvement is made to the vhci_hcd module. v6: - Add Acked-bys v4 & v5: - Fix a coding style issue v3 resend: - Remove already picked patches - Add a few *-bys v3: - Check both ends of the nports - Check the return of ncontrollers - Add a few Reviewed-bys and Acked-bys - Minor coding changes v2: - Remove ncontrollers RO attr as suggested by Krzysztof - As a result, scandir vhci_hcd* dir in platform to learn how many we have as suggested by Krzysztof - Minor coding changes Thanks, Yuyang -- Yuyang Du (4): usb: usbip tool: Check the return of get_nports() usb: usbip tool: Add ncontrollers in vhci_driver structure usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() tools/usb/usbip/libsrc/vhci_driver.c | 110 +-- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/usbip_attach.c | 2 + 3 files changed, 83 insertions(+), 30 deletions(-) -- 2.7.4 -- 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
[PATCH v6 1/4] usb: usbip tool: Check the return of get_nports()
From: Yuyang Du <yuyang...@intel.com> If we get nonpositive number of ports, there is no sense to continue, then fail gracefully. In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: modifications to vhci driver") introduced configurable numbers of controllers and ports, but we have a static port number maximum, MAXNPORT. If exceeded, the idev array will be overflown. We fix it by validating the nports to make sure the port number max is not exceeded. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f659c14..036b62b 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -220,9 +220,16 @@ int usbip_vhci_driver_open(void) } vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); + if (vhci_driver->nports <= 0) { + err("no available ports"); + goto err; + } else if (vhci_driver->nports > MAXNPORT) { + err("port number exceeds %d", MAXNPORT); + goto err; + } + if (refresh_imported_device_list()) goto err; -- 2.7.4 -- 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
[PATCH v6 2/4] usb: usbip tool: Add ncontrollers in vhci_driver structure
From: Yuyang Du <yuyang...@intel.com> A new field ncontrollers is added to the vhci_driver structure. And this field is stored by scanning the vhci_hcd* dirs in the platform udev. Suggested-and-reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 36 tools/usb/usbip/libsrc/vhci_driver.h | 1 + 2 files changed, 37 insertions(+) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 036b62b..f6f3a19 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -134,6 +135,33 @@ static int get_nports(void) return (int)strtoul(attr_nports, NULL, 10); } +static int vhci_hcd_filter(const struct dirent *dirent) +{ + return strcmp(dirent->d_name, "vhci_hcd") >= 0; +} + +static int get_ncontrollers(void) +{ + struct dirent **namelist; + struct udev_device *platform; + int n; + + platform = udev_device_get_parent(vhci_driver->hc_device); + if (platform == NULL) + return -1; + + n = scandir(udev_device_get_syspath(platform), , vhci_hcd_filter, NULL); + if (n < 0) + err("scandir failed"); + else { + for (int i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + } + + return n; +} + /* * Read the given port's record. * @@ -230,6 +258,14 @@ int usbip_vhci_driver_open(void) goto err; } + vhci_driver->ncontrollers = get_ncontrollers(); + dbg("available controllers: %d", vhci_driver->ncontrollers); + + if (vhci_driver->ncontrollers <=0) { + err("no available usb controllers"); + goto err; + } + if (refresh_imported_device_list()) goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..33add14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -31,6 +31,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; + int ncontrollers; int nports; struct usbip_imported_device idev[MAXNPORT]; }; -- 2.7.4 -- 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
[PATCH v6 4/4] usb: usbip tool: Fix parse_status()
From: Yuyang Du <yuyang...@intel.com> In parse_status(), all nports number of idev's are initiated to 0 by memset(), it is simply wrong, because parse_status() reads the status sys file one by one, therefore, it can only update the according vhci_driver->idev's for it to parse. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 38 ++-- tools/usb/usbip/src/usbip_attach.c | 2 ++ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index aa82c4b..f519c73 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -36,18 +36,11 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) return NULL; } - - static int parse_status(const char *value) { int ret = 0; char *c; - - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); - - /* skip a header line */ c = strchr(value, '\n'); if (!c) @@ -58,6 +51,7 @@ static int parse_status(const char *value) int port, status, speed, devid; unsigned long socket; char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; ret = sscanf(c, "%d %d %d %x %lx %31s\n", , , , @@ -72,30 +66,28 @@ static int parse_status(const char *value) port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; + idev = _driver->idev[port]; - idev->port = port; - idev->status= status; + memset(idev, 0, sizeof(*idev)); - idev->devid = devid; + idev->port = port; + idev->status= status; - idev->busnum= (devid >> 16); - idev->devnum= (devid & 0x); + idev->devid = devid; - if (idev->status != VDEV_ST_NULL - && idev->status != VDEV_ST_NOTASSIGNED) { - idev = imported_device_init(idev, lbusid); - if (!idev) { - dbg("imported_device_init failed"); - return -1; - } + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); + + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; } } - /* go to the next line */ c = strchr(c, '\n'); if (!c) diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..62a297f 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -108,6 +108,8 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } + dbg("got free port %d", port); + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, udev->devnum, udev->speed); if (rc < 0) { -- 2.7.4 -- 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
[PATCH v6 3/4] usb: usbip tool: Fix refresh_imported_device_list()
From: Yuyang Du <yuyang...@intel.com> The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, but the status of the ports are only extracted from the first status file, fix it. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f6f3a19..aa82c4b 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -108,18 +108,33 @@ static int parse_status(const char *value) return 0; } +#define MAX_STATUS_NAME 16 + static int refresh_imported_device_list(void) { const char *attr_status; + char status[MAX_STATUS_NAME+1] = "status"; + int i, ret; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); - return -1; + for (i = 0; i < vhci_driver->ncontrollers; i++) { + if (i > 0) + snprintf(status, sizeof(status), "status.%d", i); + + attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, + status); + if (!attr_status) { + err("udev_device_get_sysattr_value failed"); + return -1; + } + + dbg("controller %d", i); + + ret = parse_status(attr_status); + if (ret != 0) + return ret; } - return parse_status(attr_status); + return 0; } static int get_nports(void) -- 2.7.4 -- 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
[PATCH v5 0/4] usb: usbip: Fix ports and port status
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced several bugs relating to the number of ports amd the port status. In addition, a small improvement is made to the vhci_hcd module. v4 & v5: - Fix a coding style issue v3 resend: - Remove already picked patches - Add a few *-bys v3: - Check both ends of the nports - Check the return of ncontrollers - Add a few Reviewed-bys and Acked-bys - Minor coding changes v2: - Remove ncontrollers RO attr as suggested by Krzysztof - As a result, scandir vhci_hcd* dir in platform to learn how many we have as suggested by Krzysztof - Minor coding changes Thanks, Yuyang -- Yuyang Du (4): usb: usbip tool: Check the return of get_nports() usb: usbip tool: Add ncontrollers in vhci_driver structure usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() tools/usb/usbip/libsrc/vhci_driver.c | 110 +-- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/usbip_attach.c | 2 + 3 files changed, 83 insertions(+), 30 deletions(-) -- 2.7.4 -- 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
[PATCH v5 2/4] usb: usbip tool: Add ncontrollers in vhci_driver structure
From: Yuyang Du <yuyang...@intel.com> A new field ncontrollers is added to the vhci_driver structure. And this field is stored by scanning the vhci_hcd* dirs in the platform udev. Suggested-and-reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 36 tools/usb/usbip/libsrc/vhci_driver.h | 1 + 2 files changed, 37 insertions(+) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 036b62b..f6f3a19 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -134,6 +135,33 @@ static int get_nports(void) return (int)strtoul(attr_nports, NULL, 10); } +static int vhci_hcd_filter(const struct dirent *dirent) +{ + return strcmp(dirent->d_name, "vhci_hcd") >= 0; +} + +static int get_ncontrollers(void) +{ + struct dirent **namelist; + struct udev_device *platform; + int n; + + platform = udev_device_get_parent(vhci_driver->hc_device); + if (platform == NULL) + return -1; + + n = scandir(udev_device_get_syspath(platform), , vhci_hcd_filter, NULL); + if (n < 0) + err("scandir failed"); + else { + for (int i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + } + + return n; +} + /* * Read the given port's record. * @@ -230,6 +258,14 @@ int usbip_vhci_driver_open(void) goto err; } + vhci_driver->ncontrollers = get_ncontrollers(); + dbg("available controllers: %d", vhci_driver->ncontrollers); + + if (vhci_driver->ncontrollers <=0) { + err("no available usb controllers"); + goto err; + } + if (refresh_imported_device_list()) goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..33add14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -31,6 +31,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; + int ncontrollers; int nports; struct usbip_imported_device idev[MAXNPORT]; }; -- 2.7.4 -- 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
[PATCH v5 1/4] usb: usbip tool: Check the return of get_nports()
From: Yuyang Du <yuyang...@intel.com> If we get nonpositive number of ports, there is no sense to continue, then fail gracefully. In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: modifications to vhci driver") introduced configurable numbers of controllers and ports, but we have a static port number maximum, MAXNPORT. If exceeded, the idev array will be overflown. We fix it by validating the nports to make sure the port number max is not exceeded. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f659c14..036b62b 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -220,9 +220,16 @@ int usbip_vhci_driver_open(void) } vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); + if (vhci_driver->nports <= 0) { + err("no available ports"); + goto err; + } else if (vhci_driver->nports > MAXNPORT) { + err("port number exceeds %d", MAXNPORT); + goto err; + } + if (refresh_imported_device_list()) goto err; -- 2.7.4 -- 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
[PATCH v5 3/4] usb: usbip tool: Fix refresh_imported_device_list()
From: Yuyang Du <yuyang...@intel.com> The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, but the status of the ports are only extracted from the first status file, fix it. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f6f3a19..aa82c4b 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -108,18 +108,33 @@ static int parse_status(const char *value) return 0; } +#define MAX_STATUS_NAME 16 + static int refresh_imported_device_list(void) { const char *attr_status; + char status[MAX_STATUS_NAME+1] = "status"; + int i, ret; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); - return -1; + for (i = 0; i < vhci_driver->ncontrollers; i++) { + if (i > 0) + snprintf(status, sizeof(status), "status.%d", i); + + attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, + status); + if (!attr_status) { + err("udev_device_get_sysattr_value failed"); + return -1; + } + + dbg("controller %d", i); + + ret = parse_status(attr_status); + if (ret != 0) + return ret; } - return parse_status(attr_status); + return 0; } static int get_nports(void) -- 2.7.4 -- 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
[PATCH v5 4/4] usb: usbip tool: Fix parse_status()
From: Yuyang Du <yuyang...@intel.com> In parse_status(), all nports number of idev's are initiated to 0 by memset(), it is simply wrong, because parse_status() reads the status sys file one by one, therefore, it can only update the according vhci_driver->idev's for it to parse. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 38 ++-- tools/usb/usbip/src/usbip_attach.c | 2 ++ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index aa82c4b..f519c73 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -36,18 +36,11 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) return NULL; } - - static int parse_status(const char *value) { int ret = 0; char *c; - - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); - - /* skip a header line */ c = strchr(value, '\n'); if (!c) @@ -58,6 +51,7 @@ static int parse_status(const char *value) int port, status, speed, devid; unsigned long socket; char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; ret = sscanf(c, "%d %d %d %x %lx %31s\n", , , , @@ -72,30 +66,28 @@ static int parse_status(const char *value) port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; + idev = _driver->idev[port]; - idev->port = port; - idev->status= status; + memset(idev, 0, sizeof(*idev)); - idev->devid = devid; + idev->port = port; + idev->status= status; - idev->busnum= (devid >> 16); - idev->devnum= (devid & 0x); + idev->devid = devid; - if (idev->status != VDEV_ST_NULL - && idev->status != VDEV_ST_NOTASSIGNED) { - idev = imported_device_init(idev, lbusid); - if (!idev) { - dbg("imported_device_init failed"); - return -1; - } + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); + + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; } } - /* go to the next line */ c = strchr(c, '\n'); if (!c) diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..62a297f 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -108,6 +108,8 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } + dbg("got free port %d", port); + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, udev->devnum, udev->speed); if (rc < 0) { -- 2.7.4 -- 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
Re: [PATCH v2 0/9] usbip: Enable USB3 SuperSpeed
Hi Shuah, On Fri, May 19, 2017 at 04:55:40PM -0600, Shuah Khan wrote: > > > > v2: > > - Remove set_link_state() since it is not used > > > > Regards, > > Yuyang > > Hi Yuyang, > > Thanks for the patch series. I will try to review this next week > on my business trip. If not, I will definitely get to it the week > of May 29th. Thank you! It'd be good if you can too finish the review of the rest of the patch series "usb: usbip: Fix ports and port status": usb: usbip tool: Add ncontrollers in vhci_driver structure usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() Thanks, Yuyang -- 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
Re: [PATCH v4 1/4] usb: usbip tool: Check the return of get_nports()
On Mon, May 22, 2017 at 12:13:12PM +0300, Sergei Shtylyov wrote: > >+if (vhci_driver->nports <= 0) { > >+err("no available ports"); > >+goto err; > >+} > >+else if (vhci_driver->nports > MAXNPORT) { > > } and *else if* should be on te same line. Not sure how I missed that in > the 1st review, sorry about that... Thank you so much. No, it's all on me. I'm sorry, really. Thanks, Yuyang -- 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
[PATCH v4 4/4] usb: usbip tool: Fix parse_status()
In parse_status(), all nports number of idev's are initiated to 0 by memset(), it is simply wrong, because parse_status() reads the status sys file one by one, therefore, it can only update the according vhci_driver->idev's for it to parse. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 38 ++-- tools/usb/usbip/src/usbip_attach.c | 2 ++ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 85c9736..b23a156 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -36,18 +36,11 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) return NULL; } - - static int parse_status(const char *value) { int ret = 0; char *c; - - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); - - /* skip a header line */ c = strchr(value, '\n'); if (!c) @@ -58,6 +51,7 @@ static int parse_status(const char *value) int port, status, speed, devid; unsigned long socket; char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; ret = sscanf(c, "%d %d %d %x %lx %31s\n", , , , @@ -72,30 +66,28 @@ static int parse_status(const char *value) port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; + idev = _driver->idev[port]; - idev->port = port; - idev->status= status; + memset(idev, 0, sizeof(*idev)); - idev->devid = devid; + idev->port = port; + idev->status= status; - idev->busnum= (devid >> 16); - idev->devnum= (devid & 0x); + idev->devid = devid; - if (idev->status != VDEV_ST_NULL - && idev->status != VDEV_ST_NOTASSIGNED) { - idev = imported_device_init(idev, lbusid); - if (!idev) { - dbg("imported_device_init failed"); - return -1; - } + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); + + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; } } - /* go to the next line */ c = strchr(c, '\n'); if (!c) diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..62a297f 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -108,6 +108,8 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } + dbg("got free port %d", port); + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, udev->devnum, udev->speed); if (rc < 0) { -- 2.7.4 -- 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
[PATCH v4 1/4] usb: usbip tool: Check the return of get_nports()
If we get nonpositive number of ports, there is no sense to continue, then fail gracefully. In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: modifications to vhci driver") introduced configurable numbers of controllers and ports, but we have a static port number maximum, MAXNPORT. If exceeded, the idev array will be overflown. We fix it by validating the nports to make sure the port number max is not exceeded. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f659c14..0a6d113 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -220,9 +220,17 @@ int usbip_vhci_driver_open(void) } vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); + if (vhci_driver->nports <= 0) { + err("no available ports"); + goto err; + } + else if (vhci_driver->nports > MAXNPORT) { + err("port number exceeds %d", MAXNPORT); + goto err; + } + if (refresh_imported_device_list()) goto err; -- 2.7.4 -- 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
[PATCH v4 3/4] usb: usbip tool: Fix refresh_imported_device_list()
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, but the status of the ports are only extracted from the first status file, fix it. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index debb9a4..85c9736 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -108,18 +108,33 @@ static int parse_status(const char *value) return 0; } +#define MAX_STATUS_NAME 16 + static int refresh_imported_device_list(void) { const char *attr_status; + char status[MAX_STATUS_NAME+1] = "status"; + int i, ret; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); - return -1; + for (i = 0; i < vhci_driver->ncontrollers; i++) { + if (i > 0) + snprintf(status, sizeof(status), "status.%d", i); + + attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, + status); + if (!attr_status) { + err("udev_device_get_sysattr_value failed"); + return -1; + } + + dbg("controller %d", i); + + ret = parse_status(attr_status); + if (ret != 0) + return ret; } - return parse_status(attr_status); + return 0; } static int get_nports(void) -- 2.7.4 -- 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
[PATCH v4 0/4] usb: usbip: Fix ports and port status
From: Yuyang Du <yuyang...@linux.intel.com> The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced several bugs relating to the number of ports amd the port status. In addition, a small improvement is made to the vhci_hcd module. v4: - Fix a coding style issue v3 resend: - Remove already picked patches - Add a few *-bys v3: - Check both ends of the nports - Check the return of ncontrollers - Add a few Reviewed-bys and Acked-bys - Minor coding changes v2: - Remove ncontrollers RO attr as suggested by Krzysztof - As a result, scandir vhci_hcd* dir in platform to learn how many we have as suggested by Krzysztof - Minor coding changes Thanks, Yuyang -- Yuyang Du (4): usb: usbip tool: Check the return of get_nports() usb: usbip tool: Add ncontrollers in vhci_driver structure usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() tools/usb/usbip/libsrc/vhci_driver.c | 111 +-- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/usbip_attach.c | 2 + 3 files changed, 84 insertions(+), 30 deletions(-) -- 2.7.4 -- 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
[PATCH v4 2/4] usb: usbip tool: Add ncontrollers in vhci_driver structure
A new field ncontrollers is added to the vhci_driver structure. And this field is stored by scanning the vhci_hcd* dirs in the platform udev. Suggested-and-reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 36 tools/usb/usbip/libsrc/vhci_driver.h | 1 + 2 files changed, 37 insertions(+) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 0a6d113..debb9a4 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -134,6 +135,33 @@ static int get_nports(void) return (int)strtoul(attr_nports, NULL, 10); } +static int vhci_hcd_filter(const struct dirent *dirent) +{ + return strcmp(dirent->d_name, "vhci_hcd") >= 0; +} + +static int get_ncontrollers(void) +{ + struct dirent **namelist; + struct udev_device *platform; + int n; + + platform = udev_device_get_parent(vhci_driver->hc_device); + if (platform == NULL) + return -1; + + n = scandir(udev_device_get_syspath(platform), , vhci_hcd_filter, NULL); + if (n < 0) + err("scandir failed"); + else { + for (int i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + } + + return n; +} + /* * Read the given port's record. * @@ -231,6 +259,14 @@ int usbip_vhci_driver_open(void) goto err; } + vhci_driver->ncontrollers = get_ncontrollers(); + dbg("available controllers: %d", vhci_driver->ncontrollers); + + if (vhci_driver->ncontrollers <=0) { + err("no available usb controllers"); + goto err; + } + if (refresh_imported_device_list()) goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..33add14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -31,6 +31,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; + int ncontrollers; int nports; struct usbip_imported_device idev[MAXNPORT]; }; -- 2.7.4 -- 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
Re: [PATCH resend v3 1/4] usb: usbip tool: Check the return of get_nports()
On Thu, May 18, 2017 at 03:53:04PM +0300, Sergei Shtylyov wrote: > >+if (vhci_driver->nports <=0) { > >Please add a space after <= too. Indeed. Thanks. Hi Greg, Do you want me to send another version to fix this? Thanks, Yuyang -- 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
Re: [PATCH resend v3 1/4] usb: usbip tool: Check the return of get_nports()
On Thu, May 18, 2017 at 03:53:04PM +0300, Sergei Shtylyov wrote: > >From: Yuyang Du <yuyang...@intel.com> > > > >If we get nonpositive number of ports, there is no sense to > >Negative? Negative and zero. -- 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
[PATCH v2 8/9] usbip: vhci-hcd: Add USB3 port status bits
From: Yuyang Du <yuyang...@intel.com> As USB3 has (slightly) different bit meanings in the port status. Add a new status bit array for USB3. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 56 +++- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 43cacbc..a71254b 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -66,7 +66,7 @@ static const char * const bit_desc[] = { "SUSPEND", /*2*/ "OVER_CURRENT", /*3*/ "RESET",/*4*/ - "R5", /*5*/ + "L1", /*5*/ "R6", /*6*/ "R7", /*7*/ "POWER",/*8*/ @@ -82,7 +82,7 @@ static const char * const bit_desc[] = { "C_SUSPEND",/*18*/ "C_OVER_CURRENT", /*19*/ "C_RESET", /*20*/ - "R21", /*21*/ + "C_L1", /*21*/ "R22", /*22*/ "R23", /*23*/ "R24", /*24*/ @@ -95,10 +95,49 @@ static const char * const bit_desc[] = { "R31", /*31*/ }; -static void dump_port_status_diff(u32 prev_status, u32 new_status) +static const char * const bit_desc_ss[] = { + "CONNECTION", /*0*/ + "ENABLE", /*1*/ + "SUSPEND", /*2*/ + "OVER_CURRENT", /*3*/ + "RESET",/*4*/ + "L1", /*5*/ + "R6", /*6*/ + "R7", /*7*/ + "R8", /*8*/ + "POWER",/*9*/ + "HIGHSPEED",/*10*/ + "PORT_TEST",/*11*/ + "INDICATOR",/*12*/ + "R13", /*13*/ + "R14", /*14*/ + "R15", /*15*/ + "C_CONNECTION", /*16*/ + "C_ENABLE", /*17*/ + "C_SUSPEND",/*18*/ + "C_OVER_CURRENT", /*19*/ + "C_RESET", /*20*/ + "C_BH_RESET", /*21*/ + "C_LINK_STATE", /*22*/ + "C_CONFIG_ERROR", /*23*/ + "R24", /*24*/ + "R25", /*25*/ + "R26", /*26*/ + "R27", /*27*/ + "R28", /*28*/ + "R29", /*29*/ + "R30", /*30*/ + "R31", /*31*/ +}; + +static void dump_port_status_diff(u32 prev_status, u32 new_status, bool usb3) { int i = 0; u32 bit = 1; + const char * const *desc = bit_desc; + + if (usb3) + desc = bit_desc_ss; pr_debug("status prev -> new: %08x -> %08x\n", prev_status, new_status); while (bit) { @@ -113,8 +152,12 @@ static void dump_port_status_diff(u32 prev_status, u32 new_status) else change = ' '; - if (prev || new) - pr_debug(" %c%s\n", change, bit_desc[i]); + if (prev || new) { + pr_debug(" %c%s\n", change, desc[i]); + + if (bit == 1) /* USB_PORT_STAT_CONNECTION */ + pr_debug(" %c%s\n", change, "USB_PORT_STAT_SPEED_5GBPS"); + } bit <<= 1; i++; } @@ -563,7 +606,8 @@ 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], - vhci_hcd->port_status[rhport]); + vhci_hcd->port_status[rhport], + hcd->speed == HCD_USB3); } } usbip_dbg_vhci_rh(" bye\n"); -- 2.7.4 -- 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
[PATCH v2 2/9] usbip: vhci-hcd: Add vhci struct
From: Yuyang Du <yuyang...@intel.com> In order to support SuperSpeed devices, a USB3 HCD is added to share the USB2 HCD. As a result, a VHCI is composed of two vhci_hcds associated with the two HCDs respectively. So we add another level of abstraction, vhci, and thus this vhci structure. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index bff472f..9959584 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -87,8 +87,17 @@ struct vhci_unlink { #define MAX_STATUS_NAME 16 -/* for usb_bus.hcpriv */ +struct vhci { + spinlock_t lock; + + struct vhci_hcd *vhci_hcd_hs; + struct vhci_hcd *vhci_hcd_ss; +}; + +/* for usb_hcd.hcd_priv[0] */ struct vhci_hcd { + struct vhci *vhci; + spinlock_t lock; u32 port_status[VHCI_HC_PORTS]; @@ -108,6 +117,7 @@ struct vhci_hcd { extern int vhci_num_controllers; extern struct platform_device **vhci_pdevs; +extern struct vhci *vhcis; extern struct attribute_group vhci_attr_group; /* vhci_hcd.c */ -- 2.7.4 -- 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
[PATCH v2 9/9] usbip: vhci-hcd: Clean up the code by adding a new macro
From: Yuyang Du <yuyang...@intel.com> Each vhci has 2*VHCI_HC_PORTS ports, in which VHCI_HC_PORTS ports are HighSpeed (or below), and VHCI_HC_PORTS are SuperSpeed. This new macro VHCI_PORTS reflects this configuration. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 5 - drivers/usb/usbip/vhci_sysfs.c | 10 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index db28eb5..5cfb59e 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -84,6 +84,9 @@ enum hub_speed { #define VHCI_HC_PORTS 8 #endif +/* Each VHCI has 2 hubs (USB2 and USB3), each has VHCI_HC_PORTS ports */ +#define VHCI_PORTS (VHCI_HC_PORTS*2) + #ifdef CONFIG_USBIP_VHCI_NR_HCS #define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS #else @@ -145,7 +148,7 @@ static inline __u32 port_to_rhport(__u32 port) static inline int port_to_pdev_nr(__u32 port) { - return port / (VHCI_HC_PORTS * 2); + return port / VHCI_PORTS; } static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 3ad68ff..5778b64 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -92,7 +92,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out) spin_lock(>ud.lock); port_show_vhci(, HUB_SPEED_HIGH, - pdev_nr * VHCI_HC_PORTS * 2 + i, vdev); + pdev_nr * VHCI_PORTS + i, vdev); spin_unlock(>ud.lock); } @@ -101,7 +101,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out) spin_lock(>ud.lock); port_show_vhci(, HUB_SPEED_SUPER, - pdev_nr * VHCI_HC_PORTS * 2 + VHCI_HC_PORTS + i, vdev); + pdev_nr * VHCI_PORTS + VHCI_HC_PORTS + i, vdev); spin_unlock(>ud.lock); } @@ -117,7 +117,7 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out) for (i = 0; i < VHCI_HC_PORTS; i++) { out += sprintf(out, "hs %04u %03u ", - (pdev_nr * VHCI_HC_PORTS * 2) + i, + (pdev_nr * VHCI_PORTS) + i, VDEV_ST_NOTASSIGNED); out += sprintf(out, "000 0-0"); out += sprintf(out, "\n"); @@ -125,7 +125,7 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out) for (i = 0; i < VHCI_HC_PORTS; i++) { out += sprintf(out, "ss %04u %03u ", - (pdev_nr * VHCI_HC_PORTS * 2) + VHCI_HC_PORTS + i, + (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i, VDEV_ST_NOTASSIGNED); out += sprintf(out, "000 0-0"); out += sprintf(out, "\n"); @@ -176,7 +176,7 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr, /* * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2. */ - out += sprintf(out, "%d\n", VHCI_HC_PORTS * vhci_num_controllers * 2); + out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); return out - s; } static DEVICE_ATTR_RO(nports); -- 2.7.4 -- 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
[PATCH v2 1/9] usbip: vhci-hcd: Rename function names to reflect their struct names
From: Yuyang Du <yuyang...@intel.com> These helper function names are renamed to have their full struct names to avoid confusion: - hcd_to_vhci() -> hcd_to_vhci_hcd() - vhci_to_hcd() -> vhci_hcd_to_hcd() - vdev_to_vhci() -> vdev_to_vhci_hcd() Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 11 +-- drivers/usb/usbip/vhci_hcd.c | 34 +- drivers/usb/usbip/vhci_rx.c| 12 ++-- drivers/usb/usbip/vhci_sysfs.c | 6 +++--- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..bff472f 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -134,7 +134,7 @@ static inline int port_to_pdev_nr(__u32 port) return port / VHCI_HC_PORTS; } -static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) +static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) { return (struct vhci_hcd *) (hcd->hcd_priv); } @@ -149,15 +149,14 @@ static inline const char *hcd_name(struct usb_hcd *hcd) return (hcd)->self.bus_name; } -static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci) +static inline struct usb_hcd *vhci_hcd_to_hcd(struct vhci_hcd *vhci_hcd) { - return container_of((void *) vhci, struct usb_hcd, hcd_priv); + return container_of((void *) vhci_hcd, struct usb_hcd, hcd_priv); } -static inline struct vhci_hcd *vdev_to_vhci(struct vhci_device *vdev) +static inline struct vhci_hcd *vdev_to_vhci_hcd(struct vhci_device *vdev) { - return container_of( - (void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); + return container_of((void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); } #endif /* __USBIP_VHCI_H */ diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 5d8b2c2..624265a 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -124,7 +124,7 @@ 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(vdev); + struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev); int rhport = vdev->rhport; u32 status; unsigned long flags; @@ -152,12 +152,12 @@ void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed) spin_unlock_irqrestore(>lock, flags); - usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); + usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci)); } static void rh_port_disconnect(struct vhci_device *vdev) { - struct vhci_hcd *vhci = vdev_to_vhci(vdev); + struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev); int rhport = vdev->rhport; u32 status; unsigned long flags; @@ -174,7 +174,7 @@ static void rh_port_disconnect(struct vhci_device *vdev) vhci->port_status[rhport] = status; spin_unlock_irqrestore(>lock, flags); - usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); + usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci)); } #define PORT_C_MASK\ @@ -206,7 +206,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) retval = DIV_ROUND_UP(VHCI_HC_PORTS + 1, 8); memset(buf, 0, retval); - vhci = hcd_to_vhci(hcd); + vhci = hcd_to_vhci_hcd(hcd); spin_lock_irqsave(>lock, flags); if (!HCD_HW_ACCESSIBLE(hcd)) { @@ -268,7 +268,7 @@ 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); + dum = hcd_to_vhci_hcd(hcd); spin_lock_irqsave(>lock, flags); @@ -440,7 +440,7 @@ static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) pr_err("could not get virtual device"); return; } - vhci = vdev_to_vhci(vdev); + vhci = vdev_to_vhci_hcd(vdev); priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); if (!priv) { @@ -468,7 +468,7 @@ 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); + struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd); struct device *dev = >dev->dev; u8 portnum = urb->dev->portnum; int ret = 0; @@ -635,7 +635,7 @@ 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); + struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd);
[PATCH v2 3/9] usbip: vhci-hcd: Move VHCI platform device into vhci struct
From: Yuyang Du <yuyang...@intel.com> Every VHCI is a platform device, so move the platform_device struct into the VHCI struct. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 3 ++- drivers/usb/usbip/vhci_hcd.c | 17 - drivers/usb/usbip/vhci_sysfs.c | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 9959584..62ee537 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -90,6 +90,8 @@ struct vhci_unlink { struct vhci { spinlock_t lock; + struct platform_device *pdev; + struct vhci_hcd *vhci_hcd_hs; struct vhci_hcd *vhci_hcd_ss; }; @@ -116,7 +118,6 @@ struct vhci_hcd { }; extern int vhci_num_controllers; -extern struct platform_device **vhci_pdevs; extern struct vhci *vhcis; extern struct attribute_group vhci_attr_group; diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 624265a..7a04497 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -58,8 +58,7 @@ static const char driver_name[] = "vhci_hcd"; static const char driver_desc[] = "USB/IP Virtual Host Controller"; int vhci_num_controllers = VHCI_NR_HCS; - -struct platform_device **vhci_pdevs; +struct vhci *vhcis; static const char * const bit_desc[] = { "CONNECTION", /*0*/ @@ -1188,7 +1187,7 @@ static int add_platform_device(int id) if (IS_ERR(pdev)) return PTR_ERR(pdev); - *(vhci_pdevs + id) = pdev; + vhcis[id].pdev = pdev; return 0; } @@ -1198,10 +1197,10 @@ static void del_platform_devices(void) int i; for (i = 0; i < vhci_num_controllers; i++) { - pdev = *(vhci_pdevs + i); + pdev = vhcis[i].pdev; if (pdev != NULL) platform_device_unregister(pdev); - *(vhci_pdevs + i) = NULL; + vhcis[i].pdev = NULL; } sysfs_remove_link(_bus.kobj, driver_name); } @@ -1216,8 +1215,8 @@ static int __init vhci_hcd_init(void) if (vhci_num_controllers < 1) vhci_num_controllers = 1; - vhci_pdevs = kcalloc(vhci_num_controllers, sizeof(void *), GFP_KERNEL); - if (vhci_pdevs == NULL) + vhcis = kcalloc(vhci_num_controllers, sizeof(struct vhci), GFP_KERNEL); + if (vhcis == NULL) return -ENOMEM; ret = platform_driver_register(_driver); @@ -1237,7 +1236,7 @@ static int __init vhci_hcd_init(void) del_platform_devices(); platform_driver_unregister(_driver); err_driver_register: - kfree(vhci_pdevs); + kfree(vhcis); return ret; } @@ -1245,7 +1244,7 @@ static void __exit vhci_hcd_exit(void) { del_platform_devices(); platform_driver_unregister(_driver); - kfree(vhci_pdevs); + kfree(vhcis); } module_init(vhci_hcd_init); diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index d878faa..07f0d37 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -32,7 +32,7 @@ /* Sysfs entry to show port status */ static ssize_t status_show_vhci(int pdev_nr, char *out) { - struct platform_device *pdev = *(vhci_pdevs + pdev_nr); + struct platform_device *pdev = vhcis[pdev_nr].pdev; struct vhci_hcd *vhci; char *s = out; int i = 0; @@ -206,7 +206,7 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr, if (!valid_port(pdev_nr, rhport)) return -EINVAL; - hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr)); + hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); if (hcd == NULL) { dev_err(dev, "port is not ready %u\n", port); return -EAGAIN; @@ -287,7 +287,7 @@ 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)); + hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); if (hcd == NULL) { dev_err(dev, "port %d is not ready\n", port); return -EAGAIN; -- 2.7.4 -- 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
[PATCH v2 4/9] usbip: vhci-hcd: Rework vhci_hcd_init
From: Yuyang Du <yuyang...@intel.com> A vhci struct is added as the platform-specific data to the vhci platform device, in order to get the vhci by its platform device. This is done in vhci_hcd_init(). Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 51 tools/usb/usbip/libsrc/vhci_driver.c | 2 +- tools/usb/usbip/libsrc/vhci_driver.h | 1 + 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 7a04497..2bc77ee 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1173,24 +1173,6 @@ static struct platform_driver vhci_driver = { }, }; -static int add_platform_device(int id) -{ - struct platform_device *pdev; - int dev_nr; - - if (id == 0) - dev_nr = -1; - else - dev_nr = id; - - pdev = platform_device_register_simple(driver_name, dev_nr, NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - vhcis[id].pdev = pdev; - return 0; -} - static void del_platform_devices(void) { struct platform_device *pdev; @@ -1219,23 +1201,46 @@ static int __init vhci_hcd_init(void) if (vhcis == NULL) return -ENOMEM; + for (i = 0; i < vhci_num_controllers; i++) { + vhcis[i].pdev = platform_device_alloc(driver_name, i); + if (!vhcis[i].pdev) { + i--; + while (i >= 0) + platform_device_put(vhcis[i--].pdev); + ret = -ENOMEM; + goto err_device_alloc; + } + } + for (i = 0; i < vhci_num_controllers; i++) { + void *vhci = [i]; + ret = platform_device_add_data(vhcis[i].pdev, , sizeof(void *)); + if (ret) + goto err_driver_register; + } + ret = platform_driver_register(_driver); if (ret) goto err_driver_register; for (i = 0; i < vhci_num_controllers; i++) { - ret = add_platform_device(i); - if (ret) - goto err_platform_device_register; + ret = platform_device_add(vhcis[i].pdev); + if (ret < 0) { + i--; + while (i >= 0) + platform_device_del(vhcis[i--].pdev); + goto err_add_hcd; + } } pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; -err_platform_device_register: - del_platform_devices(); +err_add_hcd: platform_driver_unregister(_driver); err_driver_register: + for (i = 0; i < vhci_num_controllers; i++) + platform_device_put(vhcis[i].pdev); +err_device_alloc: kfree(vhcis); return ret; } diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index af88447..5b19a32 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -248,7 +248,7 @@ int usbip_vhci_driver_open(void) vhci_driver->hc_device = udev_device_new_from_subsystem_sysname(udev_context, USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); + USBIP_VHCI_DEVICE_NAME); if (!vhci_driver->hc_device) { err("udev_device_new_from_subsystem_sysname failed"); goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 33add14..dfe19c1 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -11,6 +11,7 @@ #include "usbip_common.h" #define USBIP_VHCI_BUS_TYPE "platform" +#define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" #define MAXNPORT 128 struct usbip_imported_device { -- 2.7.4 -- 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
[PATCH v2 0/9] usbip: Enable USB3 SuperSpeed
Hi Shuah, SuperSpeed (only) USB devices cannot be shared via usbip. This patch series attempts to fix it. The first 5 patches refactors the existing code to prepare for the SuperSpeed addition. With this series, our SuperSpeed device works fine. Many thanks to Greg and Krzysztof for their patience to answer my non-usb-professional questions, and special thanks to Krzysztof for the pointer to the SuperSpeed patch in dummy_hcd. This series is based on the series: "usb: usbip: Fix ports and port status v3" (https://www.spinics.net/lists/linux-usb/msg155834.html). v2: - Remove set_link_state() since it is not used Regards, Yuyang -- Yuyang Du (9): usbip: vhci-hcd: Rename function names to reflect their struct names usbip: vhci-hcd: Add vhci struct usbip: vhci-hcd: Move VHCI platform device into vhci struct usbip: vhci-hcd: Rework vhci_hcd_init usbip: vhci-hcd: Set the vhci structure up to work usbip: vhci-hcd: Add USB3 SuperSpeed support usbip: Add USB_SPEED_SUPER as valid arg usbip: vhci-hcd: Add USB3 port status bits usbip: vhci-hcd: Clean up the code by adding a new macro drivers/usb/usbip/vhci.h | 36 ++- drivers/usb/usbip/vhci_hcd.c | 605 +-- drivers/usb/usbip/vhci_rx.c | 16 +- drivers/usb/usbip/vhci_sysfs.c | 138 +--- tools/usb/usbip/libsrc/vhci_driver.c | 25 +- tools/usb/usbip/libsrc/vhci_driver.h | 9 +- tools/usb/usbip/src/usbip_attach.c | 3 +- 7 files changed, 601 insertions(+), 231 deletions(-) -- 2.7.4 -- 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
[PATCH v2 7/9] usbip: Add USB_SPEED_SUPER as valid arg
From: Yuyang Du <yuyang...@intel.com> With this patch, USB_SPEED_SUPER is a valid speed when attaching a USB3 SuperSpeed device. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index cac2319..3ad68ff 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -277,6 +277,7 @@ static int valid_args(__u32 pdev_nr, __u32 rhport, enum usb_device_speed speed) case USB_SPEED_FULL: case USB_SPEED_HIGH: case USB_SPEED_WIRELESS: + case USB_SPEED_SUPER: break; default: pr_err("Failed attach request for unsupported USB speed: %s\n", -- 2.7.4 -- 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
[PATCH v2 5/9] usbip: vhci-hcd: Set the vhci structure up to work
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> --- 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(>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(>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(>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(>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(>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(&
[PATCH v2 6/9] usbip: vhci-hcd: Add USB3 SuperSpeed support
From: Yuyang Du <yuyang...@intel.com> This patch adds a USB3 HCD to an existing USB2 HCD and provides the support of SuperSpeed, in case the device can only be enumerated with SuperSpeed. The bulk of the added code in usb3_bos_desc and hub_control to support SuperSpeed is borrowed from the commit 1cd8fd2887e162ad ("usb: gadget: dummy_hcd: add SuperSpeed support"). With this patch, each vhci will have VHCI_HC_PORTS HighSpeed ports and VHCI_HC_PORTS SuperSpeed ports. Suggested-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Signed-off-by: Yuyang Du <yuyang...@linux.intel.com> --- drivers/usb/usbip/vhci.h | 7 +- drivers/usb/usbip/vhci_hcd.c | 323 --- drivers/usb/usbip/vhci_sysfs.c | 109 tools/usb/usbip/libsrc/vhci_driver.c | 23 ++- tools/usb/usbip/libsrc/vhci_driver.h | 8 +- tools/usb/usbip/src/usbip_attach.c | 3 +- 6 files changed, 370 insertions(+), 103 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 8a979fc..db28eb5 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -72,6 +72,11 @@ struct vhci_unlink { unsigned long unlink_seqnum; }; +enum hub_speed { + HUB_SPEED_HIGH = 0, + HUB_SPEED_SUPER, +}; + /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ #ifdef CONFIG_USBIP_VHCI_HC_PORTS #define VHCI_HC_PORTS CONFIG_USBIP_VHCI_HC_PORTS @@ -140,7 +145,7 @@ static inline __u32 port_to_rhport(__u32 port) static inline int port_to_pdev_nr(__u32 port) { - return port / VHCI_HC_PORTS; + return port / (VHCI_HC_PORTS * 2); } static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 8cfba1d..43cacbc 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -232,6 +232,40 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) return changed ? retval : 0; } +/* usb 3.0 root hub device descriptor */ +static struct { + struct usb_bos_descriptor bos; + struct usb_ss_cap_descriptor ss_cap; +} __packed usb3_bos_desc = { + + .bos = { + .bLength= USB_DT_BOS_SIZE, + .bDescriptorType= USB_DT_BOS, + .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), + .bNumDeviceCaps = 1, + }, + .ss_cap = { + .bLength= USB_DT_USB_SS_CAP_SIZE, + .bDescriptorType= USB_DT_DEVICE_CAPABILITY, + .bDevCapabilityType = USB_SS_CAP_TYPE, + .wSpeedSupported= cpu_to_le16(USB_5GBPS_OPERATION), + .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), + }, +}; + +static inline void +ss_hub_descriptor(struct usb_hub_descriptor *desc) +{ + memset(desc, 0, sizeof *desc); + desc->bDescriptorType = USB_DT_SS_HUB; + desc->bDescLength = 12; + desc->wHubCharacteristics = cpu_to_le16( + HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); + desc->bNbrPorts = VHCI_HC_PORTS; + desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/ + desc->u.ss.DeviceRemovable = 0x; +} + static inline void hub_descriptor(struct usb_hub_descriptor *desc) { memset(desc, 0, sizeof(*desc)); @@ -260,13 +294,15 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, /* * NOTE: -* wIndex shows the port number and begins from 1. +* wIndex (bits 0-7) shows the port number and begins from 1? */ + wIndex = ((__u8)(wIndex & 0x00ff)); usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex); + if (wIndex > VHCI_HC_PORTS) pr_err("invalid port number %d\n", wIndex); - rhport = ((__u8)(wIndex & 0x00ff)) - 1; + rhport = wIndex - 1; vhci_hcd = hcd_to_vhci_hcd(hcd); vhci = vhci_hcd->vhci; @@ -286,34 +322,26 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case ClearPortFeature: switch (wValue) { case USB_PORT_FEAT_SUSPEND: + if (hcd->speed == HCD_USB3) { + pr_err(" ClearPortFeature: USB_PORT_FEAT_SUSPEND req not " + "supported for USB 3.0 roothub\n"); + goto error; + } + usbip_dbg_vhci_rh( + " ClearPortFeature: USB_PORT_FEAT_SUSPEND\n"); if (vhci_hcd->port_status[rhport] & USB_PORT_STAT_SUSPEND) {
[PATCH resend v3 1/4] usb: usbip tool: Check the return of get_nports()
From: Yuyang Du <yuyang...@intel.com> If we get nonpositive number of ports, there is no sense to continue, then fail gracefully. In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: modifications to vhci driver") introduced configurable numbers of controllers and ports, but we have a static port number maximum, MAXNPORT. If exceeded, the idev array will be overflown. We fix it by validating the nports to make sure the port number max is not exceeded. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f659c14..151580a 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -220,9 +220,17 @@ int usbip_vhci_driver_open(void) } vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); + if (vhci_driver->nports <=0) { + err("no available ports"); + goto err; + } + else if (vhci_driver->nports > MAXNPORT) { + err("port number exceeds %d", MAXNPORT); + goto err; + } + if (refresh_imported_device_list()) goto err; -- 2.7.4 -- 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
[PATCH resend v3 4/4] usb: usbip tool: Fix parse_status()
From: Yuyang Du <yuyang...@intel.com> In parse_status(), all nports number of idev's are initiated to 0 by memset(), it is simply wrong, because parse_status() reads the status sys file one by one, therefore, it can only update the according vhci_driver->idev's for it to parse. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 38 ++-- tools/usb/usbip/src/usbip_attach.c | 2 ++ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ed2eba9..af88447 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -36,18 +36,11 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) return NULL; } - - static int parse_status(const char *value) { int ret = 0; char *c; - - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); - - /* skip a header line */ c = strchr(value, '\n'); if (!c) @@ -58,6 +51,7 @@ static int parse_status(const char *value) int port, status, speed, devid; unsigned long socket; char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; ret = sscanf(c, "%d %d %d %x %lx %31s\n", , , , @@ -72,30 +66,28 @@ static int parse_status(const char *value) port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; + idev = _driver->idev[port]; - idev->port = port; - idev->status= status; + memset(idev, 0, sizeof(*idev)); - idev->devid = devid; + idev->port = port; + idev->status= status; - idev->busnum= (devid >> 16); - idev->devnum= (devid & 0x); + idev->devid = devid; - if (idev->status != VDEV_ST_NULL - && idev->status != VDEV_ST_NOTASSIGNED) { - idev = imported_device_init(idev, lbusid); - if (!idev) { - dbg("imported_device_init failed"); - return -1; - } + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); + + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; } } - /* go to the next line */ c = strchr(c, '\n'); if (!c) diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..62a297f 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -108,6 +108,8 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } + dbg("got free port %d", port); + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, udev->devnum, udev->speed); if (rc < 0) { -- 2.7.4 -- 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
[PATCH resend v3 0/4] usb: usbip: Fix ports and port status
From: Yuyang Du <yuyang...@intel.com> The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced several bugs relating to the number of ports amd the port status. In addition, a small improvement is made to the vhci_hcd module. resend: - Remove already picked patches - Add a few *-bys v3: - Check both ends of the nports - Check the return of ncontrollers - Add a few Reviewed-bys and Acked-bys - Minor coding changes v2: - Remove ncontrollers RO attr as suggested by Krzysztof - As a result, scandir vhci_hcd* dir in platform to learn how many we have as suggested by Krzysztof - Minor coding changes Thanks, Yuyang -- Yuyang Du (4): usb: usbip tool: Check the return of get_nports() usb: usbip tool: Add ncontrollers in vhci_driver structure usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() tools/usb/usbip/libsrc/vhci_driver.c | 111 +-- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/usbip_attach.c | 2 + 3 files changed, 84 insertions(+), 30 deletions(-) -- 2.7.4 -- 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
[PATCH resend v3 2/4] usb: usbip tool: Add ncontrollers in vhci_driver structure
From: Yuyang Du <yuyang...@intel.com> A new field ncontrollers is added to the vhci_driver structure. And this field is stored by scanning the vhci_hcd* dirs in the platform udev. Suggested-and-reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 36 tools/usb/usbip/libsrc/vhci_driver.h | 1 + 2 files changed, 37 insertions(+) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 151580a..f019686 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -134,6 +135,33 @@ static int get_nports(void) return (int)strtoul(attr_nports, NULL, 10); } +static int vhci_hcd_filter(const struct dirent *dirent) +{ + return strcmp(dirent->d_name, "vhci_hcd") >= 0; +} + +static int get_ncontrollers(void) +{ + struct dirent **namelist; + struct udev_device *platform; + int n; + + platform = udev_device_get_parent(vhci_driver->hc_device); + if (platform == NULL) + return -1; + + n = scandir(udev_device_get_syspath(platform), , vhci_hcd_filter, NULL); + if (n < 0) + err("scandir failed"); + else { + for (int i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + } + + return n; +} + /* * Read the given port's record. * @@ -231,6 +259,14 @@ int usbip_vhci_driver_open(void) goto err; } + vhci_driver->ncontrollers = get_ncontrollers(); + dbg("available controllers: %d", vhci_driver->ncontrollers); + + if (vhci_driver->ncontrollers <=0) { + err("no available usb controllers"); + goto err; + } + if (refresh_imported_device_list()) goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..33add14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -31,6 +31,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; + int ncontrollers; int nports; struct usbip_imported_device idev[MAXNPORT]; }; -- 2.7.4 -- 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
[PATCH resend v3 3/4] usb: usbip tool: Fix refresh_imported_device_list()
From: Yuyang Du <yuyang...@intel.com> The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, but the status of the ports are only extracted from the first status file, fix it. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f019686..ed2eba9 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -108,18 +108,33 @@ static int parse_status(const char *value) return 0; } +#define MAX_STATUS_NAME 16 + static int refresh_imported_device_list(void) { const char *attr_status; + char status[MAX_STATUS_NAME+1] = "status"; + int i, ret; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); - return -1; + for (i = 0; i < vhci_driver->ncontrollers; i++) { + if (i > 0) + snprintf(status, sizeof(status), "status.%d", i); + + attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, + status); + if (!attr_status) { + err("udev_device_get_sysattr_value failed"); + return -1; + } + + dbg("controller %d", i); + + ret = parse_status(attr_status); + if (ret != 0) + return ret; } - return parse_status(attr_status); + return 0; } static int get_nports(void) -- 2.7.4 -- 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
Re: [PATCH 2/9] usbip: vhci-hcd: Add vhci struct
On Fri, Apr 14, 2017 at 11:29:14AM +0200, Oliver Neukum wrote: > > > what is the motivation for this change? That is the way XHCI > > > does it. But why do that when you export something over > > > a network? Are you ever going to use both VHCIs? > > > > I, a usbip client, could use a LowSpeed device and a SuperSpeed > > device from usbip host/hosts at the same time. Does that answer > > your question? > > Only partially, because the problem already exists if you use a > HighSpeed and a LowSpeed device. Then the question is whether we can have a single HCD that supports all speeds, which was my question, yet I haven't known the answer. As a result, I just followed the SuperSpeed patch implemented in dummy_hcd. Thanks, Yuyang -- 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
Re: [PATCH 2/9] usbip: vhci-hcd: Add vhci struct
Hi Oliver, > what is the motivation for this change? That is the way XHCI > does it. But why do that when you export something over > a network? Are you ever going to use both VHCIs? I, a usbip client, could use a LowSpeed device and a SuperSpeed device from usbip host/hosts at the same time. Does that answer your question? Thanks, Yuyang -- 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
[PATCH 9/9] usbip: vhci-hcd: Clean up the code by adding a new macro
Each vhci has 2*VHCI_HC_PORTS ports, in which VHCI_HC_PORTS ports are HighSpeed (or below), and VHCI_HC_PORTS are SuperSpeed. This new macro VHCI_PORTS reflects this configuration. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 5 - drivers/usb/usbip/vhci_sysfs.c | 10 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index db28eb5..5cfb59e 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -84,6 +84,9 @@ enum hub_speed { #define VHCI_HC_PORTS 8 #endif +/* Each VHCI has 2 hubs (USB2 and USB3), each has VHCI_HC_PORTS ports */ +#define VHCI_PORTS (VHCI_HC_PORTS*2) + #ifdef CONFIG_USBIP_VHCI_NR_HCS #define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS #else @@ -145,7 +148,7 @@ static inline __u32 port_to_rhport(__u32 port) static inline int port_to_pdev_nr(__u32 port) { - return port / (VHCI_HC_PORTS * 2); + return port / VHCI_PORTS; } static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 3ad68ff..5778b64 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -92,7 +92,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out) spin_lock(>ud.lock); port_show_vhci(, HUB_SPEED_HIGH, - pdev_nr * VHCI_HC_PORTS * 2 + i, vdev); + pdev_nr * VHCI_PORTS + i, vdev); spin_unlock(>ud.lock); } @@ -101,7 +101,7 @@ static ssize_t status_show_vhci(int pdev_nr, char *out) spin_lock(>ud.lock); port_show_vhci(, HUB_SPEED_SUPER, - pdev_nr * VHCI_HC_PORTS * 2 + VHCI_HC_PORTS + i, vdev); + pdev_nr * VHCI_PORTS + VHCI_HC_PORTS + i, vdev); spin_unlock(>ud.lock); } @@ -117,7 +117,7 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out) for (i = 0; i < VHCI_HC_PORTS; i++) { out += sprintf(out, "hs %04u %03u ", - (pdev_nr * VHCI_HC_PORTS * 2) + i, + (pdev_nr * VHCI_PORTS) + i, VDEV_ST_NOTASSIGNED); out += sprintf(out, "000 0-0"); out += sprintf(out, "\n"); @@ -125,7 +125,7 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out) for (i = 0; i < VHCI_HC_PORTS; i++) { out += sprintf(out, "ss %04u %03u ", - (pdev_nr * VHCI_HC_PORTS * 2) + VHCI_HC_PORTS + i, + (pdev_nr * VHCI_PORTS) + VHCI_HC_PORTS + i, VDEV_ST_NOTASSIGNED); out += sprintf(out, "000 0-0"); out += sprintf(out, "\n"); @@ -176,7 +176,7 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr, /* * Half the ports are for SPEED_HIGH and half for SPEED_SUPER, thus the * 2. */ - out += sprintf(out, "%d\n", VHCI_HC_PORTS * vhci_num_controllers * 2); + out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers); return out - s; } static DEVICE_ATTR_RO(nports); -- 2.7.4 -- 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
[PATCH 8/9] usbip: vhci-hcd: Add USB3 port status bits
As USB3 has (slightly) different bit meanings in the port status. Add a new status bit array for USB3. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 56 +++- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 019b268..e66a3c8 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -66,7 +66,7 @@ static const char * const bit_desc[] = { "SUSPEND", /*2*/ "OVER_CURRENT", /*3*/ "RESET",/*4*/ - "R5", /*5*/ + "L1", /*5*/ "R6", /*6*/ "R7", /*7*/ "POWER",/*8*/ @@ -82,7 +82,7 @@ static const char * const bit_desc[] = { "C_SUSPEND",/*18*/ "C_OVER_CURRENT", /*19*/ "C_RESET", /*20*/ - "R21", /*21*/ + "C_L1", /*21*/ "R22", /*22*/ "R23", /*23*/ "R24", /*24*/ @@ -95,10 +95,49 @@ static const char * const bit_desc[] = { "R31", /*31*/ }; -static void dump_port_status_diff(u32 prev_status, u32 new_status) +static const char * const bit_desc_ss[] = { + "CONNECTION", /*0*/ + "ENABLE", /*1*/ + "SUSPEND", /*2*/ + "OVER_CURRENT", /*3*/ + "RESET",/*4*/ + "L1", /*5*/ + "R6", /*6*/ + "R7", /*7*/ + "R8", /*8*/ + "POWER",/*9*/ + "HIGHSPEED",/*10*/ + "PORT_TEST",/*11*/ + "INDICATOR",/*12*/ + "R13", /*13*/ + "R14", /*14*/ + "R15", /*15*/ + "C_CONNECTION", /*16*/ + "C_ENABLE", /*17*/ + "C_SUSPEND",/*18*/ + "C_OVER_CURRENT", /*19*/ + "C_RESET", /*20*/ + "C_BH_RESET", /*21*/ + "C_LINK_STATE", /*22*/ + "C_CONFIG_ERROR", /*23*/ + "R24", /*24*/ + "R25", /*25*/ + "R26", /*26*/ + "R27", /*27*/ + "R28", /*28*/ + "R29", /*29*/ + "R30", /*30*/ + "R31", /*31*/ +}; + +static void dump_port_status_diff(u32 prev_status, u32 new_status, bool usb3) { int i = 0; u32 bit = 1; + const char * const *desc = bit_desc; + + if (usb3) + desc = bit_desc_ss; pr_debug("status prev -> new: %08x -> %08x\n", prev_status, new_status); while (bit) { @@ -113,8 +152,12 @@ static void dump_port_status_diff(u32 prev_status, u32 new_status) else change = ' '; - if (prev || new) - pr_debug(" %c%s\n", change, bit_desc[i]); + if (prev || new) { + pr_debug(" %c%s\n", change, desc[i]); + + if (bit == 1) /* USB_PORT_STAT_CONNECTION */ + pr_debug(" %c%s\n", change, "USB_PORT_STAT_SPEED_5GBPS"); + } bit <<= 1; i++; } @@ -577,7 +620,8 @@ 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], - vhci_hcd->port_status[rhport]); + vhci_hcd->port_status[rhport], + hcd->speed == HCD_USB3); } } usbip_dbg_vhci_rh(" bye\n"); -- 2.7.4 -- 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
[PATCH 0/9] usbip: Enable USB3 SuperSpeed
Hi Shuah, SuperSpeed (only) USB devices cannot be shared via usbip. This patch series attempts to fix it. The first 5 patches refactors the existing code to prepare for the SuperSpeed addition. With this series, our SuperSpeed device works fine. Many thanks to Greg and Krzysztof for their patience to answer my non-usb-professional questions, and special thanks to Krzysztof for the pointer to the SuperSpeed patch in dummy_hcd. This series is based on the series: "usb: usbip: Fix ports and port status v3" (https://www.spinics.net/lists/linux-usb/msg155834.html). Regards, Yuyang -- Yuyang Du (9): usbip: vhci-hcd: Rename function names to reflect their struct names usbip: vhci-hcd: Add vhci struct usbip: vhci-hcd: Move VHCI platform device into vhci struct usbip: vhci-hcd: Rework vhci_hcd_init usbip: vhci-hcd: Set the vhci structure up to work usbip: vhci-hcd: Add USB3 SuperSpeed support usbip: Add USB_SPEED_SUPER as valid arg usbip: vhci-hcd: Add USB3 port status bits usbip: vhci-hcd: Clean up the code by adding a new macro drivers/usb/usbip/vhci.h | 36 +- drivers/usb/usbip/vhci_hcd.c | 619 ++- drivers/usb/usbip/vhci_rx.c | 16 +- drivers/usb/usbip/vhci_sysfs.c | 138 +--- tools/usb/usbip/libsrc/vhci_driver.c | 25 +- tools/usb/usbip/libsrc/vhci_driver.h | 9 +- tools/usb/usbip/src/usbip_attach.c | 3 +- 7 files changed, 615 insertions(+), 231 deletions(-) -- 2.7.4 -- 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
[PATCH 6/9] usbip: vhci-hcd: Add USB3 SuperSpeed support
This patch adds a USB3 HCD to an existing USB2 HCD and provides the support of SuperSpeed, in case the device can only be enumerated with SuperSpeed. The bulk of the added code in usb3_bos_desc and hub_control to support SuperSpeed is borrowed from the commit 1cd8fd2887e162ad ("usb: gadget: dummy_hcd: add SuperSpeed support"). With this patch, each vhci will have VHCI_HC_PORTS HighSpeed ports and VHCI_HC_PORTS SuperSpeed ports. Suggested-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 7 +- drivers/usb/usbip/vhci_hcd.c | 337 --- drivers/usb/usbip/vhci_sysfs.c | 109 +++ tools/usb/usbip/libsrc/vhci_driver.c | 23 ++- tools/usb/usbip/libsrc/vhci_driver.h | 8 +- tools/usb/usbip/src/usbip_attach.c | 3 +- 6 files changed, 384 insertions(+), 103 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 8a979fc..db28eb5 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -72,6 +72,11 @@ struct vhci_unlink { unsigned long unlink_seqnum; }; +enum hub_speed { + HUB_SPEED_HIGH = 0, + HUB_SPEED_SUPER, +}; + /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ #ifdef CONFIG_USBIP_VHCI_HC_PORTS #define VHCI_HC_PORTS CONFIG_USBIP_VHCI_HC_PORTS @@ -140,7 +145,7 @@ static inline __u32 port_to_rhport(__u32 port) static inline int port_to_pdev_nr(__u32 port) { - return port / VHCI_HC_PORTS; + return port / (VHCI_HC_PORTS * 2); } static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 8cfba1d..019b268 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -232,6 +232,45 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) return changed ? retval : 0; } +/* caller must hold lock */ +static void set_link_state(struct vhci_hcd *vhci_hcd) +{ +} + +/* usb 3.0 root hub device descriptor */ +static struct { + struct usb_bos_descriptor bos; + struct usb_ss_cap_descriptor ss_cap; +} __packed usb3_bos_desc = { + + .bos = { + .bLength= USB_DT_BOS_SIZE, + .bDescriptorType= USB_DT_BOS, + .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), + .bNumDeviceCaps = 1, + }, + .ss_cap = { + .bLength= USB_DT_USB_SS_CAP_SIZE, + .bDescriptorType= USB_DT_DEVICE_CAPABILITY, + .bDevCapabilityType = USB_SS_CAP_TYPE, + .wSpeedSupported= cpu_to_le16(USB_5GBPS_OPERATION), + .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), + }, +}; + +static inline void +ss_hub_descriptor(struct usb_hub_descriptor *desc) +{ + memset(desc, 0, sizeof *desc); + desc->bDescriptorType = USB_DT_SS_HUB; + desc->bDescLength = 12; + desc->wHubCharacteristics = cpu_to_le16( + HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); + desc->bNbrPorts = VHCI_HC_PORTS; + desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/ + desc->u.ss.DeviceRemovable = 0x; +} + static inline void hub_descriptor(struct usb_hub_descriptor *desc) { memset(desc, 0, sizeof(*desc)); @@ -260,13 +299,15 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, /* * NOTE: -* wIndex shows the port number and begins from 1. +* wIndex (bits 0-7) shows the port number and begins from 1? */ + wIndex = ((__u8)(wIndex & 0x00ff)); usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex); + if (wIndex > VHCI_HC_PORTS) pr_err("invalid port number %d\n", wIndex); - rhport = ((__u8)(wIndex & 0x00ff)) - 1; + rhport = wIndex - 1; vhci_hcd = hcd_to_vhci_hcd(hcd); vhci = vhci_hcd->vhci; @@ -286,45 +327,58 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case ClearPortFeature: switch (wValue) { case USB_PORT_FEAT_SUSPEND: + if (hcd->speed == HCD_USB3) { + pr_err(" ClearPortFeature: USB_PORT_FEAT_SUSPEND req not " + "supported for USB 3.0 roothub\n"); + goto error; + } + usbip_dbg_vhci_rh( + " ClearPortFeature: USB_PORT_FEAT_SUSPEND\n"); if (vhci_hcd->port_status[rhport] & USB_PORT_STAT_SUSPEND) { /* 20
[PATCH 7/9] usbip: Add USB_SPEED_SUPER as valid arg
With this patch, USB_SPEED_SUPER is a valid speed when attaching a USB3 SuperSpeed device. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index cac2319..3ad68ff 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -277,6 +277,7 @@ static int valid_args(__u32 pdev_nr, __u32 rhport, enum usb_device_speed speed) case USB_SPEED_FULL: case USB_SPEED_HIGH: case USB_SPEED_WIRELESS: + case USB_SPEED_SUPER: break; default: pr_err("Failed attach request for unsupported USB speed: %s\n", -- 2.7.4 -- 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
[PATCH 5/9] usbip: vhci-hcd: Set the vhci structure up to work
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> --- 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(>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(>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(>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(>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(>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);
[PATCH 1/9] usbip: vhci-hcd: Rename function names to reflect their struct names
These helper function names are renamed to have their full struct names to avoid confusion: - hcd_to_vhci() -> hcd_to_vhci_hcd() - vhci_to_hcd() -> vhci_hcd_to_hcd() - vdev_to_vhci() -> vdev_to_vhci_hcd() Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 11 +-- drivers/usb/usbip/vhci_hcd.c | 34 +- drivers/usb/usbip/vhci_rx.c| 12 ++-- drivers/usb/usbip/vhci_sysfs.c | 6 +++--- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..bff472f 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -134,7 +134,7 @@ static inline int port_to_pdev_nr(__u32 port) return port / VHCI_HC_PORTS; } -static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) +static inline struct vhci_hcd *hcd_to_vhci_hcd(struct usb_hcd *hcd) { return (struct vhci_hcd *) (hcd->hcd_priv); } @@ -149,15 +149,14 @@ static inline const char *hcd_name(struct usb_hcd *hcd) return (hcd)->self.bus_name; } -static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci) +static inline struct usb_hcd *vhci_hcd_to_hcd(struct vhci_hcd *vhci_hcd) { - return container_of((void *) vhci, struct usb_hcd, hcd_priv); + return container_of((void *) vhci_hcd, struct usb_hcd, hcd_priv); } -static inline struct vhci_hcd *vdev_to_vhci(struct vhci_device *vdev) +static inline struct vhci_hcd *vdev_to_vhci_hcd(struct vhci_device *vdev) { - return container_of( - (void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); + return container_of((void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); } #endif /* __USBIP_VHCI_H */ diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 5d8b2c2..624265a 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -124,7 +124,7 @@ 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(vdev); + struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev); int rhport = vdev->rhport; u32 status; unsigned long flags; @@ -152,12 +152,12 @@ void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed) spin_unlock_irqrestore(>lock, flags); - usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); + usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci)); } static void rh_port_disconnect(struct vhci_device *vdev) { - struct vhci_hcd *vhci = vdev_to_vhci(vdev); + struct vhci_hcd *vhci = vdev_to_vhci_hcd(vdev); int rhport = vdev->rhport; u32 status; unsigned long flags; @@ -174,7 +174,7 @@ static void rh_port_disconnect(struct vhci_device *vdev) vhci->port_status[rhport] = status; spin_unlock_irqrestore(>lock, flags); - usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); + usb_hcd_poll_rh_status(vhci_hcd_to_hcd(vhci)); } #define PORT_C_MASK\ @@ -206,7 +206,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) retval = DIV_ROUND_UP(VHCI_HC_PORTS + 1, 8); memset(buf, 0, retval); - vhci = hcd_to_vhci(hcd); + vhci = hcd_to_vhci_hcd(hcd); spin_lock_irqsave(>lock, flags); if (!HCD_HW_ACCESSIBLE(hcd)) { @@ -268,7 +268,7 @@ 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); + dum = hcd_to_vhci_hcd(hcd); spin_lock_irqsave(>lock, flags); @@ -440,7 +440,7 @@ static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) pr_err("could not get virtual device"); return; } - vhci = vdev_to_vhci(vdev); + vhci = vdev_to_vhci_hcd(vdev); priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); if (!priv) { @@ -468,7 +468,7 @@ 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); + struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd); struct device *dev = >dev->dev; u8 portnum = urb->dev->portnum; int ret = 0; @@ -635,7 +635,7 @@ 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); + struct vhci_hcd *vhci = hcd_to_vhci_hcd(hcd); struct vhci_priv *priv; s
[PATCH 2/9] usbip: vhci-hcd: Add vhci struct
In order to support SuperSpeed devices, a USB3 HCD is added to share the USB2 HCD. As a result, a "VHCI" is composed of two vhci_hcds associated with the two HCDs respectively. So we add another level of abstraction, vhci, and thus this vhci structure. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index bff472f..9959584 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -87,8 +87,17 @@ struct vhci_unlink { #define MAX_STATUS_NAME 16 -/* for usb_bus.hcpriv */ +struct vhci { + spinlock_t lock; + + struct vhci_hcd *vhci_hcd_hs; + struct vhci_hcd *vhci_hcd_ss; +}; + +/* for usb_hcd.hcd_priv[0] */ struct vhci_hcd { + struct vhci *vhci; + spinlock_t lock; u32 port_status[VHCI_HC_PORTS]; @@ -108,6 +117,7 @@ struct vhci_hcd { extern int vhci_num_controllers; extern struct platform_device **vhci_pdevs; +extern struct vhci *vhcis; extern struct attribute_group vhci_attr_group; /* vhci_hcd.c */ -- 2.7.4 -- 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
[PATCH 3/9] usbip: vhci-hcd: Move VHCI platform device into vhci struct
Every VHCI is a platform device, so move the platform_device struct into the VHCI struct. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci.h | 3 ++- drivers/usb/usbip/vhci_hcd.c | 17 - drivers/usb/usbip/vhci_sysfs.c | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 9959584..62ee537 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -90,6 +90,8 @@ struct vhci_unlink { struct vhci { spinlock_t lock; + struct platform_device *pdev; + struct vhci_hcd *vhci_hcd_hs; struct vhci_hcd *vhci_hcd_ss; }; @@ -116,7 +118,6 @@ struct vhci_hcd { }; extern int vhci_num_controllers; -extern struct platform_device **vhci_pdevs; extern struct vhci *vhcis; extern struct attribute_group vhci_attr_group; diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 624265a..7a04497 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -58,8 +58,7 @@ static const char driver_name[] = "vhci_hcd"; static const char driver_desc[] = "USB/IP Virtual Host Controller"; int vhci_num_controllers = VHCI_NR_HCS; - -struct platform_device **vhci_pdevs; +struct vhci *vhcis; static const char * const bit_desc[] = { "CONNECTION", /*0*/ @@ -1188,7 +1187,7 @@ static int add_platform_device(int id) if (IS_ERR(pdev)) return PTR_ERR(pdev); - *(vhci_pdevs + id) = pdev; + vhcis[id].pdev = pdev; return 0; } @@ -1198,10 +1197,10 @@ static void del_platform_devices(void) int i; for (i = 0; i < vhci_num_controllers; i++) { - pdev = *(vhci_pdevs + i); + pdev = vhcis[i].pdev; if (pdev != NULL) platform_device_unregister(pdev); - *(vhci_pdevs + i) = NULL; + vhcis[i].pdev = NULL; } sysfs_remove_link(_bus.kobj, driver_name); } @@ -1216,8 +1215,8 @@ static int __init vhci_hcd_init(void) if (vhci_num_controllers < 1) vhci_num_controllers = 1; - vhci_pdevs = kcalloc(vhci_num_controllers, sizeof(void *), GFP_KERNEL); - if (vhci_pdevs == NULL) + vhcis = kcalloc(vhci_num_controllers, sizeof(struct vhci), GFP_KERNEL); + if (vhcis == NULL) return -ENOMEM; ret = platform_driver_register(_driver); @@ -1237,7 +1236,7 @@ static int __init vhci_hcd_init(void) del_platform_devices(); platform_driver_unregister(_driver); err_driver_register: - kfree(vhci_pdevs); + kfree(vhcis); return ret; } @@ -1245,7 +1244,7 @@ static void __exit vhci_hcd_exit(void) { del_platform_devices(); platform_driver_unregister(_driver); - kfree(vhci_pdevs); + kfree(vhcis); } module_init(vhci_hcd_init); diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index d878faa..07f0d37 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -32,7 +32,7 @@ /* Sysfs entry to show port status */ static ssize_t status_show_vhci(int pdev_nr, char *out) { - struct platform_device *pdev = *(vhci_pdevs + pdev_nr); + struct platform_device *pdev = vhcis[pdev_nr].pdev; struct vhci_hcd *vhci; char *s = out; int i = 0; @@ -206,7 +206,7 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr, if (!valid_port(pdev_nr, rhport)) return -EINVAL; - hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr)); + hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); if (hcd == NULL) { dev_err(dev, "port is not ready %u\n", port); return -EAGAIN; @@ -287,7 +287,7 @@ 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)); + hcd = platform_get_drvdata(vhcis[pdev_nr].pdev); if (hcd == NULL) { dev_err(dev, "port %d is not ready\n", port); return -EAGAIN; -- 2.7.4 -- 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
[PATCH 4/9] usbip: vhci-hcd: Rework vhci_hcd_init
A vhci struct is added as the platform-specific data to the vhci platform device, in order to get the vhci by its platform device. This is done in vhci_hcd_init(). Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 51 tools/usb/usbip/libsrc/vhci_driver.c | 2 +- tools/usb/usbip/libsrc/vhci_driver.h | 1 + 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 7a04497..2bc77ee 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1173,24 +1173,6 @@ static struct platform_driver vhci_driver = { }, }; -static int add_platform_device(int id) -{ - struct platform_device *pdev; - int dev_nr; - - if (id == 0) - dev_nr = -1; - else - dev_nr = id; - - pdev = platform_device_register_simple(driver_name, dev_nr, NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - vhcis[id].pdev = pdev; - return 0; -} - static void del_platform_devices(void) { struct platform_device *pdev; @@ -1219,23 +1201,46 @@ static int __init vhci_hcd_init(void) if (vhcis == NULL) return -ENOMEM; + for (i = 0; i < vhci_num_controllers; i++) { + vhcis[i].pdev = platform_device_alloc(driver_name, i); + if (!vhcis[i].pdev) { + i--; + while (i >= 0) + platform_device_put(vhcis[i--].pdev); + ret = -ENOMEM; + goto err_device_alloc; + } + } + for (i = 0; i < vhci_num_controllers; i++) { + void *vhci = [i]; + ret = platform_device_add_data(vhcis[i].pdev, , sizeof(void *)); + if (ret) + goto err_driver_register; + } + ret = platform_driver_register(_driver); if (ret) goto err_driver_register; for (i = 0; i < vhci_num_controllers; i++) { - ret = add_platform_device(i); - if (ret) - goto err_platform_device_register; + ret = platform_device_add(vhcis[i].pdev); + if (ret < 0) { + i--; + while (i >= 0) + platform_device_del(vhcis[i--].pdev); + goto err_add_hcd; + } } pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; -err_platform_device_register: - del_platform_devices(); +err_add_hcd: platform_driver_unregister(_driver); err_driver_register: + for (i = 0; i < vhci_num_controllers; i++) + platform_device_put(vhcis[i].pdev); +err_device_alloc: kfree(vhcis); return ret; } diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index af88447..5b19a32 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -248,7 +248,7 @@ int usbip_vhci_driver_open(void) vhci_driver->hc_device = udev_device_new_from_subsystem_sysname(udev_context, USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); + USBIP_VHCI_DEVICE_NAME); if (!vhci_driver->hc_device) { err("udev_device_new_from_subsystem_sysname failed"); goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 33add14..dfe19c1 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -11,6 +11,7 @@ #include "usbip_common.h" #define USBIP_VHCI_BUS_TYPE "platform" +#define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" #define MAXNPORT 128 struct usbip_imported_device { -- 2.7.4 -- 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
Re: [PATCH v3 3/6] usb: usbip tool: Check the return of get_nports()
On Tue, Apr 11, 2017 at 08:51:13AM -0600, Shuah Khan wrote: > > Please bear with me. I was out sick most of last week. till catching Hope you are all well now :) > Could you please pick this up. > > Acked-by: Shuah KhanThanks, Shuah. Yuyang -- 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
Re: [PATCH v3 3/6] usb: usbip tool: Check the return of get_nports()
Hi Greg, On Tue, Apr 11, 2017 at 04:13:50PM +0200, Greg KH wrote: > > Please send patches out, no need to wait, I'll just wait to apply them > for the review, you can always build on top of previous series. Got it. Thank you. Yuyang -- 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
Re: [PATCH v3 3/6] usb: usbip tool: Check the return of get_nports()
Hi Shuah, Could you please take a look at these patches? I got more patches that sit on these to send out. Thanks, Yuyang On Thu, Apr 06, 2017 at 06:03:24AM +0800, Yuyang Du wrote: > If we get nonpositive number of ports, there is no sense to > continue, then fail gracefully. > > In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: > modifications to vhci driver") introduced configurable numbers of > controllers and ports, but we have a static port number maximum, > MAXNPORT. If exceeded, the idev array will be overflown. We fix > it by validating the nports to make sure the port number max is > not exceeded. > > Signed-off-by: Yuyang Du <yuyang...@intel.com> > --- > tools/usb/usbip/libsrc/vhci_driver.c | 10 +- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/tools/usb/usbip/libsrc/vhci_driver.c > b/tools/usb/usbip/libsrc/vhci_driver.c > index f659c14..151580a 100644 > --- a/tools/usb/usbip/libsrc/vhci_driver.c > +++ b/tools/usb/usbip/libsrc/vhci_driver.c > @@ -220,9 +220,17 @@ int usbip_vhci_driver_open(void) > } > > vhci_driver->nports = get_nports(); > - > dbg("available ports: %d", vhci_driver->nports); > > + if (vhci_driver->nports <=0) { > + err("no available ports"); > + goto err; > + } > + else if (vhci_driver->nports > MAXNPORT) { > + err("port number exceeds %d", MAXNPORT); > + goto err; > + } > + > if (refresh_imported_device_list()) > goto err; > > -- > 2.7.4 -- 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
Re: [PATCH v3 3/6] usb: usbip tool: Check the return of get_nports()
On Fri, Apr 07, 2017 at 03:41:37PM +0200, Krzysztof Opasiak wrote: > > > On 04/06/2017 12:03 AM, Yuyang Du wrote: > >If we get nonpositive number of ports, there is no sense to > >continue, then fail gracefully. > > > >In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: > >modifications to vhci driver") introduced configurable numbers of > >controllers and ports, but we have a static port number maximum, > >MAXNPORT. If exceeded, the idev array will be overflown. We fix > >it by validating the nports to make sure the port number max is > >not exceeded. > > > >Signed-off-by: Yuyang Du <yuyang...@intel.com> > >--- > > tools/usb/usbip/libsrc/vhci_driver.c | 10 +- > > 1 file changed, 9 insertions(+), 1 deletion(-) > > > >diff --git a/tools/usb/usbip/libsrc/vhci_driver.c > >b/tools/usb/usbip/libsrc/vhci_driver.c > >index f659c14..151580a 100644 > >--- a/tools/usb/usbip/libsrc/vhci_driver.c > >+++ b/tools/usb/usbip/libsrc/vhci_driver.c > >@@ -220,9 +220,17 @@ int usbip_vhci_driver_open(void) > > } > > > > vhci_driver->nports = get_nports(); > >- > > dbg("available ports: %d", vhci_driver->nports); > > > >+if (vhci_driver->nports <=0) { > >+err("no available ports"); > >+goto err; > >+} > >+else if (vhci_driver->nports > MAXNPORT) { > >+err("port number exceeds %d", MAXNPORT); > >+goto err; > >+} > >+ > > if (refresh_imported_device_list()) > > goto err; > > > > > > Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Thank you so much, Krzysztof. Yuyang -- 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
[PATCH v3 0/6] usb: usbip: Fix ports and port status
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced several bugs relating to the number of ports amd the port status. In addition, a small improvement is made to the vhci_hcd module. v3: - Check both ends of the nports - Check the return of ncontrollers - Add a few Reviewed-bys and Acked-bys - Minor coding changes v2: - Remove ncontrollers RO attr as suggested by Krzysztof - As a result, scandir vhci_hcd* dir in platform to learn how many we have as suggested by Krzysztof - Minor coding changes Thanks, Yuyang -- Yuyang Du (6): usb: usbip: Remove unnecessary get_vdev() usb: usbip tool: Fix get_nports() usb: usbip tool: Check the return of get_nports() usb: usbip tool: Add ncontrollers in vhci_driver structure usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() drivers/usb/usbip/vhci_hcd.c | 32 + tools/usb/usbip/libsrc/vhci_driver.c | 133 ++- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/usbip_attach.c | 2 + 4 files changed, 88 insertions(+), 80 deletions(-) -- 2.7.4 -- 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
[PATCH v3 3/6] usb: usbip tool: Check the return of get_nports()
If we get nonpositive number of ports, there is no sense to continue, then fail gracefully. In addition, the commit 0775a9cbc694e8c72 ("usbip: vhci extension: modifications to vhci driver") introduced configurable numbers of controllers and ports, but we have a static port number maximum, MAXNPORT. If exceeded, the idev array will be overflown. We fix it by validating the nports to make sure the port number max is not exceeded. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f659c14..151580a 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -220,9 +220,17 @@ int usbip_vhci_driver_open(void) } vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); + if (vhci_driver->nports <=0) { + err("no available ports"); + goto err; + } + else if (vhci_driver->nports > MAXNPORT) { + err("port number exceeds %d", MAXNPORT); + goto err; + } + if (refresh_imported_device_list()) goto err; -- 2.7.4 -- 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
[PATCH v3 2/6] usb: usbip tool: Fix get_nports()
The commit 0775a9cbc694e8c72 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, and nports as a sys file, and claimed to read the nports from it, but it didn't. In addition, the get_nports() has been so wrong that even with 8 port lines for instance, it gets 7 (I am guessing it is due to a '\n' mess). Nevertheless, we fix it by reading the nports attribute. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 28 +--- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..f659c14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -123,33 +123,15 @@ static int refresh_imported_device_list(void) static int get_nports(void) { - char *c; - int nports = 0; - const char *attr_status; + const char *attr_nports; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); + attr_nports = udev_device_get_sysattr_value(vhci_driver->hc_device, "nports"); + if (!attr_nports) { + err("udev_device_get_sysattr_value nports failed"); return -1; } - /* skip a header line */ - c = strchr(attr_status, '\n'); - if (!c) - return 0; - c++; - - while (*c != '\0') { - /* go to the next line */ - c = strchr(c, '\n'); - if (!c) - return nports; - c++; - nports += 1; - } - - return nports; + return (int)strtoul(attr_nports, NULL, 10); } /* -- 2.7.4 -- 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
[PATCH v3 4/6] usb: usbip tool: Add ncontrollers in vhci_driver structure
A new field ncontrollers is added to the vhci_driver structure. And this field is stored by scanning the vhci_hcd* dirs in the platform udev. Suggested-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 36 tools/usb/usbip/libsrc/vhci_driver.h | 1 + 2 files changed, 37 insertions(+) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 151580a..f019686 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -134,6 +135,33 @@ static int get_nports(void) return (int)strtoul(attr_nports, NULL, 10); } +static int vhci_hcd_filter(const struct dirent *dirent) +{ + return strcmp(dirent->d_name, "vhci_hcd") >= 0; +} + +static int get_ncontrollers(void) +{ + struct dirent **namelist; + struct udev_device *platform; + int n; + + platform = udev_device_get_parent(vhci_driver->hc_device); + if (platform == NULL) + return -1; + + n = scandir(udev_device_get_syspath(platform), , vhci_hcd_filter, NULL); + if (n < 0) + err("scandir failed"); + else { + for (int i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + } + + return n; +} + /* * Read the given port's record. * @@ -231,6 +259,14 @@ int usbip_vhci_driver_open(void) goto err; } + vhci_driver->ncontrollers = get_ncontrollers(); + dbg("available controllers: %d", vhci_driver->ncontrollers); + + if (vhci_driver->ncontrollers <=0) { + err("no available usb controllers"); + goto err; + } + if (refresh_imported_device_list()) goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..33add14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -31,6 +31,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; + int ncontrollers; int nports; struct usbip_imported_device idev[MAXNPORT]; }; -- 2.7.4 -- 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
[PATCH v3 1/6] usb: usbip: Remove unnecessary get_vdev()
vhci_tx_urb() should be able to get the vhci_device from its caller vhci_urb_enqueue(), instead of brutal-force searching it. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> Acked-by: Shuah Khan <shua...@osg.samsung.com> --- drivers/usb/usbip/vhci_hcd.c | 32 ++-- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index e4cb9f0..5d8b2c2 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -430,36 +430,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, return retval; } -static struct vhci_device *get_vdev(struct usb_device *udev) +static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) { - struct platform_device *pdev; - struct usb_hcd *hcd; - struct vhci_hcd *vhci; - int pdev_nr, rhport; - - if (!udev) - return NULL; - - for (pdev_nr = 0; pdev_nr < vhci_num_controllers; pdev_nr++) { - pdev = *(vhci_pdevs + pdev_nr); - if (pdev == NULL) - continue; - hcd = platform_get_drvdata(pdev); - if (hcd == NULL) - continue; - vhci = hcd_to_vhci(hcd); - for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { - if (vhci->vdev[rhport].udev == udev) - return >vdev[rhport]; - } - } - - return NULL; -} - -static void vhci_tx_urb(struct urb *urb) -{ - struct vhci_device *vdev = get_vdev(urb->dev); struct vhci_priv *priv; struct vhci_hcd *vhci; unsigned long flags; @@ -601,7 +573,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, } out: - vhci_tx_urb(urb); + vhci_tx_urb(urb, vdev); spin_unlock_irqrestore(>lock, flags); return 0; -- 2.7.4 -- 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
[PATCH v3 5/6] usb: usbip tool: Fix refresh_imported_device_list()
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, but the status of the ports are only extracted from the first status file, fix it. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f019686..ed2eba9 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -108,18 +108,33 @@ static int parse_status(const char *value) return 0; } +#define MAX_STATUS_NAME 16 + static int refresh_imported_device_list(void) { const char *attr_status; + char status[MAX_STATUS_NAME+1] = "status"; + int i, ret; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); - return -1; + for (i = 0; i < vhci_driver->ncontrollers; i++) { + if (i > 0) + snprintf(status, sizeof(status), "status.%d", i); + + attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, + status); + if (!attr_status) { + err("udev_device_get_sysattr_value failed"); + return -1; + } + + dbg("controller %d", i); + + ret = parse_status(attr_status); + if (ret != 0) + return ret; } - return parse_status(attr_status); + return 0; } static int get_nports(void) -- 2.7.4 -- 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
[PATCH v3 6/6] usb: usbip tool: Fix parse_status()
In parse_status(), all nports number of idev's are initiated to 0 by memset(), it is simply wrong, because parse_status() reads the status sys file one by one, therefore, it can only update the according vhci_driver->idev's for it to parse. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 38 ++-- tools/usb/usbip/src/usbip_attach.c | 2 ++ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ed2eba9..af88447 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -36,18 +36,11 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) return NULL; } - - static int parse_status(const char *value) { int ret = 0; char *c; - - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); - - /* skip a header line */ c = strchr(value, '\n'); if (!c) @@ -58,6 +51,7 @@ static int parse_status(const char *value) int port, status, speed, devid; unsigned long socket; char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; ret = sscanf(c, "%d %d %d %x %lx %31s\n", , , , @@ -72,30 +66,28 @@ static int parse_status(const char *value) port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; + idev = _driver->idev[port]; - idev->port = port; - idev->status= status; + memset(idev, 0, sizeof(*idev)); - idev->devid = devid; + idev->port = port; + idev->status= status; - idev->busnum= (devid >> 16); - idev->devnum= (devid & 0x); + idev->devid = devid; - if (idev->status != VDEV_ST_NULL - && idev->status != VDEV_ST_NOTASSIGNED) { - idev = imported_device_init(idev, lbusid); - if (!idev) { - dbg("imported_device_init failed"); - return -1; - } + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); + + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; } } - /* go to the next line */ c = strchr(c, '\n'); if (!c) diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..62a297f 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -108,6 +108,8 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } + dbg("got free port %d", port); + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, udev->devnum, udev->speed); if (rc < 0) { -- 2.7.4 -- 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
Re: [PATCH v2 3/6] usb: usbip tool: Add ncontrollers in vhci_driver structure
On Wed, Apr 05, 2017 at 11:46:06AM +0200, Krzysztof Opasiak wrote: > > > On 04/04/2017 09:08 PM, Yuyang Du wrote: > >Hi Krzysztof, > > > >On Tue, Apr 04, 2017 at 04:52:32PM +0200, Krzysztof Opasiak wrote: > >> > >> > >>On 03/31/2017 02:28 AM, Yuyang Du wrote: > >>>A new field ncontrollers is added to the vhci_driver structure. > >>>And this field is stored by scanning the vhci_hcd* dirs in the > >>>platform udev. > >>> > >>>Suggested-by: Krzysztof Opasiak <k.opas...@samsung.com> > >>>Signed-off-by: Yuyang Du <yuyang...@intel.com> > >>>--- > >>>tools/usb/usbip/libsrc/vhci_driver.c | 32 +++- > >>>tools/usb/usbip/libsrc/vhci_driver.h | 1 + > >>>2 files changed, 32 insertions(+), 1 deletion(-) > >>> > >>>diff --git a/tools/usb/usbip/libsrc/vhci_driver.c > >>>b/tools/usb/usbip/libsrc/vhci_driver.c > >>>index f659c14..ccecd47 100644 > >>>--- a/tools/usb/usbip/libsrc/vhci_driver.c > >>>+++ b/tools/usb/usbip/libsrc/vhci_driver.c > >>>@@ -7,6 +7,7 @@ > >>>#include > >>>#include > >>>#include > >>>+#include > >>>#include "sysfs_utils.h" > >>> > >>>#undef PROGNAME > >>>@@ -134,6 +135,33 @@ static int get_nports(void) > >>> return (int)strtoul(attr_nports, NULL, 10); > >>>} > >>> > >>>+static int vhci_hcd_filter(const struct dirent *dirent) > >>>+{ > >>>+ return strcmp(dirent->d_name, "vhci_hcd") >= 0 ? 1: 0; > >> > >>The ? operator may be omitted here as according to doc we need to > >>return nonzero not 1 exactly. > > > >No, it can't. strcmp() would return negative if not containing "vhci_hcd". > >E.g., > > > >strcmp("!@#", "vhci_hcd") ==> -1 > >strcmp("v", "vhci_hcd") ==> -1 > > I meant, just to drop the ? itself but leave >= 0 > > return strcmp(dirent->d_name, "vhci_hcd") >= 0; Oh, that's doable :) Send a Reviewed-by ? Thanks, Yuyang -- 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
Re: [PATCH v2 4/6] usb: usbip tool: Fix refresh_imported_device_list()
Hi Khan, On Tue, Apr 04, 2017 at 11:14:33AM -0600, Shuah Khan wrote: > On 03/30/2017 06:28 PM, Yuyang Du wrote: > > The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications > > to vhci driver") introduced multiple controllers, but the status > > of the ports are only extracted from the first status file, fix it. > > Are sure this change is needed? What bug are you fixing? This change > will impact every single code path that calls usbip_vhci_driver_open() > > It might be sufficient to look at just the first file status in many of > these cases? Yes, I'm sure. The 1st status file only has the 1st controller's ports, but we must have the status of all the ports of all the controllers. > > > > Signed-off-by: Yuyang Du <yuyang...@intel.com> > > --- > > tools/usb/usbip/libsrc/vhci_driver.c | 27 +-- > > 1 file changed, 21 insertions(+), 6 deletions(-) > > > > diff --git a/tools/usb/usbip/libsrc/vhci_driver.c > > b/tools/usb/usbip/libsrc/vhci_driver.c > > index ccecd47..630b139 100644 > > --- a/tools/usb/usbip/libsrc/vhci_driver.c > > +++ b/tools/usb/usbip/libsrc/vhci_driver.c > > @@ -108,18 +108,33 @@ static int parse_status(const char *value) > > return 0; > > } > > > > +#define MAX_STATUS_NAME 16 > > + > > static int refresh_imported_device_list(void) > > { > > const char *attr_status; > > + char status[MAX_STATUS_NAME+1] = "status"; > > + int i, ret; > > > > - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, > > - "status"); > > - if (!attr_status) { > > - err("udev_device_get_sysattr_value failed"); > > - return -1; > > + for (i = 0; i < vhci_driver->ncontrollers; i++) { > > + if (i > 0) > > + snprintf(status, sizeof(status), "status.%d", i); > > + > > + attr_status = > > udev_device_get_sysattr_value(vhci_driver->hc_device, > > + status); > > + if (!attr_status) { > > + err("udev_device_get_sysattr_value failed"); > > + return -1; > > + } > > + > > + dbg("controller %d", i); > > + > > + ret = parse_status(attr_status); > > + if (ret != 0) > > + return ret; > > usbip_vhci_driver_open() will fail even if one of these fails? Is that > what you would want? Ditto. Thanks, Yuyang -- 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
Re: [PATCH v2 3/6] usb: usbip tool: Add ncontrollers in vhci_driver structure
Hi Krzysztof, On Tue, Apr 04, 2017 at 04:52:32PM +0200, Krzysztof Opasiak wrote: > > > On 03/31/2017 02:28 AM, Yuyang Du wrote: > >A new field ncontrollers is added to the vhci_driver structure. > >And this field is stored by scanning the vhci_hcd* dirs in the > >platform udev. > > > >Suggested-by: Krzysztof Opasiak <k.opas...@samsung.com> > >Signed-off-by: Yuyang Du <yuyang...@intel.com> > >--- > > tools/usb/usbip/libsrc/vhci_driver.c | 32 +++- > > tools/usb/usbip/libsrc/vhci_driver.h | 1 + > > 2 files changed, 32 insertions(+), 1 deletion(-) > > > >diff --git a/tools/usb/usbip/libsrc/vhci_driver.c > >b/tools/usb/usbip/libsrc/vhci_driver.c > >index f659c14..ccecd47 100644 > >--- a/tools/usb/usbip/libsrc/vhci_driver.c > >+++ b/tools/usb/usbip/libsrc/vhci_driver.c > >@@ -7,6 +7,7 @@ > > #include > > #include > > #include > >+#include > > #include "sysfs_utils.h" > > > > #undef PROGNAME > >@@ -134,6 +135,33 @@ static int get_nports(void) > > return (int)strtoul(attr_nports, NULL, 10); > > } > > > >+static int vhci_hcd_filter(const struct dirent *dirent) > >+{ > >+return strcmp(dirent->d_name, "vhci_hcd") >= 0 ? 1: 0; > > The ? operator may be omitted here as according to doc we need to > return nonzero not 1 exactly. No, it can't. strcmp() would return negative if not containing "vhci_hcd". E.g., strcmp("!@#", "vhci_hcd") ==> -1 strcmp("v", "vhci_hcd") ==> -1 > >+ > >+static int get_ncontrollers(void) > >+{ > >+struct dirent **namelist; > >+struct udev_device *platform; > >+int n; > >+ > >+platform = udev_device_get_parent(vhci_driver->hc_device); > >+if (platform == NULL) > >+return -1; > >+ > >+n = scandir(udev_device_get_syspath(platform), , > >vhci_hcd_filter, NULL); > >+if (n < 0) > >+err("scandir failed"); > >+else { > >+for (int i = 0; i < n; i++) > >+free(namelist[i]); > >+free(namelist); > >+} > >+ > >+return n; > >+} > >+ > > /* > > * Read the given port's record. > > * > >@@ -220,9 +248,11 @@ int usbip_vhci_driver_open(void) > > } > > > > vhci_driver->nports = get_nports(); > >- > > Seems to be unrelated. > > > dbg("available ports: %d", vhci_driver->nports); > > > >+vhci_driver->ncontrollers = get_ncontrollers(); > > shouldn't we check here if we didn't got error from scandir()? If scandir() failed, we should have (only) printed errors. But yes, both get_nports() and get_ncontrollers() should check and fail gracefully. Thanks, Yuyang -- 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
[PATCH v2 6/6] usb: usbip tool: Remove empty lines
Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f596ef4..d34a482 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -36,8 +36,6 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) return NULL; } - - static int parse_status(const char *value) { int ret = 0; -- 2.7.4 -- 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
[PATCH v2 5/6] usb: usbip tool: Fix parse_status()
parse_status() reads the status file one by one, so it can only update the available and according vhci_driver->idev's. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 36 +++- tools/usb/usbip/src/usbip_attach.c | 2 ++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 630b139..f596ef4 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -43,11 +43,6 @@ static int parse_status(const char *value) int ret = 0; char *c; - - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); - - /* skip a header line */ c = strchr(value, '\n'); if (!c) @@ -58,6 +53,7 @@ static int parse_status(const char *value) int port, status, speed, devid; unsigned long socket; char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; ret = sscanf(c, "%d %d %d %x %lx %31s\n", , , , @@ -72,30 +68,28 @@ static int parse_status(const char *value) port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; + idev = _driver->idev[port]; + + memset(idev, 0, sizeof(*idev)); - idev->port = port; - idev->status= status; + idev->port = port; + idev->status= status; - idev->devid = devid; + idev->devid = devid; - idev->busnum= (devid >> 16); - idev->devnum= (devid & 0x); + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); - if (idev->status != VDEV_ST_NULL - && idev->status != VDEV_ST_NOTASSIGNED) { - idev = imported_device_init(idev, lbusid); - if (!idev) { - dbg("imported_device_init failed"); - return -1; - } + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; } } - /* go to the next line */ c = strchr(c, '\n'); if (!c) diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..62a297f 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -108,6 +108,8 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } + dbg("got free port %d", port); + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, udev->devnum, udev->speed); if (rc < 0) { -- 2.7.4 -- 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
[PATCH v2 1/6] usb: usbip: Remove unnecessary get_vdev()
vhci_tx_urb() should be able to get the vhci_device from its caller vhci_urb_enqueue(), instead of brutal-force searching it. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 32 ++-- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index e4cb9f0..5d8b2c2 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -430,36 +430,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, return retval; } -static struct vhci_device *get_vdev(struct usb_device *udev) +static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) { - struct platform_device *pdev; - struct usb_hcd *hcd; - struct vhci_hcd *vhci; - int pdev_nr, rhport; - - if (!udev) - return NULL; - - for (pdev_nr = 0; pdev_nr < vhci_num_controllers; pdev_nr++) { - pdev = *(vhci_pdevs + pdev_nr); - if (pdev == NULL) - continue; - hcd = platform_get_drvdata(pdev); - if (hcd == NULL) - continue; - vhci = hcd_to_vhci(hcd); - for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { - if (vhci->vdev[rhport].udev == udev) - return >vdev[rhport]; - } - } - - return NULL; -} - -static void vhci_tx_urb(struct urb *urb) -{ - struct vhci_device *vdev = get_vdev(urb->dev); struct vhci_priv *priv; struct vhci_hcd *vhci; unsigned long flags; @@ -601,7 +573,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, } out: - vhci_tx_urb(urb); + vhci_tx_urb(urb, vdev); spin_unlock_irqrestore(>lock, flags); return 0; -- 2.7.4 -- 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
[PATCH v2 4/6] usb: usbip tool: Fix refresh_imported_device_list()
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, but the status of the ports are only extracted from the first status file, fix it. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ccecd47..630b139 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -108,18 +108,33 @@ static int parse_status(const char *value) return 0; } +#define MAX_STATUS_NAME 16 + static int refresh_imported_device_list(void) { const char *attr_status; + char status[MAX_STATUS_NAME+1] = "status"; + int i, ret; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); - return -1; + for (i = 0; i < vhci_driver->ncontrollers; i++) { + if (i > 0) + snprintf(status, sizeof(status), "status.%d", i); + + attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, + status); + if (!attr_status) { + err("udev_device_get_sysattr_value failed"); + return -1; + } + + dbg("controller %d", i); + + ret = parse_status(attr_status); + if (ret != 0) + return ret; } - return parse_status(attr_status); + return 0; } static int get_nports(void) -- 2.7.4 -- 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
[PATCH v2 2/6] usb: usbip tool: Fix get_nports()
The commit 0775a9cbc694e8c72 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, and nports as a sys file, and claimed to read the nports from it, but it didn't. In addition, the get_nports() has been so wrong that even with 8 port lines for instance, it gets 7 (I am guessing it is due to a '\n' mess). Nevertheless, we fix it by reading the nports attribute. Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 28 +--- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..f659c14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -123,33 +123,15 @@ static int refresh_imported_device_list(void) static int get_nports(void) { - char *c; - int nports = 0; - const char *attr_status; + const char *attr_nports; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); + attr_nports = udev_device_get_sysattr_value(vhci_driver->hc_device, "nports"); + if (!attr_nports) { + err("udev_device_get_sysattr_value nports failed"); return -1; } - /* skip a header line */ - c = strchr(attr_status, '\n'); - if (!c) - return 0; - c++; - - while (*c != '\0') { - /* go to the next line */ - c = strchr(c, '\n'); - if (!c) - return nports; - c++; - nports += 1; - } - - return nports; + return (int)strtoul(attr_nports, NULL, 10); } /* -- 2.7.4 -- 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
[PATCH v2 0/6] usb: usbip: Fix ports and port status
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced several bugs relating to the number of ports amd the port status. In addition, a small improvement is made to the vhci_hcd module. v2: - Remove ncontrollers RO attr as suggested by Krzysztof - As a result, scandir vhci_hcd* dir in platform to learn how many we have as suggested by Krzysztof - Minor coding changes Thanks, Yuyang -- Yuyang Du (6): usb: usbip: Remove unnecessary get_vdev() usb: usbip tool: Fix get_nports() usb: usbip tool: Add ncontrollers in vhci_driver structure usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() usb: usbip tool: Remove empty lines drivers/usb/usbip/vhci_hcd.c | 32 +- tools/usb/usbip/libsrc/vhci_driver.c | 119 --- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/usbip_attach.c | 2 + 4 files changed, 74 insertions(+), 80 deletions(-) -- 2.7.4 -- 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
[PATCH v2 3/6] usb: usbip tool: Add ncontrollers in vhci_driver structure
A new field ncontrollers is added to the vhci_driver structure. And this field is stored by scanning the vhci_hcd* dirs in the platform udev. Suggested-by: Krzysztof Opasiak <k.opas...@samsung.com> Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 32 +++- tools/usb/usbip/libsrc/vhci_driver.h | 1 + 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index f659c14..ccecd47 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -134,6 +135,33 @@ static int get_nports(void) return (int)strtoul(attr_nports, NULL, 10); } +static int vhci_hcd_filter(const struct dirent *dirent) +{ + return strcmp(dirent->d_name, "vhci_hcd") >= 0 ? 1: 0; +} + +static int get_ncontrollers(void) +{ + struct dirent **namelist; + struct udev_device *platform; + int n; + + platform = udev_device_get_parent(vhci_driver->hc_device); + if (platform == NULL) + return -1; + + n = scandir(udev_device_get_syspath(platform), , vhci_hcd_filter, NULL); + if (n < 0) + err("scandir failed"); + else { + for (int i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + } + + return n; +} + /* * Read the given port's record. * @@ -220,9 +248,11 @@ int usbip_vhci_driver_open(void) } vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); + vhci_driver->ncontrollers = get_ncontrollers(); + dbg("available controllers: %d", vhci_driver->ncontrollers); + if (refresh_imported_device_list()) goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..33add14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -31,6 +31,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; + int ncontrollers; int nports; struct usbip_imported_device idev[MAXNPORT]; }; -- 2.7.4 -- 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
Re: [PATCH 5/6] usb: usbip tool: Fix refresh_imported_device_list()
Hi Krzysztof, On Mon, Mar 27, 2017 at 04:31:42PM +0200, Krzysztof Opasiak wrote: > > > On 03/27/2017 07:25 AM, Yuyang Du wrote: > >On Mon, Mar 27, 2017 at 09:07:50AM +0200, Krzysztof Opasiak wrote: > >> > >>As now we have multiple controllers I would be more than happy if we > >>could fix functions like this one to take a controller as a > >>parameter and invoke commands on it instead hardcoding loops like > >>this one with some unclear conditions like if (i > 0). > > > >You mean something like this? > > > >int parse_controller_status(int controller) { > > > > if (controller > 0) > > ... > > > > ... > > > >} > > > > Rather: > > int parse_status(controller *ctrl) > { > stat = get_status(ctrl->status_path); > > ... > } I hope I know how to get the status_path easily, but I don't. So I'll post another version with this unaddressed. Please make it in detail and I'll make another version. Thanks, Yuyang -- 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
Re: [PATCH 5/6] usb: usbip tool: Fix refresh_imported_device_list()
On Mon, Mar 27, 2017 at 09:07:50AM +0200, Krzysztof Opasiak wrote: > > As now we have multiple controllers I would be more than happy if we > could fix functions like this one to take a controller as a > parameter and invoke commands on it instead hardcoding loops like > this one with some unclear conditions like if (i > 0). You mean something like this? int parse_controller_status(int controller) { if (controller > 0) ... ... } Thanks, Yuyang -- 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
Re: [PATCH 2/6] usb: usbip tool: Fix get_nports()
On Mon, Mar 27, 2017 at 08:56:44AM +0200, Krzysztof Opasiak wrote: > + Shuah Khan Sorry for not having sent to Shuah. > On 03/23/2017 03:46 AM, Yuyang Du wrote: ... > As strtoul() returns long and get_nports() should return int I'd > prefer to do here some explicit cast to int to avoid some potential > compiler warnings. > > After fixing this you may add my: > > Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> Many thanks. Yuyang -- 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
Re: [PATCH 3/6] usb: usbip: Export the number of VHCI controllers in a sysfs file
On Mon, Mar 27, 2017 at 09:00:06AM +0200, Krzysztof Opasiak wrote: > >+static ssize_t ncontrollers_show(struct device *dev, struct > >device_attribute *attr, > >+ char *out) > >+{ > >+char *s = out; > >+ > >+out += sprintf(out, "%d\n", vhci_num_controllers); > >+return out - s; > >+} > >+static DEVICE_ATTR_RO(ncontrollers); > >+ > > Why you need a special RO attribute for this? Can't just cannot > check content of directory using for example scandir() to learn what > we have? We can learn or somebody simply tells, I chose the latter. This makes it easier as the changelog says? -- 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
[PATCH v2] usb: gadget: dummy_hcd: Fix wrong power status bit clear/reset in dummy_hub_control()
This fixes the commit: 1cd8fd2887e1 ("usb: gadget: dummy_hcd: add SuperSpeed support"). In the case of ClearPortFeature and USB_PORT_FEAT_POWER, simply clear the right bit regardless of what the wValue is. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/gadget/udc/dummy_hcd.c | 20 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 8cabc59..c790819 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -2062,16 +2062,13 @@ static int dummy_hub_control( } break; case USB_PORT_FEAT_POWER: - if (hcd->speed == HCD_USB3) { - if (dum_hcd->port_status & USB_PORT_STAT_POWER) - dev_dbg(dummy_dev(dum_hcd), - "power-off\n"); - } else - if (dum_hcd->port_status & - USB_SS_PORT_STAT_POWER) - dev_dbg(dummy_dev(dum_hcd), - "power-off\n"); - /* FALLS THROUGH */ + dev_dbg(dummy_dev(dum_hcd), "power-off\n"); + if (hcd->speed == HCD_USB3) + dum_hcd->port_status &= ~USB_SS_PORT_STAT_POWER; + else + dum_hcd->port_status &= ~USB_PORT_STAT_POWER; + set_link_state(dum_hcd); + break; default: dum_hcd->port_status &= ~(1 << wValue); set_link_state(dum_hcd); @@ -2242,14 +2239,13 @@ static int dummy_hub_control( if ((dum_hcd->port_status & USB_SS_PORT_STAT_POWER) != 0) { dum_hcd->port_status |= (1 << wValue); - set_link_state(dum_hcd); } } else if ((dum_hcd->port_status & USB_PORT_STAT_POWER) != 0) { dum_hcd->port_status |= (1 << wValue); - set_link_state(dum_hcd); } + set_link_state(dum_hcd); } break; case GetPortErrorCount: -- 1.9.1 -- 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
[PATCH 6/6] usb: usbip tool: Fix parse_status()
parse_status() reads the status file one by one, so it can only update the available and according vhci_driver->idev's. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 34 ++ tools/usb/usbip/src/usbip_attach.c | 2 ++ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 1c0e7f0..5b14235 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -40,10 +40,6 @@ static int parse_status(const char *value) int ret = 0; char *c; - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); - - /* skip a header line */ c = strchr(value, '\n'); if (!c) @@ -68,30 +64,28 @@ static int parse_status(const char *value) port, status, speed, devid); dbg("socket %lx lbusid %s", socket, lbusid); - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; + struct usbip_imported_device *idev = _driver->idev[port]; - idev->port = port; - idev->status= status; + memset(_driver->idev[port], 0, sizeof(struct usbip_imported_device)); - idev->devid = devid; + idev->port = port; + idev->status= status; - idev->busnum= (devid >> 16); - idev->devnum= (devid & 0x); + idev->devid = devid; - if (idev->status != VDEV_ST_NULL - && idev->status != VDEV_ST_NOTASSIGNED) { - idev = imported_device_init(idev, lbusid); - if (!idev) { - dbg("imported_device_init failed"); - return -1; - } + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); + + if (idev->status != VDEV_ST_NULL + && idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; } } - /* go to the next line */ c = strchr(c, '\n'); if (!c) diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..62a297f 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -108,6 +108,8 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } + dbg("got free port %d", port); + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, udev->devnum, udev->speed); if (rc < 0) { -- 1.9.1 -- 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
[PATCH 5/6] usb: usbip tool: Fix refresh_imported_device_list()
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced multiple controllers, but the status of the ports are only extracted from the first status file, fix it. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 30 +- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index d335f04..1c0e7f0 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -35,14 +35,11 @@ return NULL; } - - static int parse_status(const char *value) { int ret = 0; char *c; - for (int i = 0; i < vhci_driver->nports; i++) memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); @@ -107,18 +104,33 @@ static int parse_status(const char *value) return 0; } +#define MAX_STATUS_NAME 16 + static int refresh_imported_device_list(void) { const char *attr_status; + char status[MAX_STATUS_NAME+1] = "status"; + int i, ret; - attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, - "status"); - if (!attr_status) { - err("udev_device_get_sysattr_value failed"); - return -1; + for (i = 0; i < vhci_driver->ncontrollers; i++) { + if (i > 0) + snprintf(status, MAX_STATUS_NAME+1, "status.%d", i); + + attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, + status); + if (!attr_status) { + err("udev_device_get_sysattr_value failed"); + return -1; + } + + dbg("controller %d", i); + + ret = parse_status(attr_status); + if (ret != 0) + return ret; } - return parse_status(attr_status); + return 0; } static int get_nports(void) -- 1.9.1 -- 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
[PATCH 1/6] usb: usbip: Remove unnecessary get_vdev()
vhci_tx_urb() should be able to get the vhci_device from its caller vhci_urb_enqueue(), instead of brutal-force searching it. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- drivers/usb/usbip/vhci_hcd.c | 32 ++-- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index e4cb9f0..5d8b2c2 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -430,36 +430,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, return retval; } -static struct vhci_device *get_vdev(struct usb_device *udev) +static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) { - struct platform_device *pdev; - struct usb_hcd *hcd; - struct vhci_hcd *vhci; - int pdev_nr, rhport; - - if (!udev) - return NULL; - - for (pdev_nr = 0; pdev_nr < vhci_num_controllers; pdev_nr++) { - pdev = *(vhci_pdevs + pdev_nr); - if (pdev == NULL) - continue; - hcd = platform_get_drvdata(pdev); - if (hcd == NULL) - continue; - vhci = hcd_to_vhci(hcd); - for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { - if (vhci->vdev[rhport].udev == udev) - return >vdev[rhport]; - } - } - - return NULL; -} - -static void vhci_tx_urb(struct urb *urb) -{ - struct vhci_device *vdev = get_vdev(urb->dev); struct vhci_priv *priv; struct vhci_hcd *vhci; unsigned long flags; @@ -601,7 +573,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, } out: - vhci_tx_urb(urb); + vhci_tx_urb(urb, vdev); spin_unlock_irqrestore(>lock, flags); return 0; -- 1.9.1 -- 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
[PATCH 4/6] usb: usbip tool: Add ncontrollers in vhci_driver structure
This field is read from the newly added ncontroller sysfs. Signed-off-by: Yuyang Du <yuyang...@intel.com> --- tools/usb/usbip/libsrc/vhci_driver.c | 18 +- tools/usb/usbip/libsrc/vhci_driver.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 4228b98..d335f04 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -134,6 +134,20 @@ static int get_nports(void) return strtoul(attr_nports, NULL, 10); } +static int get_ncontrollers(void) +{ + const char *attr_ncontrollers; + + attr_ncontrollers = udev_device_get_sysattr_value(vhci_driver->hc_device, + "ncontrollers"); + if (!attr_ncontrollers) { + err("udev_device_get_sysattr_value ncontrollers failed"); + return -1; + } + + return strtoul(attr_ncontrollers, NULL, 10); +} + /* * Read the given port's record. * @@ -220,9 +234,11 @@ int usbip_vhci_driver_open(void) } vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); + vhci_driver->ncontrollers = get_ncontrollers(); + dbg("available controllers: %d", vhci_driver->ncontrollers); + if (refresh_imported_device_list()) goto err; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..33add14 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -31,6 +31,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; + int ncontrollers; int nports; struct usbip_imported_device idev[MAXNPORT]; }; -- 1.9.1 -- 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
[PATCH 0/6] usb: usbip: Fix ports and port status
The commit 0775a9cbc694e8c7 ("usbip: vhci extension: modifications to vhci driver") introduced several bugs relating to the number of ports amd the port status. In addition, a small improvement is made to the vhci_hcd module. Only lightly tested with a box being both server and client. Thanks, Yuyang -- Yuyang Du (6): usb: usbip: Remove unnecessary get_vdev() usb: usbip tool: Fix get_nports() usb: usbip: Export the number of VHCI controllers in a sysfs file usb: usbip tool: Add ncontrollers in vhci_driver structure and store usb: usbip tool: Fix refresh_imported_device_list() usb: usbip tool: Fix parse_status() drivers/usb/usbip/vhci_hcd.c | 32 +-- drivers/usb/usbip/vhci_sysfs.c | 19 +-- tools/usb/usbip/libsrc/vhci_driver.c | 104 ++- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/usbip_attach.c | 2 + 5 files changed, 74 insertions(+), 84 deletions(-) -- 1.9.1 -- 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