Changeset 867e6735 in mainline


Ignore:
Timestamp:
2011-02-18T19:55:39Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
228f251
Parents:
72363a1 (diff), b6c7da6 (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:

Merge development/ changes

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/iface.c

    r72363a1 r867e6735  
    5454}
    5555/*----------------------------------------------------------------------------*/
    56 static int reserve_default_address(device_t *dev)
     56static int reserve_default_address(device_t *dev, usb_speed_t speed)
    5757{
    5858        assert(dev);
     
    7272}
    7373/*----------------------------------------------------------------------------*/
    74 static int request_address(device_t *dev, usb_address_t *address)
     74static int request_address(device_t *dev, usb_speed_t speed,
     75    usb_address_t *address)
    7576{
    7677        assert(dev);
     
    103104/*----------------------------------------------------------------------------*/
    104105static int interrupt_out(device_t *dev, usb_target_t target,
    105     void *data, size_t size,
    106     usbhc_iface_transfer_out_callback_t callback, void *arg)
    107 {
    108         size_t max_packet_size = 8;
     106    size_t max_packet_size,
     107    void *data, size_t size,
     108    usbhc_iface_transfer_out_callback_t callback, void *arg)
     109{
    109110        dev_speed_t speed = FULL_SPEED;
    110111
     
    118119/*----------------------------------------------------------------------------*/
    119120static int interrupt_in(device_t *dev, usb_target_t target,
    120     void *data, size_t size,
    121     usbhc_iface_transfer_in_callback_t callback, void *arg)
    122 {
    123         size_t max_packet_size = 4;
     121    size_t max_packet_size,
     122    void *data, size_t size,
     123    usbhc_iface_transfer_in_callback_t callback, void *arg)
     124{
    124125        dev_speed_t speed = FULL_SPEED;
    125126
     
    133134/*----------------------------------------------------------------------------*/
    134135static int control_write(device_t *dev, usb_target_t target,
     136    size_t max_packet_size,
    135137    void *setup_data, size_t setup_size, void *data, size_t size,
    136138    usbhc_iface_transfer_out_callback_t callback, void *arg)
    137139{
    138         size_t max_packet_size = 8;
    139140        dev_speed_t speed = FULL_SPEED;
    140141
     
    149150/*----------------------------------------------------------------------------*/
    150151static int control_read(device_t *dev, usb_target_t target,
     152    size_t max_packet_size,
    151153    void *setup_data, size_t setup_size, void *data, size_t size,
    152154    usbhc_iface_transfer_in_callback_t callback, void *arg)
    153155{
    154         size_t max_packet_size = 8;
    155156        dev_speed_t speed = FULL_SPEED;
    156157
     
    165166/*----------------------------------------------------------------------------*/
    166167static int control_write_setup(device_t *dev, usb_target_t target,
    167     void *data, size_t size,
    168     usbhc_iface_transfer_out_callback_t callback, void *arg)
     168    size_t max_packet_size,
     169    void *data, size_t size,
     170    usbhc_iface_transfer_out_callback_t callback, void *arg)
     171{
     172        dev_speed_t speed = FULL_SPEED;
     173
     174        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     175        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     176            max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
     177        if (!batch)
     178                return ENOMEM;
     179        batch_control_setup_old(batch);
     180        return EOK;
     181}
     182/*----------------------------------------------------------------------------*/
     183static int control_write_data(device_t *dev, usb_target_t target,
     184    size_t max_packet_size,
     185    void *data, size_t size,
     186    usbhc_iface_transfer_out_callback_t callback, void *arg)
     187{
     188        dev_speed_t speed = FULL_SPEED;
     189
     190        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     191        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     192            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
     193        if (!batch)
     194                return ENOMEM;
     195        batch_control_write_data_old(batch);
     196        return EOK;
     197}
     198/*----------------------------------------------------------------------------*/
     199static int control_write_status(device_t *dev, usb_target_t target,
     200    usbhc_iface_transfer_in_callback_t callback, void *arg)
    169201{
    170202        size_t max_packet_size = 8;
     
    173205        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    174206        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     207            max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg);
     208        if (!batch)
     209                return ENOMEM;
     210        batch_control_write_status_old(batch);
     211        return EOK;
     212}
     213/*----------------------------------------------------------------------------*/
     214static int control_read_setup(device_t *dev, usb_target_t target,
     215    size_t max_packet_size,
     216    void *data, size_t size,
     217    usbhc_iface_transfer_out_callback_t callback, void *arg)
     218{
     219        dev_speed_t speed = FULL_SPEED;
     220
     221        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     222        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    175223            max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
    176224        if (!batch)
     
    180228}
    181229/*----------------------------------------------------------------------------*/
    182 static int control_write_data(device_t *dev, usb_target_t target,
    183     void *data, size_t size,
    184     usbhc_iface_transfer_out_callback_t callback, void *arg)
    185 {
    186         size_t max_packet_size = 8;
    187         dev_speed_t speed = FULL_SPEED;
    188 
    189         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    190         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    191             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
    192         if (!batch)
    193                 return ENOMEM;
    194         batch_control_write_data_old(batch);
    195         return EOK;
    196 }
    197 /*----------------------------------------------------------------------------*/
    198 static int control_write_status(device_t *dev, usb_target_t target,
    199     usbhc_iface_transfer_in_callback_t callback, void *arg)
    200 {
    201         size_t max_packet_size = 8;
    202         dev_speed_t speed = FULL_SPEED;
    203 
    204         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    205         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    206             max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg);
    207         if (!batch)
    208                 return ENOMEM;
    209         batch_control_write_status_old(batch);
    210         return EOK;
    211 }
    212 /*----------------------------------------------------------------------------*/
    213 static int control_read_setup(device_t *dev, usb_target_t target,
    214     void *data, size_t size,
    215     usbhc_iface_transfer_out_callback_t callback, void *arg)
    216 {
    217         size_t max_packet_size = 8;
    218         dev_speed_t speed = FULL_SPEED;
    219 
    220         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    221         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    222             max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
    223         if (!batch)
    224                 return ENOMEM;
    225         batch_control_setup_old(batch);
    226         return EOK;
    227 }
    228 /*----------------------------------------------------------------------------*/
    229230static int control_read_data(device_t *dev, usb_target_t target,
    230     void *data, size_t size,
    231     usbhc_iface_transfer_in_callback_t callback, void *arg)
    232 {
    233         size_t max_packet_size = 8;
     231    size_t max_packet_size,
     232    void *data, size_t size,
     233    usbhc_iface_transfer_in_callback_t callback, void *arg)
     234{
    234235        dev_speed_t speed = FULL_SPEED;
    235236
  • uspace/drv/uhci-rhd/port.c

    r72363a1 r867e6735  
    131131        return EOK;
    132132}
    133 /*----------------------------------------------------------------------------*/
    134 static int uhci_port_new_device(uhci_port_t *port)
    135 {
    136         assert(port);
    137         assert(usb_hc_connection_is_opened(&port->hc_connection));
    138 
    139         usb_log_info("Adding new device on port %d.\n", port->number);
    140 
    141         /* get address of the future device */
    142         const usb_address_t usb_address = usb_hc_request_address(&port->hc_connection);
    143 
    144         if (usb_address <= 0) {
    145                 usb_log_error("Recieved invalid address(%d).\n", usb_address);
    146                 return usb_address;
    147         }
    148         usb_log_debug("Sucessfully obtained address %d for port %d.\n",
    149             usb_address, port->number);
    150 
    151         /* get default address */
    152         int ret = usb_hc_reserve_default_address(&port->hc_connection);
    153         if (ret != EOK) {
    154                 usb_log_error("Failed to reserve default address on port %d.\n",
    155                     port->number);
    156                 int ret2 = usb_hc_unregister_device(&port->hc_connection,
    157                     usb_address);
    158                 if (ret2 != EOK) {
    159                         usb_log_fatal("Failed to return requested address on port %d.\n",
    160                            port->number);
    161                         return ret2;
    162                 }
    163                 usb_log_debug("Successfully returned reserved address on port %d.\n",
    164                         port->number);
    165                 return ret;
    166         }
    167         usb_log_debug("Sucessfully obtained default address for port %d.\n",
    168             port->number);
     133
     134/** Callback for enabling port during adding a new device.
     135 *
     136 * @param portno Port number (unused).
     137 * @param arg Pointer to uhci_port_t of port with the new device.
     138 * @return Error code.
     139 */
     140static int new_device_enable_port(int portno, void *arg)
     141{
     142        uhci_port_t *port = (uhci_port_t *) arg;
     143
     144        usb_log_debug("new_device_enable_port(%d)\n", port->number);
    169145
    170146        /*
    171          * the host then waits for at least 100 ms to allow completion of
     147         * The host then waits for at least 100 ms to allow completion of
    172148         * an insertion process and for power at the device to become stable.
    173149         */
    174150        async_usleep(100000);
    175151
    176         /* enable port */
     152        /* Enable the port. */
    177153        uhci_port_set_enabled(port, true);
    178154
     
    196172        }
    197173
    198         /*
    199          * Initialize connection to the device.
    200          */
    201         /* FIXME: check for errors. */
    202         usb_device_connection_t new_dev_connection;
    203         usb_endpoint_pipe_t new_dev_ctrl_pipe;
    204         usb_device_connection_initialize_on_default_address(
    205             &new_dev_connection, &port->hc_connection);
    206         usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe,
    207             &new_dev_connection);
    208 
    209         /*
    210          * Assign new address to the device. This function updates
    211          * the backing connection to still point to the same device.
    212          */
    213         /* FIXME: check for errors. */
    214         usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe);
    215         ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address);
    216         usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe);
    217 
    218         if (ret != EOK) { /* address assigning went wrong */
    219                 usb_log_error("Failed(%d) to assign address to the device.\n", ret);
     174        return EOK;
     175}
     176
     177/*----------------------------------------------------------------------------*/
     178static int uhci_port_new_device(uhci_port_t *port)
     179{
     180        assert(port);
     181        assert(usb_hc_connection_is_opened(&port->hc_connection));
     182
     183        usb_log_info("Detected new device on port %u.\n", port->number);
     184
     185        usb_address_t dev_addr;
     186        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
     187            USB_SPEED_FULL,
     188            new_device_enable_port, port->number, port,
     189            &dev_addr, &port->attached_device);
     190        if (rc != EOK) {
     191                usb_log_error("Failed adding new device on port %u: %s.\n",
     192                    port->number, str_error(rc));
    220193                uhci_port_set_enabled(port, false);
    221                 int release = usb_hc_release_default_address(&port->hc_connection);
    222                 if (release != EOK) {
    223                         usb_log_error("Failed to release default address on port %d.\n",
    224                             port->number);
    225                         return release;
    226                 }
    227                 usb_log_debug("Sucessfully released default address on port %d.\n",
    228                     port->number);
    229                 return ret;
    230         }
    231         usb_log_debug("Sucessfully assigned address %d for port %d.\n",
    232             usb_address, port->number);
    233 
    234         /* release default address */
    235         ret = usb_hc_release_default_address(&port->hc_connection);
    236         if (ret != EOK) {
    237                 usb_log_error("Failed to release default address on port %d.\n",
    238                     port->number);
    239                 return ret;
    240         }
    241         usb_log_debug("Sucessfully released default address on port %d.\n",
    242             port->number);
    243 
    244         /* communicate and possibly report to devman */
    245         assert(port->attached_device == 0);
    246 
    247         ret = usb_device_register_child_in_devman(new_dev_connection.address,
    248             new_dev_connection.hc_handle, port->rh, &port->attached_device);
    249 
    250         if (ret != EOK) { /* something went wrong */
    251                 usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret);
    252                 uhci_port_set_enabled(port, false);
    253                 return ENOMEM;
    254         }
    255         usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n",
    256                 port->number, usb_address, port->attached_device);
    257 
    258         /*
    259          * Register the device in the host controller.
    260          */
    261         usb_hc_attached_device_t new_device = {
    262                 .address = new_dev_connection.address,
    263                 .handle = port->attached_device
    264         };
    265 
    266         ret = usb_hc_register_device(&port->hc_connection, &new_device);
    267         // TODO: proper error check here
    268         assert(ret == EOK);
    269 
    270         return EOK;
    271 }
     194                return rc;
     195        }
     196
     197        usb_log_info("New device on port %u has address %d (handle %zu).\n",
     198            port->number, dev_addr, port->attached_device);
     199
     200        return EOK;
     201}
     202
    272203/*----------------------------------------------------------------------------*/
    273204static int uhci_port_remove_device(uhci_port_t *port)
  • uspace/drv/vhc/connhost.c

    r72363a1 r867e6735  
    276276
    277277static int interrupt_out(device_t *dev, usb_target_t target,
     278    size_t max_packet_size,
    278279    void *data, size_t size,
    279280    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    285286
    286287static int interrupt_in(device_t *dev, usb_target_t target,
     288    size_t max_packet_size,
    287289    void *data, size_t size,
    288290    usbhc_iface_transfer_in_callback_t callback, void *arg)
     
    294296
    295297static int control_write_setup(device_t *dev, usb_target_t target,
     298    size_t max_packet_size,
    296299    void *data, size_t size,
    297300    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    303306
    304307static int control_write_data(device_t *dev, usb_target_t target,
     308    size_t max_packet_size,
    305309    void *data, size_t size,
    306310    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    320324
    321325static int control_write(device_t *dev, usb_target_t target,
     326    size_t max_packet_size,
    322327    void *setup_packet, size_t setup_packet_size,
    323328    void *data, size_t data_size,
     
    337342
    338343static int control_read_setup(device_t *dev, usb_target_t target,
     344    size_t max_packet_size,
    339345    void *data, size_t size,
    340346    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    346352
    347353static int control_read_data(device_t *dev, usb_target_t target,
     354    size_t max_packet_size,
    348355    void *data, size_t size,
    349356    usbhc_iface_transfer_in_callback_t callback, void *arg)
     
    363370
    364371static int control_read(device_t *dev, usb_target_t target,
     372    size_t max_packet_size,
    365373    void *setup_packet, size_t setup_packet_size,
    366374    void *data, size_t data_size,
     
    382390
    383391
    384 static int reserve_default_address(device_t *dev)
     392static int reserve_default_address(device_t *dev, usb_speed_t ignored)
    385393{
    386394        usb_address_keeping_reserve_default(&addresses);
     
    394402}
    395403
    396 static int request_address(device_t *dev, usb_address_t *address)
     404static int request_address(device_t *dev, usb_speed_t ignored,
     405    usb_address_t *address)
    397406{
    398407        usb_address_t addr = usb_address_keeping_request(&addresses);
  • uspace/lib/c/generic/str_error.c

    r72363a1 r867e6735  
    7373                case EBADCHECKSUM:
    7474                        return "Bad checksum";
     75                case ESTALL:
     76                        return "Operation stalled";
    7577                case EAGAIN:
    7678                        return "Resource temporarily unavailable";
  • uspace/lib/c/include/errno.h

    r72363a1 r867e6735  
    5959#define EBADCHECKSUM  (-300)
    6060
     61/** USB: stalled operation. */
     62#define ESTALL (-301)
     63
    6164/** An API function is called while another blocking function is in progress. */
    6265#define EINPROGRESS  (-10036)
  • uspace/lib/drv/generic/remote_usbhc.c

    r72363a1 r867e6735  
    4040
    4141#define USB_MAX_PAYLOAD_SIZE 1020
     42#define HACK_MAX_PACKET_SIZE 8
     43#define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4
    4244
    4345static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    163165                return;
    164166        }
    165 
    166         int rc = usb_iface->reserve_default_address(device);
     167       
     168        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
     169       
     170        int rc = usb_iface->reserve_default_address(device, speed);
    167171
    168172        async_answer_0(callid, rc);
     
    193197                return;
    194198        }
     199       
     200        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    195201
    196202        usb_address_t address;
    197         int rc = usb_iface->request_address(device, &address);
     203        int rc = usb_iface->request_address(device, speed, &address);
    198204        if (rc != EOK) {
    199205                async_answer_0(callid, rc);
     
    322328        trans->size = len;
    323329
    324         int rc = transfer_func(device, target, buffer, len,
     330        int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE,
     331            buffer, len,
    325332            callback_out, trans);
    326333
     
    368375        trans->size = len;
    369376
    370         int rc = transfer_func(device, target, trans->buffer, len,
     377        int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE_INTERRUPT_IN,
     378            trans->buffer, len,
    371379            callback_in, trans);
    372380
     
    576584        trans->size = data_buffer_len;
    577585
    578         rc = usb_iface->control_write(device, target,
     586        rc = usb_iface->control_write(device, target, HACK_MAX_PACKET_SIZE,
    579587            setup_packet, setup_packet_len,
    580588            data_buffer, data_buffer_len,
     
    640648        }
    641649
    642         rc = usb_iface->control_read(device, target,
     650        rc = usb_iface->control_read(device, target, HACK_MAX_PACKET_SIZE,
    643651            setup_packet, setup_packet_len,
    644652            trans->buffer, trans->size,
  • uspace/lib/drv/include/usbhc_iface.h

    r72363a1 r867e6735  
    4040#include "driver.h"
    4141#include <usb/usb.h>
     42#include <bool.h>
    4243
    4344
     
    215216
    216217/** Out transfer processing function prototype. */
    217 typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t,
     218typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t, size_t,
    218219    void *, size_t,
    219220    usbhc_iface_transfer_out_callback_t, void *);
    220221
    221 /** Setup transfer processing function prototype. */
     222/** Setup transfer processing function prototype. @deprecated */
    222223typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t;
    223224
    224225/** In transfer processing function prototype. */
    225 typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t,
     226typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t, size_t,
    226227    void *, size_t,
    227228    usbhc_iface_transfer_in_callback_t, void *);
     
    231232        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
    232233
    233         int (*reserve_default_address)(device_t *);
     234        int (*reserve_default_address)(device_t *, usb_speed_t);
    234235        int (*release_default_address)(device_t *);
    235         int (*request_address)(device_t *, usb_address_t *);
     236        int (*request_address)(device_t *, usb_speed_t, usb_address_t *);
    236237        int (*bind_address)(device_t *, usb_address_t, devman_handle_t);
    237238        int (*release_address)(device_t *, usb_address_t);
     
    251252
    252253        int (*control_write)(device_t *, usb_target_t,
     254            size_t,
    253255            void *, size_t, void *, size_t,
    254256            usbhc_iface_transfer_out_callback_t, void *);
    255257
    256258        int (*control_read)(device_t *, usb_target_t,
     259            size_t,
    257260            void *, size_t, void *, size_t,
    258261            usbhc_iface_transfer_in_callback_t, void *);
  • uspace/lib/usb/include/usb/hub.h

    r72363a1 r867e6735  
    3939#include <usb/usbdevice.h>
    4040
     41int usb_hc_new_device_wrapper(device_t *, usb_hc_connection_t *, usb_speed_t,
     42    int (*)(int, void *), int, void *, usb_address_t *, devman_handle_t *);
     43
    4144/** Info about device attached to host controller.
    4245 *
     
    5255} usb_hc_attached_device_t;
    5356
    54 int usb_hc_reserve_default_address(usb_hc_connection_t *);
     57int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t);
    5558int usb_hc_release_default_address(usb_hc_connection_t *);
    5659
    57 usb_address_t usb_hc_request_address(usb_hc_connection_t *);
     60usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
    5861int usb_hc_register_device(usb_hc_connection_t *,
    5962    const usb_hc_attached_device_t *);
  • uspace/lib/usb/include/usb/usb.h

    r72363a1 r867e6735  
    6868        USB_DIRECTION_BOTH
    6969} usb_direction_t;
     70
     71/** USB speeds. */
     72typedef enum {
     73        /** USB 1.1 low speed (1.5Mbits/s). */
     74        USB_SPEED_LOW,
     75        /** USB 1.1 full speed (12Mbits/s). */
     76        USB_SPEED_FULL,
     77        /** USB 2.0 high speed (480Mbits/s). */
     78        USB_SPEED_HIGH
     79} usb_speed_t;
    7080
    7181/** USB request type target. */
  • uspace/lib/usb/src/hub.c

    r72363a1 r867e6735  
    3434 */
    3535#include <usb/hub.h>
     36#include <usb/pipes.h>
     37#include <usb/request.h>
     38#include <usb/recognise.h>
    3639#include <usbhc_iface.h>
    3740#include <errno.h>
     
    5558 * @return Error code.
    5659 */
    57 int usb_hc_reserve_default_address(usb_hc_connection_t *connection)
     60int usb_hc_reserve_default_address(usb_hc_connection_t *connection,
     61    usb_speed_t speed)
     62{
     63        CHECK_CONNECTION(connection);
     64
     65        return async_req_2_0(connection->hc_phone,
     66            DEV_IFACE_ID(USBHC_DEV_IFACE),
     67            IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed);
     68}
     69
     70/** Tell host controller to release default address.
     71 *
     72 * @param connection Opened connection to host controller.
     73 * @return Error code.
     74 */
     75int usb_hc_release_default_address(usb_hc_connection_t *connection)
    5876{
    5977        CHECK_CONNECTION(connection);
     
    6179        return async_req_1_0(connection->hc_phone,
    6280            DEV_IFACE_ID(USBHC_DEV_IFACE),
    63             IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
    64 }
    65 
    66 /** Tell host controller to release default address.
    67  *
    68  * @param connection Opened connection to host controller.
    69  * @return Error code.
    70  */
    71 int usb_hc_release_default_address(usb_hc_connection_t *connection)
    72 {
    73         CHECK_CONNECTION(connection);
    74 
    75         return async_req_1_0(connection->hc_phone,
    76             DEV_IFACE_ID(USBHC_DEV_IFACE),
    7781            IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
    7882}
     
    8387 * @return Assigned USB address or negative error code.
    8488 */
    85 usb_address_t usb_hc_request_address(usb_hc_connection_t *connection)
     89usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
     90    usb_speed_t speed)
    8691{
    8792        CHECK_CONNECTION(connection);
    8893
    8994        sysarg_t address;
    90         int rc = async_req_1_1(connection->hc_phone,
    91             DEV_IFACE_ID(USBHC_DEV_IFACE),
    92             IPC_M_USBHC_REQUEST_ADDRESS, &address);
     95        int rc = async_req_2_1(connection->hc_phone,
     96            DEV_IFACE_ID(USBHC_DEV_IFACE),
     97            IPC_M_USBHC_REQUEST_ADDRESS, speed,
     98            &address);
    9399        if (rc != EOK) {
    94100                return (usb_address_t) rc;
     
    135141
    136142
     143/** Wrapper for registering attached device to the hub.
     144 *
     145 * The @p enable_port function is expected to enable singalling on given
     146 * port.
     147 * The two arguments to it can have arbitrary meaning
     148 * (the @p port_no is only a suggestion)
     149 * and are not touched at all by this function
     150 * (they are passed as is to the @p enable_port function).
     151 *
     152 * If the @p enable_port fails (i.e. does not return EOK), the device
     153 * addition is cancelled.
     154 * The return value is then returned (it is good idea to use different
     155 * error codes than those listed as return codes by this function itself).
     156 *
     157 * @param parent Parent device (i.e. the hub device).
     158 * @param connection Opened connection to host controller.
     159 * @param dev_speed New device speed.
     160 * @param enable_port Function for enabling signalling through the port the
     161 *      device is attached to.
     162 * @param port_no Port number (passed through to @p enable_port).
     163 * @param arg Any data argument to @p enable_port.
     164 * @param[out] assigned_address USB address of the device.
     165 * @param[out] assigned_handle Devman handle of the new device.
     166 * @return Error code.
     167 * @retval ENOENT Connection to HC not opened.
     168 * @retval EADDRNOTAVAIL Failed retrieving free address from host controller.
     169 * @retval EBUSY Failed reserving default USB address.
     170 * @retval ENOTCONN Problem connecting to the host controller via USB pipe.
     171 * @retval ESTALL Problem communication with device (either SET_ADDRESS
     172 *      request or requests for descriptors when creating match ids).
     173 */
     174int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection,
     175    usb_speed_t dev_speed,
     176    int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
     177    usb_address_t *assigned_address, devman_handle_t *assigned_handle)
     178{
     179        CHECK_CONNECTION(connection);
     180
     181        /*
     182         * Request new address.
     183         */
     184        usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed);
     185        if (dev_addr < 0) {
     186                return EADDRNOTAVAIL;
     187        }
     188
     189        int rc;
     190
     191        /*
     192         * Reserve the default address.
     193         */
     194        rc = usb_hc_reserve_default_address(connection, dev_speed);
     195        if (rc != EOK) {
     196                rc = EBUSY;
     197                goto leave_release_free_address;
     198        }
     199
     200        /*
     201         * Enable the port (i.e. allow signalling through this port).
     202         */
     203        rc = enable_port(port_no, arg);
     204        if (rc != EOK) {
     205                goto leave_release_default_address;
     206        }
     207
     208        /*
     209         * Change the address from default to the free one.
     210         * We need to create a new control pipe for that.
     211         */
     212        usb_device_connection_t dev_conn;
     213        rc = usb_device_connection_initialize_on_default_address(&dev_conn,
     214            connection);
     215        if (rc != EOK) {
     216                rc = ENOTCONN;
     217                goto leave_release_default_address;
     218        }
     219
     220        usb_endpoint_pipe_t ctrl_pipe;
     221        rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe,
     222            &dev_conn);
     223        if (rc != EOK) {
     224                rc = ENOTCONN;
     225                goto leave_release_default_address;
     226        }
     227
     228        rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
     229        if (rc != EOK) {
     230                rc = ENOTCONN;
     231                goto leave_release_default_address;
     232        }
     233
     234        rc = usb_request_set_address(&ctrl_pipe, dev_addr);
     235        if (rc != EOK) {
     236                rc = ESTALL;
     237                goto leave_stop_session;
     238        }
     239
     240        usb_endpoint_pipe_end_session(&ctrl_pipe);
     241
     242        /*
     243         * Once the address is changed, we can return the default address.
     244         */
     245        usb_hc_release_default_address(connection);
     246
     247        /*
     248         * It is time to register the device with devman.
     249         */
     250        /* FIXME: create device_register that will get opened ctrl pipe. */
     251        devman_handle_t child_handle;
     252        rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
     253            parent, &child_handle);
     254        if (rc != EOK) {
     255                rc = ESTALL;
     256                goto leave_release_free_address;
     257        }
     258
     259        /*
     260         * And now inform the host controller about the handle.
     261         */
     262        usb_hc_attached_device_t new_device = {
     263                .address = dev_addr,
     264                .handle = child_handle
     265        };
     266        rc = usb_hc_register_device(connection, &new_device);
     267        if (rc != EOK) {
     268                rc = EDESTADDRREQ;
     269                goto leave_release_free_address;
     270        }
     271
     272        /*
     273         * And we are done.
     274         */
     275        if (assigned_address != NULL) {
     276                *assigned_address = dev_addr;
     277        }
     278        if (assigned_handle != NULL) {
     279                *assigned_handle = child_handle;
     280        }
     281
     282        return EOK;
     283
     284
     285
     286        /*
     287         * Error handling (like nested exceptions) starts here.
     288         * Completely ignoring errors here.
     289         */
     290
     291leave_stop_session:
     292        usb_endpoint_pipe_end_session(&ctrl_pipe);
     293
     294leave_release_default_address:
     295        usb_hc_release_default_address(connection);
     296
     297leave_release_free_address:
     298        usb_hc_unregister_device(connection, dev_addr);
     299
     300        return rc;
     301}
     302
     303
    137304/**
    138305 * @}
  • uspace/lib/usbvirt/Makefile

    r72363a1 r867e6735  
    3030LIBRARY = libusbvirt
    3131
    32 LIBS = $(LIBUSB_PREFIX)/libusb.a
    3332EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -Iinclude
    3433
Note: See TracChangeset for help on using the changeset viewer.