Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - USB drive detection on startup: (12 Items)
   
USB drive detection on startup  
We are using QNX 6.5.0 with a minimal configuration in an embedded system.  Our application has the requirement that if 
it powers up with a USB drive plugged in, we look for a file with a specific signature, an if it exists, we execute it 
instead of the installed application.  We use this feature for fault recovery and debugging.  We execute the following 
in the image script before our application is executed:

# USB port support
io-usb -dehci -dohci -duhci &
waitfor /dev/io-usb/io-usb
devb-umass cam pnp blk noatime disk name=umass cdrom name=umasscd &

# Start the automounter
/usr/sbin/mcd -v /etc/mcd.conf

Our startup program blindly waits two seconds before checking the USB drive for files.  This is to give time for the 
automounter to detect and mount the drive.  I found a USB drive that take just over two seconds for the automounter to 
detect, so they do not get detected in time.  I can extend this wait time to accommodate it, but I do not like this dead
 time in our startup and would like to make it more intelligent. 

I can monitor in a timed loop to detect the presence of a USB drive earlier, but it would still wait the full timeout if
 no USB drive is inserted.  What I need is a way to detect that there is no drive inserted and then skip the check.  Is 
there any way to detect that there is no drive installed that hasn't been mounted yet?
Re: USB drive detection on startup  
That last question should be is there any way to detect that there is no USB drive installed versus one that is 
installed but hasn't been mounted yet?
Re: USB drive detection on startup  
Can you call the "usb" utility and grep the output for the enumeration list?  Linst hould contain your usb drive OR not.
Re: USB drive detection on startup  
You could do a shared access scan for the device by connecting 
(usbd_connect())to the USB server but not providing any callbacks and 
setting the device ident to use wildcards. You then use usbd_attach() to 
loop through all the devices (see usbd_attach() docs for notes on 
"Looping") and check the instance of the attached device for a dclass of 
0x06, a subclass of 0x08 and maybe even a protocol of 0x50 (that's what 
usb -vv showed for my umass device, your mileage will vary though). You 
could then increment a counter to track how many umass devices are 
plugged in at the time or just bail out at that point and return status 
to your script etc.

On 05/17/2013 08:31 AM, Robert Murrell wrote:
> That last question should be is there any way to detect that there is no USB drive installed versus one that is 
installed but hasn't been mounted yet?
>
>
>
>
> _______________________________________________
>
> OSTech
> http://community.qnx.com/sf/go/post101515
> To cancel your subscription to this discussion, please e-mail ostech-core_os-unsubscribe@community.qnx.com

Re: USB drive detection on startup  
Thanks.  I didn't know this interface existed.  This might be just what I'm looking for.
Re: USB drive detection on startup  
Base on your suggestion and the example code in the docs, I wrote this test program:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/usbdi.h>

int main(int argc, char *argv[]) {

	int rc;
	usbd_connect_parm_t parms;
	struct usbd_connection *connection;

	usbd_device_ident_t ident;
	usbd_funcs_t funcs;

	usbd_device_instance_t instance;
	struct usbd_device *device;

	usbd_device_descriptor_t *descriptor;
	struct usbd_desc_node *node;

	memset(&parms, 0, sizeof(parms));
	memset(&funcs, 0, sizeof(funcs));

	funcs.nentries = _USBDI_NFUNCS;
	ident.vendor = USBD_CONNECT_WILDCARD;
	ident.device = USBD_CONNECT_WILDCARD;
	ident.dclass = USBD_CONNECT_WILDCARD;
	ident.subclass = USBD_CONNECT_WILDCARD;
	ident.protocol = USBD_CONNECT_WILDCARD;
	parms.vusb = USB_VERSION;
	parms.vusbd = USBD_VERSION;
	parms.ident = &ident;
	parms.funcs = &funcs;
	parms.connect_wait = 2;

	if ((rc = usbd_connect(&parms, &connection)) == EOK) {

		//attach to USB0
		int busno;
		int devno;
		for (busno = 0; busno < 10; ++busno) {
		    for (devno = 0; devno < 64; ++devno) {
				memset(&instance, USBD_CONNECT_WILDCARD, sizeof(instance));
				instance.path = busno;
				instance.devno = devno;
				if ((rc = usbd_attach(connection, &instance, 0, &device)) == EOK) {
					if ((descriptor = usbd_device_descriptor(device, &node)) != NULL) {
						printf("Found device\n");
					}
				} else {
					printf("Bus %d device %d: %s\n", busno, devno, strerror(rc));
				}
		    }
		}
		rc = usbd_disconnect(connection);
	}
	return EXIT_SUCCESS;
}

