From: James M. <jam...@ho...> - 2006-08-14 00:43:23
|
>From: Alan Stern <st...@ro...> >To: James McMechan <jam...@ho...> >CC: lin...@li..., ><use...@li...> >Subject: Re: [linux-usb-devel] [ link to patch] resurrecting the uml-hcd >Date: Sun, 13 Aug 2006 15:00:35 -0400 (EDT) > >On Sun, 13 Aug 2006, James McMechan wrote: > > > I am attempting to resurrect the uml-hcd driver > > this version is based off of the gadget/dummy_hcd.c driver. > > > > I am aiming at a 2.6.12.2 target where it will be used. > > I have forward ported it to 2.6.17.6 for testing and hopefully > > eventual inclusion. > > > > This patch has a #PLATFORM to deal with the issues between > > 2.6.17.6/2.6.12.2 since platform_register... is not present in older > > kernels and the new kernels don't work with the older registration. > > > > For some reason the usb core is not sending hub urbs to my hcd > > all the control seems to run through hub_control and hub_status_data > > both of which are not checked before calling and so segfaults the kernel > > if not present rather than queuing a control urb to get the > > status as I would have expected... > >No. These function pointers _must_ be set. > >There's no point queuing an URB for the root hub. Queued URBs are sent >out over the USB bus... which makes no sense when the URB's destination is >the HCD itself. > >Or to put it another way: Why should an HCD have to work to unpack the >request, request type, value, index, and length fields from the URB when >usbcore has already done all that? It's simpler to pass the values >directly to a hub_control method than to force every HCD to repeat this >work. On real hardware I agree there seems be no need, nor on a fully simulated device, UML is a odd case of half simulated half real hardware where it will be sending a urb off to the real root hub while simulating the UML root hub which proxies for the real root hub > > Now I realize, that in hub_control I can assemble a urb out of the data > > presented and call my enqueue method, but it looks like that would > > be unusually dense of me, since it appears that there should already be > > some way to get the urbs. > >It is indeed possible to get at the original control URB. Just follow the >linked list in hcd->self.root_hub->ep0.urb_list; there should be only one >entry in the list and it will be the URB. Would sending hub control stuff through usbdevfs to the hub break things e.g. what can user space do without upsetting the hub thread on the host, or conversely is there a set of safe commands to send? USB_PORT_FEAT_CONNECTION,ENABLE,SUSPEND,OVER_CURRENT RESET,POWER should be doable but I am not sure UML hub thread will see the corresponding USB_PORT_FEAT_C bit before the host hub thread clears it. As I recall the last time I worked on this one of the biggest problems was maintaining the proxy hub's state in UML to match what the real hub (or hubs) was doing. UML would be perfectly happy if it could just claim a hub as it own, or yield all hub control down to the host system. Neither of which was doable in 2.4 nor do I see a obvious way in 2.6 yet, perhaps convince the host the hub is quiescing? but leave it running or some other havoc with the hub thread. > > On 2.6.17.6 it segfaults in the core at hub.c:2251 dev_dbg > > where udev->bus->controller->driver->name is used without checking > > if driver == NULL which it was in my version. I have not figured out > > where that driver is supposed to be set since the controller appears to > > be created in the usb core somewhere... > > This patch now checks for that. > > > > Does anyone know where bus->controller->driver is supposed to be set? > >It gets set when your HCD is bound to the platform device. In dummy_hcd.c >this occurs in the initialization routine, where the code calls > > retval = platform_driver_register (&dummy_hcd_driver); > ... > retval = platform_device_register (&the_hcd_pdev); > >This causes the driver core to set the_hcd_pdev.dev.driver equal to >&dummy_hcd_driver.driver. In your code this mechanism doesn't work >because the names don't match: Your device's name is "uml-hcd" with a '-' >and your driver's name is "uml_hcd" with an '_'. Ah, Thank you, I had been chaseing usb initializion through the core for several days without finding that point. Though fixing that now causes the devices to show up twice, two host controllers & two usb devices. > > > uml-hcd is currently partly operational > > I can enumerate the device, libusb will talk to it. > > Control URBs seem to go back and forth. > > and report status back correctly. > > > > I have walked through the usbmon output on the host and the hub >simulation > > is producing the same status in the same order as the host does > > the host appears to produce urbs for its root hub however. > > under uml usbmon does not show up in /sys/kernel/debug so > > I have not been able to test it there, my current spew level dev_info >dumps > > all the hub control/status to my console. > >Doesn't uml implement the debugfs filesystem? Did you remember to set >CONFIG_DEBUG_FS and to do "mount -t debugfs none /sys/kernel/debug"? Yes, I just goofed, I saw the /sys/kernel/debug and forgot to mount it in the UML. > > Your thoughts are welcome, I would hate to have to fall back to creating >a > > virtual proc files system that just forwards all the libusb calls down >to > > the > > host OS. This was working a few years ago and it looks (from >dummy_hcd.c > > and usbip) that it should be possible here. I know it was possible to >write > > a complete usb from userspace without requiring a stub driver back in > > the bad old days of 2.4.18... > > > > No doubt this version takes may liberties with the core and driver model > > if you could point out some of the more obvious ones to me, > > I still was thinking about the automatic interrupt urb submission when >last > > this was current. > >On a quick glance, it appears that your dequeue method does not try to >cancel the URB on the host. Shouldn't it do so? Yes it should, partly operational it is, and that is one of the partlys I really should fix, I have not had a test case with a canceled urb that I could notice the urb needing cancelling. > > The patch can be fetched from > > http://mysite.verizon.net/james.mcmechan/uml-hcd.2.6.17.6.patch > > or bzipped as > > http://mysite.verizon.net/james.mcmechan/uml-hcd.2.6.17.6.patch.bz2 > > it is 1104 lines long & 31K in size so I stuck it on a web page. > >Your server doesn't set the MIME type correctly; everything appears to be >text/html or something similar. > >Alan Stern > Sorry about that, I was in a hurry and did not want to bomb the list with a 30K patch, I just checked that wget fetched it from the server correctly I have added a version at http://mysite.verizon.net/james.mcmechan/uml-hcd.2.6.17.6.txt for viewing since I have no clue how to get verizon's apache to use mime type settings. Thank you for looking at the code. James McMechan |
From: James M. <jam...@ho...> - 2006-08-15 02:41:58
|
>From: Alan Stern <st...@ro...> >To: James McMechan <jam...@ho...> >CC: lin...@li..., ><use...@li...> >Subject: Re: [linux-usb-devel] [ link to patch] resurrecting the uml-hcd >Date: Mon, 14 Aug 2006 10:59:12 -0400 (EDT) > >On Mon, 14 Aug 2006, James McMechan wrote: > > > >There's no point queuing an URB for the root hub. Queued URBs are sent > > >out over the USB bus... which makes no sense when the URB's destination >is > > >the HCD itself. > > > > > >Or to put it another way: Why should an HCD have to work to unpack the > > >request, request type, value, index, and length fields from the URB >when > > >usbcore has already done all that? It's simpler to pass the values > > >directly to a hub_control method than to force every HCD to repeat this > > >work. > > > > On real hardware I agree there seems be no need, nor on a fully >simulated > > device, UML is a odd case of half simulated half real hardware > > where it will be sending a urb off to the real root hub while > > simulating the UML root hub which proxies for the real root hub > >Yes. And UML is even odder in that it runs entirely in userspace, with no >(or minimal) host-kernel component. > > > >It is indeed possible to get at the original control URB. Just follow >the > > >linked list in hcd->self.root_hub->ep0.urb_list; there should be only >one > > >entry in the list and it will be the URB. > > > > Would sending hub control stuff through usbdevfs to the hub break things > > e.g. what can user space do without upsetting the hub thread on > > the host, or conversely is there a set of safe commands to send? > >It's a tough situation. If you're not careful, you will end up with two >hub drivers (one in the host kernel and one in the UML kernel) both >trying to drive the same device! That can't possibly work. Yep, two hub threads one in the UML and one in the host system which is why it will need a hub proxy. I don't know what it is legal to do from userspace, the usbdevfs documentation sparse notably on async urbs and reaping. > > USB_PORT_FEAT_CONNECTION,ENABLE,SUSPEND,OVER_CURRENT > > RESET,POWER should be doable but I am not sure UML hub thread will > > see the corresponding USB_PORT_FEAT_C bit before the host hub > > thread clears it. > > > > As I recall the last time I worked on this one of the biggest problems > > was maintaining the proxy hub's state in UML to match what > > the real hub (or hubs) was doing. UML would be perfectly happy if > > it could just claim a hub as it own, or yield all hub control down > > to the host system. Neither of which was doable in 2.4 nor do I > > see a obvious way in 2.6 yet, perhaps convince the host the hub > > is quiescing? but leave it running or some other havoc with the > > hub thread. > >Well, you can't have UML take total control of the root hub because then >there would be no way to tell the host kernel about the existence of any >child devices. (usbfs doesn't provide any means of doing this.) If the >host doesn't know about child devices, it can't send URBs to them. So >you'd be stuck. > >You can't have UML and the host both trying to drive the same hub; that >way madness lies. Your only choice is to invent a totally virtual >root-hub device, existing only within UML. In fact, you would want to >replace most of the standard hub driver with a version customized for the >UML kernel; basically it wouldn't have to do much of anything. Then you >could have UML grab control of various real USB devices, importing them >within its own space. Yes, madness or in this case emulation, a proxy hub that just sits there to receive the commands and decide which ones to pass on to the real hub and how to fake the status on the others (and for the ones being forwarded while waiting for the real hub to complete its business) note it is not just the root hub that is a problem all hubs will need to do this and I would really prefer to do it only one way, which is why I was asking about the hub urbs, since the hub emulation will need to unpack urbs for non-root hubs it might be easier to have the proxy be called from wrappers in hub_control/status_data and the urb handler It will then decide e.g. that the PORT_RESET should be sent and then start faking the status returns for the UML hub thread while waiting for the real hardware to execute the RESET and clear C_RESET but that has the race: will I even see the RESET status or C_RESET status at all? The 2.4 version sat in the timer and walked the list of hubs each tick checking for port status changes via the HUB_PORT_INFO ioctl and then rescanned the usb bus to determine if the topology had changes and updated the simulated hubs and I seem to recall added busses & hcd's as it was updated. This should be better in 2.6 /proc/bus/usb/devices is documented as giving a poll status change on device changes. If you have a suggestion on how I should override the hub thread so UML would work better I would be quite happy hear suggestions. currently UML does not touch the USB core where the hub thread is is it even a good idea to do so? I admit the proxy hubs are somewhat of a messy design with both simulated and real status and urbs going back and forth on both the UML and the host. > > >This causes the driver core to set the_hcd_pdev.dev.driver equal to > > >&dummy_hcd_driver.driver. In your code this mechanism doesn't work > > >because the names don't match: Your device's name is "uml-hcd" with a >'-' > > >and your driver's name is "uml_hcd" with an '_'. > > > > Ah, Thank you, I had been chaseing usb initializion through the core > > for several days without finding that point. > > Though fixing that now causes the devices to show up twice, > > two host controllers & two usb devices. > >Maybe this is because the standard mechanisms are now operating in >addition to whatever workaround you installed. I haven't looked at your >code closely enough to be able to tell. > >Alan Stern > |
From: Alan S. <st...@ro...> - 2006-08-15 19:10:55
|
On Tue, 15 Aug 2006, James McMechan wrote: > Yep, two hub threads one in the UML and one in the host system > which is why it will need a hub proxy. I don't know what it is legal > to do from userspace, the usbdevfs documentation sparse notably > on async urbs and reaping. For hubs, it's legal to submit pretty much any URB through usbfs except for Clear-Halt. > >You can't have UML and the host both trying to drive the same hub; that > >way madness lies. Your only choice is to invent a totally virtual > >root-hub device, existing only within UML. In fact, you would want to > >replace most of the standard hub driver with a version customized for the > >UML kernel; basically it wouldn't have to do much of anything. Then you > >could have UML grab control of various real USB devices, importing them > >within its own space. By the way, your reply would be a _lot_ easier to read if you divided it up into regular English sentences... > Yes, madness or in this case emulation, a proxy hub that just sits there > to receive the commands and decide which ones to pass on to the real > hub and how to fake the status on the others It's not just hubs. For example, from within UML you can't really send a Set-Configuration request to any device. Or rather, you can send it but it will badly confuse the host kernel. You would have to translate such a request into a USBDEVFS_SETCONFIGURATION ioctl. Similar considerations apply to port resets and suspend/resume requests. Let's face it, the USB stack in Linux is designed in such a way that USB devices cannot effectively be virtualized without using a host-kernel driver. Within these limitations, the UML hub driver won't have to do anything, really. It won't generate requests or pass anything through to the host kernel. The hub_control routine in uml_hcd would simply send all URBs through to the host's root hub. > (and for the ones being > forwarded while waiting for the real hub to complete its business) note > it is not just the root hub that is a problem all hubs will need > to do this That's true. You should be able to use the same driver for all hubs, since it won't have to do anything. > and I would really prefer to do it only one way, which is why > I was asking about the hub urbs, since the hub emulation will need to > unpack urbs for non-root hubs Without the ability to do port resets, you can't have much of a hub emulator. You might as well simply pass through all URBs that don't refer to the reset, suspend, or enable features. > it might be easier to have the proxy > be called from wrappers in hub_control/status_data and the urb handler > It will then decide e.g. that the PORT_RESET should be sent and then > start faking the status returns for the UML hub thread while waiting for > the real hardware to execute the RESET and clear C_RESET but that > has the race: will I even see the RESET status or C_RESET status at all? I don't think you can make port resets from UML work at all. > The 2.4 version sat in the timer and walked the list of hubs each tick > checking for port status changes via the HUB_PORT_INFO ioctl > and then rescanned the usb bus to determine if the topology had > changes and updated the simulated hubs and I seem to recall > added busses & hcd's as it was updated. > > This should be better in 2.6 /proc/bus/usb/devices is documented > as giving a poll status change on device changes. > > If you have a suggestion on how I should override the hub thread > so UML would work better I would be quite happy hear suggestions. You need to do a lot more than override the hub thread. To do what you want would basically require a new general-purpose USB device driver in the host kernel, one that could relay URBs and other information back and forth between the UML kernel and the host's stack. And you would need a better conduit than usbfs for doing the relaying. > currently UML does not touch the USB core where the hub thread is > is it even a good idea to do so? I admit the proxy hubs are somewhat > of a messy design with both simulated and real status and urbs going > back and forth on both the UML and the host. Have you seen the changes to usbcore in the -mm kernel series? They introduce the notion of a USB device driver (as opposed to interface driver). You would have to write you own new device driver for the host kernel and somehow get it to override the standard generic driver. It would be a big job. Alan Stern |
From: Alan S. <st...@ro...> - 2006-08-14 14:59:16
|
On Mon, 14 Aug 2006, James McMechan wrote: > >There's no point queuing an URB for the root hub. Queued URBs are sent > >out over the USB bus... which makes no sense when the URB's destination is > >the HCD itself. > > > >Or to put it another way: Why should an HCD have to work to unpack the > >request, request type, value, index, and length fields from the URB when > >usbcore has already done all that? It's simpler to pass the values > >directly to a hub_control method than to force every HCD to repeat this > >work. > > On real hardware I agree there seems be no need, nor on a fully simulated > device, UML is a odd case of half simulated half real hardware > where it will be sending a urb off to the real root hub while > simulating the UML root hub which proxies for the real root hub Yes. And UML is even odder in that it runs entirely in userspace, with no (or minimal) host-kernel component. > >It is indeed possible to get at the original control URB. Just follow the > >linked list in hcd->self.root_hub->ep0.urb_list; there should be only one > >entry in the list and it will be the URB. > > Would sending hub control stuff through usbdevfs to the hub break things > e.g. what can user space do without upsetting the hub thread on > the host, or conversely is there a set of safe commands to send? It's a tough situation. If you're not careful, you will end up with two hub drivers (one in the host kernel and one in the UML kernel) both trying to drive the same device! That can't possibly work. > USB_PORT_FEAT_CONNECTION,ENABLE,SUSPEND,OVER_CURRENT > RESET,POWER should be doable but I am not sure UML hub thread will > see the corresponding USB_PORT_FEAT_C bit before the host hub > thread clears it. > > As I recall the last time I worked on this one of the biggest problems > was maintaining the proxy hub's state in UML to match what > the real hub (or hubs) was doing. UML would be perfectly happy if > it could just claim a hub as it own, or yield all hub control down > to the host system. Neither of which was doable in 2.4 nor do I > see a obvious way in 2.6 yet, perhaps convince the host the hub > is quiescing? but leave it running or some other havoc with the > hub thread. Well, you can't have UML take total control of the root hub because then there would be no way to tell the host kernel about the existence of any child devices. (usbfs doesn't provide any means of doing this.) If the host doesn't know about child devices, it can't send URBs to them. So you'd be stuck. You can't have UML and the host both trying to drive the same hub; that way madness lies. Your only choice is to invent a totally virtual root-hub device, existing only within UML. In fact, you would want to replace most of the standard hub driver with a version customized for the UML kernel; basically it wouldn't have to do much of anything. Then you could have UML grab control of various real USB devices, importing them within its own space. > >This causes the driver core to set the_hcd_pdev.dev.driver equal to > >&dummy_hcd_driver.driver. In your code this mechanism doesn't work > >because the names don't match: Your device's name is "uml-hcd" with a '-' > >and your driver's name is "uml_hcd" with an '_'. > > Ah, Thank you, I had been chaseing usb initializion through the core > for several days without finding that point. > Though fixing that now causes the devices to show up twice, > two host controllers & two usb devices. Maybe this is because the standard mechanisms are now operating in addition to whatever workaround you installed. I haven't looked at your code closely enough to be able to tell. Alan Stern |