Jump to main content

##

# 4.1.4 Opening the Driver

The USB Host Stack and the USB Device Stack must obtain a handle to the USB Driver to access the functionality of the driver. This handle is obtained through the USB Driver Open function. The DRV_USB_DEVICE_INTERFACE structure and DRV_USB_DEVICE_HOST_INTERFACE structure provide access to the USB Driver Open function through the `open` member of these structures. Calling the Open function may not return a valid driver handle the first time the function is called. In fact, the USB Driver will return an invalid driver handle until the driver is ready to be opened. The Host and the Device Stack call the Open function repetitively in a state machine, until the function returns a valid handle.

The USB Host Stack can open the USB Driver but can call its Host mode functions only if the USB Driver was initialized for Host mode or Dual Role operation. The USB Host Stack accesses the driver functions through the DRV_USB_HOST_INTERFACE pointer that was provided to the Host Layer through the Host Stack initialization. The USB Device Stack can open the USB Driver but can call its Device mode functions only if the USB Driver was initialized for Device mode or Dual Role operation. The USB Device Stack accesses the driver functions through the DRV_USB_HOST_INTERFACE pointer that was provided to the Host Layer through the Host Stack initialization.

The following code example shows how the USB Host Layer opens the USB Driver.

    /* This code example shows how the Host Layer open the HCD via the hcdInterface.
     * The driver handle is stored in hcdHandle member of the busObj data structure.
     * The busObj data structure Host Layer local data structure. The Host Layer
     * opens the HCD when the bus is enabled. This operation takes place in the
     * USB_HOST_BUS_STATE_ENABLING state. */
    /* Note the Host Layer calls the Open function by accessing the open member of
     * the hcdInterface which is of the type DRV_USB_HOST_INTERFACE. Also note how
     * the function is called repetitively until the Open function returns a valid
     * handle. */
        case USB_HOST_BUS_STATE_ENABLING:

        /* The bus is being enabled. Try opening the HCD */
        busObj->hcdHandle = busObj->hcdInterface->open(busObj->hcdIndex, DRV_IO_INTENT_EXCLUSIVE |
                DRV_IO_INTENT_NONBLOCKING | DRV_IO_INTENT_READWRITE );

        /* Validate the Open function status */
        if (DRV_HANDLE_INVALID == busObj->hcdHandle )
        {
            /* The driver may not open the first time. This is okay. We
             * should try opening it again. The state of bus is not
             * changed. */
        }

The following code example shows how the USB Device Layer opens the USB Driver.

    /* This code example shows how the USB Device Layer calls the USBCD open
     * function to open the USBCD. The Device Layer accesses the USBCD Open function
     * through the driverInterface member of the usbDeviceInstanceState object. The
     * driverInterface member is a DRV_USB_DEVICE_INTERFACE type. The
     * usbDeviceInstanceState is a USB Device Layer local object. */
    /* The Device Layer attempts to open the USBCD when it is initializing. Note how
     * the Device Layer advances to the next state only when the USBCD returns a
     * valid handle.   */
    switch(usbDeviceThisInstance->taskState)
    {
        case USB_DEVICE_TASK_STATE_OPENING_USBCD:

            /* Try to open the driver handle. This could fail if the driver is
             * not ready to be opened. */
            usbDeviceThisInstance->usbCDHandle =
               usbDeviceThisInstance->driverInterface->open( usbDeviceThisInstance->driverIndex,
               DRV_IO_INTENT_EXCLUSIVE|DRV_IO_INTENT_NONBLOCKING|DRV_IO_INTENT_READWRITE);

            /* Check if the driver was opened */
            if(usbDeviceThisInstance->usbCDHandle != DRV_HANDLE_INVALID)
            {
                /* Yes the driver could be opened. */
                /* Advance the state to the next state */
                usbDeviceThisInstance->taskState = USB_DEVICE_TASK_STATE_RUNNING;

                /* Update the USB Device Layer state to indicate that it can be
                 * opened */
                usbDeviceThisInstance->usbDeviceInstanceState = SYS_STATUS_READY;
            }

            break;