All calls to usbd_attach return ENODEV, except the call for busno = 0 and devno = 1.  That call returns EBUSY.  I have a
 USB drive plugged in and the values corresponds to the report given by "usb". What am I doing wrong?

> You could do a shared access scan for the device by connecting 
> (usbd_connect())to the USB server but not providing any callbacks and 
> setting the device ident to use wildcards. You then use usbd_attach() to 
> loop through all the devices (see usbd_attach() docs for notes on 
> "Looping") and check the instance of the attached device for a dclass of 
> 0x06, a subclass of 0x08 and maybe even a protocol of 0x50 (that's what 
> usb -vv showed for my umass device, your mileage will vary though). You 
> could then increment a counter to track how many umass devices are 
> plugged in at the time or just bail out at that point and return status 
> to your script etc.
> 
Re: USB drive detection on startup  
If you carefully read the documentation, you might just do the right thing  I changed my code from this:

	parms.funcs = &funcs;

to this:

	parms.funcs = NULL;

and it is working.
RE: USB drive detection on startup  
Right, someone already attached to it, you just need readonly connection,

By the way, a more efficiency approach is to do single one call for each bus

extern int					usbd_topology_ext(struct usbd_connection *connection, _Uint8t busno, usbd_bus_topology_t *tp);

and exam the tp from devno 1 to 63. if upstream_devno is 0 or 0xff, then there is no device on that devno.


-----Original Message-----
From: Robert Murrell [mailto:community-noreply@qnx.com] 
Sent: Friday, May 17, 2013 11:48 AM
To: ostech-core_os
Subject: Re: USB drive detection on startup

If you carefully read the documentation, you might just do the right thing  I changed my code from this:

	parms.funcs = &funcs;

to this:

	parms.funcs = NULL;

and it is working.




_______________________________________________

OSTech
http://community.qnx.com/sf/go/post101528
To cancel your subscription to this discussion, please e-mail ostech-core_os-unsubscribe@community.qnx.com
Re: USB drive detection on startup  
Thanks - this is good to know as I usually just looped as the 
documentation described.
Re: USB drive detection on startup  
I could have also been a bit more clear in my mention of "shared access" 
- glad you got it sorted out though.
Re: USB drive detection on startup  
We have upgraded from an 800MHz VortexDx to a 1.66GHz Atom processor, and now this code doesn't work.  My startup code 
is running before the driver has detected that a USB drive is inserted.  Is there any low-level hardware signal that I 
could look at, something similar to the RS-232 DTR signal to detect that hardware is present?  If I could detect that 
the unit was powered up with something plugged in, I could afford the time to wait for the driver to identify what it is
.
Re: USB drive detection on startup  
I still ended up to a three second delay to determine that a USB drive was NOT plugged in on power-up.  I use the USBD 
interface to check if a device is present and if not, I wait 100ms and try again.  I do this for three seconds and 
continue if not found.

But now I have found a new problem.  If I detect a USB drive present, I wait for it to be mounted by MCD by doing a stat
 on the mount point.  When this returns success, I call scandir() to get a filtered list of files in the root directory.
  If I insert a USB drive with lots of files (10K or more, not in the root diretcory), scandir only returns the files ".
" and "..".  If I put a 3 second delay before the scandir(), I get the full list of files in the root directory.  So, 
how do I work around this problem?