USB Stack

Hi,

I am writing a USB class driver for a custom board, i followed/copied (i believe for the most part) the DDk instructions for developing the driver.
I noticed that the USB stack in my machine is not started by default. I found out the USB on my device use UHCI controller ( from pci -vvv), so i start up the usb stack as,

io-usb -duhci &
After which i start my driver >./usbDriver and connect the USB devices.
Here is the problem, i cannot connect to the usb stack, i am not sure if i need to be doing something else or i am I missing something. Any help would be appreciated, I have posted my code below,

/* Prototype driver for

  • cmcc boards
  • History :
  • Nov 20 2008
    */

#include <sys/usbdi.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include “usbCmccDev.h”

#define MAX_BUFFER_SIZE 2048

cmcc_t *cmccDev;
struct usbd_connection *usbHandle = NULL;
short num_devices_attached = 0;
pthread_mutex_t usbMutex = PTHREAD_MUTEX_INITIALIZER;

/* A usb device was inserted, call

  • usbd_attach() to attach to that

  • device
    */
    void usbCmccInsertion
    (
    struct usbd_connection *connection,
    usbd_device_instance_t *instance
    )
    {
    _uint32 retVal;
    _uint32 eix;
    usbd_descriptors_t *usbDesc;
    struct usbd_desc_node *ifc, *ept;

    printf (“usbCmccInsertion called \n”);
    pthread_mutex_lock (&usbMutex);
    memcpy (&cmccDev->instance, instance, sizeof (usbd_device_instance_t));

    /* Totally arbitrary size for the extra memory, as of now i dont need it :slight_smile:/
    if ((retVal = usbd_attach (connection, instance, MAX_BUFFER_SIZE, &cmccDev->usbDev[num_devices_attached++])) != EOK)
    {
    perror (" Could not attach to the usb device \n");
    num_devices_attached–;
    }
    else
    {
    /
    Select the usb configuration /
    if ((usbd_select_config (cmccDev->usbDev[num_devices_attached],instance->config)) == EOK)
    {
    /
    select the usb interface ?*/
    usbd_select_interface (cmccDev->usbDev[num_devices_attached],
    instance->iface,
    instance->alternate);

         for (eix = 0; (usbDesc = usbd_parse_descriptors (cmccDev->usbDev[num_devices_attached], ifc,
                                                       USB_DESC_ENDPOINT, eix, &ept))!= NULL;
                        ++eix)
             {                    
             switch (usbDesc->endpoint.bmAttributes)
                 {                                               
                 case USB_ATTRIB_CONTROL:
                     break;                            
                 case USB_ATTRIB_ISOCHRONOUS:
                     break;                        
                 case USB_ATTRIB_INTERRUPT:
                     break;
                     /* We know that the cmcc board is a 
                        bulk device ?*/
    
                 case USB_ATTRIB_BULK:
                         /* USB_ENDPOINT_IN 0x80, USB_ENDPOINT_OUT 0x00 */
                     if (usbDesc->endpoint.bEndpointAddress & USB_ENDPOINT_IN)
                         {
                         
                         printf (" USB_ENDPOINT_IN\n");
                         if ((usbd_open_pipe (cmccDev->usbDev[num_devices_attached], usbDesc, &cmccDev->usbPipeIn)) != EOK)                                                        
                             {
                             perror ("Could not open the input pipe \n");
                             }
                         }                        
                     else
                         {                        
                         if ((usbd_open_pipe (cmccDev->usbDev[num_devices_attached], usbDesc, &cmccDev->usbPipeOut)) != EOK)                                                        
                             {
                             perror ("Could not open the input pipe \n");
                             }                                
                         }
                 }
             }
         }
     }
    

    /* totally arbitrary size */
    if (cmccDev->buffer = usbd_alloc (MAX_BUFFER_SIZE))
    {
    if (cmccDev->urb = usbd_alloc_urb (NULL))
    {
    printf (" Succesfully allocated memory for the handles\n");
    }
    }
    pthread_mutex_unlock (&usbMutex);
    }

