Changeset 3238506 in mainline


Ignore:
Timestamp:
2011-11-04T19:22:01Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2179cf95
Parents:
bbd09694
Message:

libusbdev: Make usb_request_set_address private.

This function causes to much trouble to be a part of the library interface.
Anyone crazy enough to change device address should add a separate wrapper
and solve all the problems it causes.

usb_request_set_address takes care of endpoint registration now.

Location:
uspace/lib/usbdev
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbdev/include/usb/dev/request.h

    rbbd09694 r3238506  
    115115int usb_request_set_feature(usb_pipe_t *, usb_request_type_t,
    116116    usb_request_recipient_t, uint16_t, uint16_t);
    117 int usb_request_set_address(usb_pipe_t *, usb_address_t);
    118117int usb_request_get_descriptor(usb_pipe_t *, usb_request_type_t,
    119     usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 
     118    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t,
    120119    size_t *);
    121120int usb_request_get_descriptor_alloc(usb_pipe_t *, usb_request_type_t,
  • uspace/lib/usbdev/src/hub.c

    rbbd09694 r3238506  
    133133}
    134134
    135 
    136 static void unregister_control_endpoint_on_default_address(
    137     usb_hc_connection_t *connection)
     135/** Change address of connected device.
     136 * This function automatically updates the backing connection to point to
     137 * the new address. It also unregisterrs the old endpoint and registers
     138 * a new one.
     139 * This creates whole bunch of problems:
     140 *  1. All pipes using this wire are broken because they are not
     141 *     registered for new address
     142 *  2. All other pipes for this device are using wrong address,
     143 *     possibly targeting completely different device
     144 *
     145 * @param pipe Control endpoint pipe (session must be already started).
     146 * @param new_address New USB address to be set (in native endianness).
     147 * @return Error code.
     148 */
     149static int usb_request_set_address(usb_pipe_t *pipe, usb_address_t new_address,
     150    usb_hc_connection_t *hc_conn)
    138151{
    139         usb_device_connection_t dev_conn;
    140         int rc = usb_device_connection_initialize_on_default_address(&dev_conn,
    141             connection);
    142         if (rc != EOK) {
    143                 return;
    144         }
    145 
    146         usb_pipe_t ctrl_pipe;
    147         rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
    148         if (rc != EOK) {
    149                 return;
    150         }
    151 
    152         usb_pipe_unregister(&ctrl_pipe, connection);
     152        if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
     153                return EINVAL;
     154        }
     155        assert(pipe);
     156        assert(hc_conn);
     157        assert(pipe->wire != NULL);
     158
     159        const uint16_t addr = uint16_host2usb((uint16_t)new_address);
     160
     161        int rc = usb_control_request_set(pipe,
     162            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     163            USB_DEVREQ_SET_ADDRESS, addr, 0, NULL, 0);
     164
     165        if (rc != EOK) {
     166                return rc;
     167        }
     168
     169        /* TODO: prevent others from accessing the wire now. */
     170        if (usb_pipe_unregister(pipe, hc_conn) != EOK) {
     171                usb_log_warning(
     172                    "Failed to unregister the old pipe on address change.\n");
     173        }
     174        /* The address is already changed so set it in the wire */
     175        pipe->wire->address = new_address;
     176        rc = usb_pipe_register(pipe, 0, hc_conn);
     177        if (rc != EOK)
     178                return EADDRNOTAVAIL;
     179
     180        return EOK;
    153181}
    154182
     
    225253         */
    226254        usb_address_t dev_addr =
    227             usb_hc_request_address(&hc_conn, 1, false, dev_speed);
     255            usb_hc_request_address(&hc_conn, 0, false, dev_speed);
    228256        if (dev_addr < 0) {
    229257                rc = EADDRNOTAVAIL;
     
    246274
    247275        usb_pipe_t ctrl_pipe;
    248         rc = usb_pipe_initialize_default_control(&ctrl_pipe,
    249             &dev_conn);
     276        rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
    250277        if (rc != EOK) {
    251278                rc = ENOTCONN;
     
    256283                rc = usb_hc_request_address(&hc_conn, USB_ADDRESS_DEFAULT,
    257284                    true, dev_speed);
    258                 if (rc != USB_ADDRESS_DEFAULT) {
     285                if (rc == ENOENT) {
    259286                        /* Do not overheat the CPU ;-). */
    260287                        async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);
    261288                }
    262289        } while (rc == ENOENT);
    263         if (rc != EOK) {
     290        if (rc < 0) {
    264291                goto leave_release_free_address;
    265292        }
    266293
     294        /* Register control pipe on default address. */
    267295        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    268296        if (rc != EOK) {
     
    283311         * above might use much of this time so we should only wait to fill
    284312         * up the 100ms quota*/
    285         suseconds_t elapsed = tv_sub(&end_time, &start_time);
     313        const suseconds_t elapsed = tv_sub(&end_time, &start_time);
    286314        if (elapsed < 100000) {
    287315                async_usleep(100000 - elapsed);
    288316        }
    289317
    290         /*
    291          * Endpoint is registered. We can enable the port and change
    292          * device address.
    293          */
     318        /* Endpoint is registered. We can enable the port and change address. */
    294319        rc = enable_port(arg);
    295320        if (rc != EOK) {
     
    303328        async_usleep(10000);
    304329
     330        /* Get max_packet_size value. */
    305331        rc = usb_pipe_probe_default_control(&ctrl_pipe);
    306332        if (rc != EOK) {
     
    309335        }
    310336
    311         rc = usb_request_set_address(&ctrl_pipe, dev_addr);
     337        rc = usb_request_set_address(&ctrl_pipe, dev_addr, &hc_conn);
    312338        if (rc != EOK) {
    313339                rc = ESTALL;
     
    315341        }
    316342
    317         /*
    318          * Address changed. We can release the original endpoint, thus
    319          * allowing other to access the default address.
    320          */
    321         unregister_control_endpoint_on_default_address(&hc_conn);
     343        /* Address changed. We can release the default, thus
     344         * allowing other to access the default address. */
    322345        usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT);
    323346
    324         /*
    325          * Time to register the new endpoint.
    326          */
    327         rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    328         if (rc != EOK) {
    329                 goto leave_release_free_address;
    330         }
    331 
    332         /*
    333          * It is time to register the device with devman.
    334          */
     347        /* Register the device with devman. */
    335348        /* FIXME: create device_register that will get opened ctrl pipe. */
    336349        ddf_fun_t *child_fun;
     
    347360
    348361
    349         /*
    350          * And now inform the host controller about the handle.
    351          */
     362        /* Inform the host controller about the handle. */
    352363        rc = usb_hc_register_device(&hc_conn, &new_device);
    353364        if (rc != EOK) {
     
    361372        }
    362373
    363         /*
    364          * And we are done.
    365          */
    366374        if (assigned_address != NULL) {
    367375                *assigned_address = dev_addr;
    368376        }
    369         if (new_fun != NULL) {
    370                 *new_fun = child_fun;
    371         }
     377
     378        *new_fun = child_fun;
    372379
    373380        rc = EOK;
     
    382389
    383390leave_release_free_address:
    384         if (usb_hc_unregister_device(&hc_conn, dev_addr) != EOK)
    385                 usb_log_warning("%s: Failed to unregister device.\n",
    386                     __FUNCTION__);
    387391        /* This might be either 0:0 or dev_addr:0 */
    388392        if (usb_pipe_unregister(&ctrl_pipe, &hc_conn) != EOK)
     
    390394                    __FUNCTION__);
    391395
     396        if (usb_hc_unregister_device(&hc_conn, dev_addr) != EOK)
     397                usb_log_warning("%s: Failed to unregister device.\n",
     398                    __FUNCTION__);
     399
    392400close_connection:
    393401        if (usb_hc_connection_close(&hc_conn) != EOK)
    394                 usb_log_warning("%s: Failed to close connection.\n",
     402                usb_log_warning("%s: Failed to close hc connection.\n",
    395403                    __FUNCTION__);
    396404
  • uspace/lib/usbdev/src/request.c

    rbbd09694 r3238506  
    250250}
    251251
    252 /** Change address of connected device.
    253  * This function automatically updates the backing connection to point to
    254  * the new address.
    255  *
    256  * @param pipe Control endpoint pipe (session must be already started).
    257  * @param new_address New USB address to be set (in native endianness).
    258  * @return Error code.
    259  */
    260 int usb_request_set_address(usb_pipe_t *pipe,
    261     usb_address_t new_address)
    262 {
    263         if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
    264                 return EINVAL;
    265         }
    266 
    267         uint16_t addr = uint16_host2usb((uint16_t)new_address);
    268 
    269         int rc = usb_control_request_set(pipe,
    270             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    271             USB_DEVREQ_SET_ADDRESS,
    272             addr, 0,
    273             NULL, 0);
    274 
    275         if (rc != EOK) {
    276                 return rc;
    277         }
    278 
    279         assert(pipe->wire != NULL);
    280         /* TODO: prevent other from accessing wire now. */
    281         pipe->wire->address = new_address;
    282 
    283         return EOK;
    284 }
    285 
    286252/** Retrieve USB descriptor of a USB device.
    287253 *
Note: See TracChangeset for help on using the changeset viewer.