Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/pipes.c

    rbc1c6fb rf0fdc7d  
    4242#include <assert.h>
    4343
     44#define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
     45
    4446/** Tell USB address assigned to given device.
    4547 *
     
    5153{
    5254        sysarg_t address;
    53 
    5455
    5556        /*
     
    9697}
    9798
     99/** Tell USB address assigned to given device.
     100 *
     101 * @param dev_handle Devman handle of the USB device in question.
     102 * @return USB address or negative error code.
     103 */
     104usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle)
     105{
     106        int parent_phone = devman_parent_device_connect(dev_handle,
     107            IPC_FLAG_BLOCKING);
     108        if (parent_phone < 0) {
     109                return parent_phone;
     110        }
     111
     112        sysarg_t address;
     113
     114        int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
     115            IPC_M_USB_GET_ADDRESS,
     116            dev_handle, &address);
     117
     118        if (rc != EOK) {
     119                return rc;
     120        }
     121
     122        async_hangup(parent_phone);
     123
     124        return (usb_address_t) address;
     125}
     126
    98127/** Initialize connection to USB device.
    99128 *
     
    123152        }
    124153
    125         my_address = get_my_address(parent_phone, dev);
    126         if (my_address < 0) {
    127                 rc = my_address;
    128                 goto leave;
    129         }
     154        /*
     155         * Asking for "my" address may require several attempts.
     156         * That is because following scenario may happen:
     157         *  - parent driver (i.e. driver of parent device) announces new device
     158         *    and devman launches current driver
     159         *  - parent driver is preempted and thus does not send address-handle
     160         *    binding to HC driver
     161         *  - this driver gets here and wants the binding
     162         *  - the HC does not know the binding yet and thus it answers ENOENT
     163         *  So, we need to wait for the HC to learn the binding.
     164         */
     165        do {
     166                my_address = get_my_address(parent_phone, dev);
     167
     168                if (my_address == ENOENT) {
     169                        /* Be nice, let other fibrils run and try again. */
     170                        async_usleep(IPC_AGAIN_DELAY);
     171                } else if (my_address < 0) {
     172                        /* Some other problem, no sense trying again. */
     173                        rc = my_address;
     174                        goto leave;
     175                }
     176
     177        } while (my_address < 0);
    130178
    131179        rc = usb_device_connection_initialize(connection,
Note: See TracChangeset for help on using the changeset viewer.