/* set up the I/O between the driver and the usb device */
int usbCmccIo
(
cmcc_t *cmccDev,
struct usbd_pipe *pipe,
_uint32 flags,
_uint8 *buffer,
_uint32 length
)
{
_uint32 retVal = EIO;

if (usbd_setup_bulk (cmccDev->urb, flags, buffer, length))
    {
    /* Wait till the message is sent/received ?*/
    retVal = usbd_io (cmccDev->urb, pipe, NULL, cmccDev, USBD_TIME_INFINITY);
    }
return retVal;            
}

int usbCmccReceive
(
_uint8 *buffer,
_uint32 length,
cmcc_t *cmccDev
)
{
_uint32 retVal;

return (retVal = usbCmccIo (cmccDev, cmccDev->usbPipeOut, URB_DIR_IN, buffer, length));
}

int usbCmccSend
(
_uint8 *buffer,
_uint32 length,
cmcc_t cmccDev
)
{
_uint32 retVal;
/
copy the user’s data in to the buffer
that is created by usbd_alloc
*/

if (length > MAX_BUFFER_SIZE)
    {
    return EMSGSIZE;
    }            
memcpy (cmccDev->buffer, buffer, length);
return (retVal = usbCmccIo (cmccDev, cmccDev->usbPipeOut, URB_DIR_OUT, cmccDev->buffer, length));
}

void usbCmccRemoval
(
struct usbd_connection *connection,
usbd_device_instance_t *instance
)
{
int numDevices = 0;

printf (" usbCmccRemoval called \n");

/* loop thru the devices to detach the devices */
while ( numDevices < 2)
    {        
    if (usbd_detach (cmccDev->usbDev[numDevices]) == EOK)
        {
        /* sleep for some time ?? */
        }
    numDevices++;        
    }
/* All memory has to be released here */

}

void usbCmccEvent
(
struct usbd_connection *connection,
usbd_device_instance_t *instance,
_uint16 type
)
{
printf (“usbCmccEvent called \n”);

}

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

/* Initialize the global device structure
   for the usb
*/

usbd_funcs_t usbFuncs = 
                      {
                       _USBDI_NFUNCS,
                       usbCmccInsertion,
                       usbCmccRemoval,
                       usbCmccEvent
                      };

//pdev is of type usbd_connect_parm_t structure
pDev = (usbd_connect_parm_t *) malloc (sizeof (usbd_connect_parm_t));

pDev->path = NULL;
pDev->vusb = USB_VERSION;
pDev->vusbd = USBD_VERSION;    
pDev->flags = 0;
pDev->argc = argc;
pDev->argv = argv;
pDev->evtbufsz = 0; /* 0 is the default size (dont know)*/
pDev->ident = &usbIdent;
pDev->funcs = &usbFuncs;    
pDev->connect_wait = USBD_CONNECT_WAIT;

if ((usbd_connect (pDev, &usbHandle)) != EOK)
    {
    printf (" Could not connec to the stack\n");
    return FAILURE;        
    }
else
    {
    printf ("Connected to the USB stack\n");        
    if (cmccDev = (cmcc_t *)malloc (sizeof (cmcc_t)))    
        return FAILURE;	
    
    return OK
     }
}

/* no arguments as of now ?*/
int main
(
int argc,
char *argv[]
)
{

if (usbCmccInit(argc, argv))
    {
    printf ("Initialized USB device \n");
    }
return OK;
}

I noticed that usbd_connect() return an errno of ENOENT which is,
No such file or directory.

Any clues ?

thanks for your help.

Strange, the documentation says that passing NULL into path parameter equates it to /dev/io-usb/io-usb, however that is not so, i kept getting errno 2 (no file or directory) however when i explicitly passed the path into the parameter it worked !!.

thanks everybody :slight_smile:

Hi,
i tried a long time programming a usb driver for qnx with the DDK, but i still don’t get it. you mentioned that you fixed your problem and the driver works now. would you be so kind telling me what’s in your header usbCmccDev.h? That would make it much easier for me to understand your hole code.
Thank you.
Simon