Changeset e50cd7f in mainline for uspace/lib/usb/src/hub.c


Ignore:
Timestamp:
2011-04-17T19:17:55Z (13 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63517c2, cfbbe1d3
Parents:
ef354b6 (diff), 8595577b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

new report structure fixes

File:
1 edited

Legend:

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

    ref354b6 re50cd7f  
    4040#include <errno.h>
    4141#include <assert.h>
     42#include <usb/debug.h>
     43
     44/** How much time to wait between attempts to register endpoint 0:0.
     45 * The value is based on typical value for port reset + some overhead.
     46 */
     47#define ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC (1000 * (10 + 2))
    4248
    4349/** Check that HC connection is alright.
     
    5359        } while (false)
    5460
    55 
    56 /** Tell host controller to reserve default address.
    57  *
    58  * @param connection Opened connection to host controller.
    59  * @param speed Speed of the device that will respond on the default address.
    60  * @return Error code.
    61  */
    62 int usb_hc_reserve_default_address(usb_hc_connection_t *connection,
    63     usb_speed_t speed)
    64 {
    65         CHECK_CONNECTION(connection);
    66 
    67         return async_req_2_0(connection->hc_phone,
    68             DEV_IFACE_ID(USBHC_DEV_IFACE),
    69             IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed);
    70 }
    71 
    72 /** Tell host controller to release default address.
    73  *
    74  * @param connection Opened connection to host controller.
    75  * @return Error code.
    76  */
    77 int usb_hc_release_default_address(usb_hc_connection_t *connection)
    78 {
    79         CHECK_CONNECTION(connection);
    80 
    81         return async_req_1_0(connection->hc_phone,
    82             DEV_IFACE_ID(USBHC_DEV_IFACE),
    83             IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
    84 }
    85 
    8661/** Ask host controller for free address assignment.
    8762 *
     
    178153 * error codes than those listed as return codes by this function itself).
    179154 *
     155 * The @p connection representing connection with host controller does not
     156 * need to be started.
     157 * This function duplicates the connection to allow simultaneous calls of
     158 * this function (i.e. from different fibrils).
     159 *
    180160 * @param[in] parent Parent device (i.e. the hub device).
    181  * @param[in] connection Opened connection to host controller.
     161 * @param[in] connection Connection to host controller.
    182162 * @param[in] dev_speed New device speed.
    183163 * @param[in] enable_port Function for enabling signaling through the port the
     
    206186    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
    207187{
    208         CHECK_CONNECTION(connection);
     188        assert(connection != NULL);
     189        // FIXME: this is awful, we are accessing directly the structure.
     190        usb_hc_connection_t hc_conn = {
     191                .hc_handle = connection->hc_handle,
     192                .hc_phone = -1
     193        };
     194
     195        int rc;
     196
     197        rc = usb_hc_connection_open(&hc_conn);
     198        if (rc != EOK) {
     199                return rc;
     200        }
     201
    209202
    210203        /*
    211204         * Request new address.
    212205         */
    213         usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed);
     206        usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
    214207        if (dev_addr < 0) {
     208                usb_hc_connection_close(&hc_conn);
    215209                return EADDRNOTAVAIL;
    216210        }
    217211
    218         int rc;
    219 
    220         /*
    221          * Reserve the default address.
    222          */
    223         rc = usb_hc_reserve_default_address(connection, dev_speed);
    224         if (rc != EOK) {
    225                 rc = EBUSY;
    226                 goto leave_release_free_address;
    227         }
    228 
    229         /*
    230          * Enable the port (i.e. allow signaling through this port).
    231          */
    232         rc = enable_port(port_no, arg);
    233         if (rc != EOK) {
    234                 goto leave_release_default_address;
    235         }
    236 
    237         /*
    238          * Change the address from default to the free one.
    239          * We need to create a new control pipe for that.
     212        /*
     213         * We will not register control pipe on default address.
     214         * The registration might fail. That means that someone else already
     215         * registered that endpoint. We will simply wait and try again.
     216         * (Someone else already wants to add a new device.)
    240217         */
    241218        usb_device_connection_t dev_conn;
    242219        rc = usb_device_connection_initialize_on_default_address(&dev_conn,
    243             connection);
     220            &hc_conn);
    244221        if (rc != EOK) {
    245222                rc = ENOTCONN;
    246                 goto leave_release_default_address;
     223                goto leave_release_free_address;
    247224        }
    248225
     
    252229        if (rc != EOK) {
    253230                rc = ENOTCONN;
     231                goto leave_release_free_address;
     232        }
     233
     234        do {
     235                rc = usb_pipe_register_with_speed(&ctrl_pipe, dev_speed, 0,
     236                    &hc_conn);
     237                if (rc != EOK) {
     238                        /* Do not overheat the CPU ;-). */
     239                        async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);
     240                }
     241        } while (rc != EOK);
     242
     243        /*
     244         * Endpoint is registered. We can enable the port and change
     245         * device address.
     246         */
     247        rc = enable_port(port_no, arg);
     248        if (rc != EOK) {
    254249                goto leave_release_default_address;
    255250        }
    256251
    257         /* Before sending any traffic, we need to register this
    258          * endpoint.
    259          */
    260         rc = usb_pipe_register(&ctrl_pipe, 0, connection);
    261         if (rc != EOK) {
    262                 rc = EREFUSED;
     252        rc = usb_pipe_probe_default_control(&ctrl_pipe);
     253        if (rc != EOK) {
     254                rc = ESTALL;
    263255                goto leave_release_default_address;
    264256        }
    265         rc = usb_pipe_probe_default_control(&ctrl_pipe);
    266         if (rc != EOK) {
    267                 rc = ENOTCONN;
     257
     258        rc = usb_request_set_address(&ctrl_pipe, dev_addr);
     259        if (rc != EOK) {
     260                rc = ESTALL;
    268261                goto leave_release_default_address;
    269262        }
    270263
    271         rc = usb_pipe_start_session(&ctrl_pipe);
    272         if (rc != EOK) {
    273                 rc = ENOTCONN;
    274                 goto leave_unregister_endpoint;
    275         }
    276 
    277         rc = usb_request_set_address(&ctrl_pipe, dev_addr);
    278         if (rc != EOK) {
    279                 rc = ESTALL;
    280                 goto leave_stop_session;
    281         }
    282 
    283         usb_pipe_end_session(&ctrl_pipe);
    284 
    285         /*
    286          * Register the control endpoint for the new device.
    287          */
    288         rc = usb_pipe_register(&ctrl_pipe, 0, connection);
    289         if (rc != EOK) {
    290                 rc = EREFUSED;
    291                 goto leave_unregister_endpoint;
    292         }
    293 
    294         /*
    295          * Release the original endpoint.
    296          */
    297         unregister_control_endpoint_on_default_address(connection);
    298 
    299         /*
    300          * Once the address is changed, we can return the default address.
    301          */
    302         usb_hc_release_default_address(connection);
    303 
     264        /*
     265         * Address changed. We can release the original endpoint, thus
     266         * allowing other to access the default address.
     267         */
     268        unregister_control_endpoint_on_default_address(&hc_conn);
     269
     270        /*
     271         * Time to register the new endpoint.
     272         */
     273        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
     274        if (rc != EOK) {
     275                goto leave_release_free_address;
     276        }
    304277
    305278        /*
     
    316289        }
    317290
    318 
    319 
    320291        /*
    321292         * And now inform the host controller about the handle.
     
    325296                .handle = child_handle
    326297        };
    327         rc = usb_hc_register_device(connection, &new_device);
     298        rc = usb_hc_register_device(&hc_conn, &new_device);
    328299        if (rc != EOK) {
    329300                rc = EDESTADDRREQ;
     
    349320         * Completely ignoring errors here.
    350321         */
    351 
    352 leave_stop_session:
    353         usb_pipe_end_session(&ctrl_pipe);
    354 
    355 leave_unregister_endpoint:
    356         usb_pipe_unregister(&ctrl_pipe, connection);
    357 
    358322leave_release_default_address:
    359         usb_hc_release_default_address(connection);
     323        usb_pipe_unregister(&ctrl_pipe, &hc_conn);
    360324
    361325leave_release_free_address:
    362         usb_hc_unregister_device(connection, dev_addr);
     326        usb_hc_unregister_device(&hc_conn, dev_addr);
     327
     328        usb_hc_connection_close(&hc_conn);
    363329
    364330        return rc;
Note: See TracChangeset for help on using the changeset viewer.