2

Hello USB / Linux gurus!

I have an embedded system based on an Atmel ARM Cortex-A5 CPU. It runs embedded Linux kernel V3.10 that configures its high-speed USB port as a USB device.

The USB device is configured as a USB composite made up of HID, NDIS Ethernet and MTP. Everything is working well.

However When plugging in this embedded system into a host OS like Windows, a situation arises when I must notify Window of the new MTP device. Currently the only way I know how to do that is to physically unplug the USB cable from the embedded system and plug it back in. Windows then notices the 'new' MTP connection, opens a folder pointing to the files on my device and everything is great!

I would like to find a way to do exactly the same thing programmatically... in other words bring my USB device port down and up just as if I were using 'ifconfig' for Ethernet.

Is there some command I can use to suspend and resume a USB device port?

Thank you very much!

Jean-Pierre

P.S. The USB driver I'm using is called 'atmel_usba_udc.c' and contains functions like 'atmel_usba_stop()' and 'atmel_usba_start()' that I'd like to invoke from user-space.

Jeepster
  • 129
  • 2
  • 11
  • 1
    The `stop()` and `start()` functions most likely are invoked when the kernel module loads and unloads. Have you tried `rmmod` / `insmod` ? – Ben Voigt Sep 29 '15 at 18:00
  • 1
    Hi Ben, thank you very much for the useful and prompt response. In the Atmel driver code I see a structure of type 'usb_gadget_ops' that has (presumably) publicly exported functions .udc_start, .udc_stop, .wakeup and a couple others. Unfortunately I have not compiled these as kernel objects due to some earlier problem (that I may be able to resolve). Would the easiest way to do what I'm trying to do to try again to compile USB driver functionality as kernel objects? Thank you!! :) – Jeepster Sep 29 '15 at 18:18
  • 1
    Well, it shouldn't be the only way, there ought to be some `ioctl` to trigger a bus reconnect. But for cases when you have only one USB device port, then reloading the kernel driver module might be a shorter path to success. – Ben Voigt Sep 29 '15 at 18:20
  • 1
    Hi Ben, thanks again. Unfortunately ioctl doesn't figure in the atmel_usba_udc driver but perhaps udc or some other usb mechanism has ioctl access but I have yet to find how to access the proper /sys node and what ioctl could do the bus reset. Q: Do you think unloading / reloading the usb physical driver will probably restore our logical USB composite configuration once insmod is called? – Jeepster Sep 29 '15 at 19:03
  • 1
    If you have a test system, just trying it is probably the easiest way to find out. – Ben Voigt Sep 29 '15 at 19:22
  • 1
    Agreed. Have recompiled atmel driver as a .ko Will report what happens when I remove / insert the actual physical USB driver. Kind of killing a fly with a sledgehammer but I don't think if I unload / reload MTP module that Windows would pop-up the folder window I need. :) – Jeepster Sep 29 '15 at 19:30
  • 1
    After a few days of work with this issue, it turns out that compiling the USB driver itself as a kernel object and loading / unloading it didn't work (usb would not work). What did work however (and is quite useful) is compiling my USB composite driver as a ko and loading/unloading that. (Thanks for the help!) – Jeepster Oct 02 '15 at 17:04
  • 1
    Can you report the issue you had with atmel_usba_udc compiled as a moduke on the linux-arm-kernel mailing lists? This is probably something we want to fix – Alexandre Belloni Oct 03 '15 at 19:49
  • 1
    It compiled & linked but USB appeared non-functional if the Atmel USB driver was loaded by ko instead of built in-kernel. (In our case anyways, loading our USB composite driver was enough to delay USB driver load so mtp-server could be started right after so windows would recognize mtp) – Jeepster Oct 04 '15 at 21:09

1 Answers1

1

'atmel_usba_stop()' and 'atmel_usba_start()' seem to be related to ops that refer to function pointers used for accessing hardware-specific operations. You can use it for instructing the kernel from userspace by linking with ioctl appropriately.

Karthik Balaguru
  • 7,424
  • 7
  • 48
  • 65
  • 1
    Hi Karthik, thanks for the hint. Indeed these functions are called when I load / unload the usb driver using kernel objects but USB was not functional. What worked is from comment above (copied here) -------- After a few days of work with this issue, it turns out that compiling the USB driver itself as a kernel object and loading / unloading it didn't work (usb would not work). What did work however (and is quite useful) is compiling my USB composite driver as a ko and loading/unloading that – Jeepster Oct 02 '15 at 17:05