Changeset bd575647 in mainline for uspace/lib/usbdev/src/pipes.c


Ignore:
Timestamp:
2011-12-11T16:30:42Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7d5ef94
Parents:
2c202c5
Message:

libusbdev: Use shared hc_connection for pipes.

File:
1 edited

Legend:

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

    r2c202c5 rbd575647  
    11/*
    22 * Copyright (c) 2011 Vojtech Horky
     3 * Copyright (c) 2011 Jan Vesely
    34 * All rights reserved.
    45 *
     
    2627 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2728 */
    28 
    2929/** @addtogroup libusbdev
    3030 * @{
     
    3333 * USB endpoint pipes miscellaneous functions.
    3434 */
    35 #include <usb/usb.h>
     35#include <usb_iface.h>
    3636#include <usb/dev/pipes.h>
    37 #include <usb/debug.h>
    38 #include <usb/hc.h>
    39 #include <usbhc_iface.h>
    40 #include <usb_iface.h>
    41 #include <devman.h>
     37#include <usb/dev.h>
    4238#include <errno.h>
    4339#include <assert.h>
    4440#include "pipepriv.h"
    45 
    46 #define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
    47 
    48 /** Tell USB address assigned to given device.
    49  *
    50  * @param sess Session to parent device.
    51  * @param dev Device in question.
    52  * @return USB address or error code.
    53  */
    54 static usb_address_t get_my_address(async_sess_t *sess, const ddf_dev_t *dev)
    55 {
    56         assert(sess);
    57         async_exch_t *exch = async_exchange_begin(sess);
    58         if (!exch)
    59                 return ENOMEM;
    60 
    61         usb_address_t address;
    62         const int ret = usb_get_my_address(exch, &address);
    63 
    64         async_exchange_end(exch);
    65 
    66         return (ret == EOK) ? address : ret;
    67 }
    6841
    6942/** Tell USB interface assigned to given device.
     
    9164
    9265        return ret == EOK ? iface_no : ret;
    93 }
    94 
    95 /** Initialize connection to USB device.
    96  *
    97  * @param connection Connection structure to be initialized.
    98  * @param dev Generic device backing the USB device.
    99  * @return Error code.
    100  */
    101 int usb_device_connection_initialize_from_device(
    102     usb_device_connection_t *connection, const ddf_dev_t *dev)
    103 {
    104         assert(connection);
    105         assert(dev);
    106        
    107         int rc;
    108         devman_handle_t hc_handle;
    109         usb_address_t my_address;
    110        
    111         rc = usb_hc_find(dev->handle, &hc_handle);
    112         if (rc != EOK)
    113                 return rc;
    114        
    115         async_sess_t *parent_sess =
    116             devman_parent_device_connect(EXCHANGE_ATOMIC, dev->handle,
    117             IPC_FLAG_BLOCKING);
    118         if (!parent_sess)
    119                 return ENOMEM;
    120        
    121         /*
    122          * Asking for "my" address may require several attempts.
    123          * That is because following scenario may happen:
    124          *  - parent driver (i.e. driver of parent device) announces new device
    125          *    and devman launches current driver
    126          *  - parent driver is preempted and thus does not send address-handle
    127          *    binding to HC driver
    128          *  - this driver gets here and wants the binding
    129          *  - the HC does not know the binding yet and thus it answers ENOENT
    130          *  So, we need to wait for the HC to learn the binding.
    131          */
    132        
    133         do {
    134                 my_address = get_my_address(parent_sess, dev);
    135                
    136                 if (my_address == ENOENT) {
    137                         /* Be nice, let other fibrils run and try again. */
    138                         async_usleep(IPC_AGAIN_DELAY);
    139                 } else if (my_address < 0) {
    140                         /* Some other problem, no sense trying again. */
    141                         rc = my_address;
    142                         goto leave;
    143                 }
    144        
    145         } while (my_address < 0);
    146        
    147         rc = usb_device_connection_initialize(connection,
    148             hc_handle, my_address);
    149        
    150 leave:
    151         async_hangup(parent_sess);
    152         return rc;
    153 }
    154 
    155 /** Initialize connection to USB device.
    156  *
    157  * @param connection Connection structure to be initialized.
    158  * @param host_controller_handle Devman handle of host controller device is
    159  *      connected to.
    160  * @param device_address Device USB address.
    161  * @return Error code.
    162  */
    163 int usb_device_connection_initialize(usb_device_connection_t *connection,
    164     devman_handle_t host_controller_handle, usb_address_t device_address)
    165 {
    166         assert(connection);
    167 
    168         if ((device_address < 0) || (device_address >= USB11_ADDRESS_MAX)) {
    169                 return EINVAL;
    170         }
    171 
    172         connection->hc_handle = host_controller_handle;
    173         connection->address = device_address;
    174 
    175         return EOK;
    176 }
    177 
    178 /** Initialize connection to USB device on default address.
    179  *
    180  * @param dev_connection Device connection structure to be initialized.
    181  * @param hc_connection Initialized connection to host controller.
    182  * @return Error code.
    183  */
    184 int usb_device_connection_initialize_on_default_address(
    185     usb_device_connection_t *dev_connection,
    186     usb_hc_connection_t *hc_connection)
    187 {
    188         assert(dev_connection);
    189 
    190         if (hc_connection == NULL) {
    191                 return EBADMEM;
    192         }
    193 
    194         return usb_device_connection_initialize(dev_connection,
    195             hc_connection->hc_handle, (usb_address_t) 0);
    19666}
    19767
Note: See TracChangeset for help on using the changeset viewer.