Changes in / [36bcf84f:78f01ff9] in mainline


Ignore:
Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbkbd/usbkbd.ma

    r36bcf84f r78f01ff9  
    1110 usb&class=hid
     210 usb&hid
  • uspace/lib/drv/generic/remote_usbhc.c

    r36bcf84f r78f01ff9  
    159159}
    160160
    161 void remote_usbhc_interrupt_out(device_t *device, void *iface,
    162             ipc_callid_t callid, ipc_call_t *call)
    163 {
    164         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     161/** Process an outgoing transfer (both OUT and SETUP).
     162 *
     163 * @param device Target device.
     164 * @param callid Initiating caller.
     165 * @param call Initiating call.
     166 * @param transfer_func Transfer function (might be NULL).
     167 */
     168static void remote_usbhc_out_transfer(device_t *device,
     169    ipc_callid_t callid, ipc_call_t *call,
     170    usbhc_iface_transfer_out_t transfer_func)
     171{
     172        if (!transfer_func) {
     173                ipc_answer_0(callid, ENOTSUP);
     174                return;
     175        }
    165176
    166177        size_t expected_len = IPC_GET_ARG3(*call);
     
    183194        }
    184195
    185         if (!usb_iface->interrupt_out) {
    186                 ipc_answer_0(callid, ENOTSUP);
    187                 return;
    188         }
    189 
    190196        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    191197        trans->caller = callid;
    192         trans->buffer = NULL;
    193         trans->size = 0;
    194 
    195         int rc = usb_iface->interrupt_out(device, target, buffer, len,
     198        trans->buffer = buffer;
     199        trans->size = len;
     200
     201        int rc = transfer_func(device, target, buffer, len,
    196202            callback_out, trans);
    197203
    198204        if (rc != EOK) {
    199205                ipc_answer_0(callid, rc);
     206                if (buffer != NULL) {
     207                        free(buffer);
     208                }
    200209                free(trans);
    201210        }
    202211}
    203212
    204 void remote_usbhc_interrupt_in(device_t *device, void *iface,
    205             ipc_callid_t callid, ipc_call_t *call)
    206 {
    207         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     213/** Process an incoming transfer.
     214 *
     215 * @param device Target device.
     216 * @param callid Initiating caller.
     217 * @param call Initiating call.
     218 * @param transfer_func Transfer function (might be NULL).
     219 */
     220static void remote_usbhc_in_transfer(device_t *device,
     221    ipc_callid_t callid, ipc_call_t *call,
     222    usbhc_iface_transfer_in_t transfer_func)
     223{
     224        if (!transfer_func) {
     225                ipc_answer_0(callid, ENOTSUP);
     226                return;
     227        }
    208228
    209229        size_t len = IPC_GET_ARG3(*call);
     
    213233        };
    214234
    215         if (!usb_iface->interrupt_in) {
    216                 ipc_answer_0(callid, ENOTSUP);
    217                 return;
    218         }
    219 
    220235        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    221236        trans->caller = callid;
     
    223238        trans->size = len;
    224239
    225         int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
     240        int rc = transfer_func(device, target, trans->buffer, len,
    226241            callback_in, trans);
    227242
     
    233248}
    234249
    235 void remote_usbhc_control_write_setup(device_t *device, void *iface,
    236             ipc_callid_t callid, ipc_call_t *call)
    237 {
    238         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    239 
    240         size_t expected_len = IPC_GET_ARG3(*call);
     250/** Process status part of control transfer.
     251 *
     252 * @param device Target device.
     253 * @param callid Initiating caller.
     254 * @param call Initiating call.
     255 * @param direction Transfer direction (read ~ in, write ~ out).
     256 * @param transfer_in_func Transfer function for control read (might be NULL).
     257 * @param transfer_out_func Transfer function for control write (might be NULL).
     258 */
     259static void remote_usbhc_status_transfer(device_t *device,
     260    ipc_callid_t callid, ipc_call_t *call,
     261    usb_direction_t direction,
     262    int (*transfer_in_func)(device_t *, usb_target_t,
     263        usbhc_iface_transfer_in_callback_t, void *),
     264    int (*transfer_out_func)(device_t *, usb_target_t,
     265        usbhc_iface_transfer_out_callback_t, void *))
     266{
     267        switch (direction) {
     268                case USB_DIRECTION_IN:
     269                        if (!transfer_in_func) {
     270                                ipc_answer_0(callid, ENOTSUP);
     271                                return;
     272                        }
     273                        break;
     274                case USB_DIRECTION_OUT:
     275                        if (!transfer_out_func) {
     276                                ipc_answer_0(callid, ENOTSUP);
     277                                return;
     278                        }
     279                        break;
     280                default:
     281                        assert(false && "unreachable code");
     282                        break;
     283        }
     284
    241285        usb_target_t target = {
    242286                .address = IPC_GET_ARG1(*call),
     
    244288        };
    245289
    246         size_t len = 0;
    247         void *buffer = NULL;
    248         if (expected_len > 0) {
    249                 int rc = async_data_write_accept(&buffer, false,
    250                     1, USB_MAX_PAYLOAD_SIZE,
    251                     0, &len);
    252 
    253                 if (rc != EOK) {
    254                         ipc_answer_0(callid, rc);
    255                         return;
    256                 }
    257         }
    258 
    259         if (!usb_iface->control_write_setup) {
    260                 ipc_answer_0(callid, ENOTSUP);
    261                 return;
    262         }
    263 
    264290        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    265291        trans->caller = callid;
     
    267293        trans->size = 0;
    268294
    269         int rc = usb_iface->control_write_setup(device, target, buffer, len,
    270             callback_out, trans);
     295        int rc;
     296        switch (direction) {
     297                case USB_DIRECTION_IN:
     298                        rc = transfer_in_func(device, target,
     299                            callback_in, trans);
     300                        break;
     301                case USB_DIRECTION_OUT:
     302                        rc = transfer_out_func(device, target,
     303                            callback_out, trans);
     304                        break;
     305                default:
     306                        assert(false && "unreachable code");
     307                        break;
     308        }
    271309
    272310        if (rc != EOK) {
     
    274312                free(trans);
    275313        }
     314        return;
     315}
     316
     317
     318void remote_usbhc_interrupt_out(device_t *device, void *iface,
     319    ipc_callid_t callid, ipc_call_t *call)
     320{
     321        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     322        assert(usb_iface != NULL);
     323
     324        return remote_usbhc_out_transfer(device, callid, call,
     325            usb_iface->interrupt_out);
     326}
     327
     328void remote_usbhc_interrupt_in(device_t *device, void *iface,
     329    ipc_callid_t callid, ipc_call_t *call)
     330{
     331        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     332        assert(usb_iface != NULL);
     333
     334        return remote_usbhc_in_transfer(device, callid, call,
     335            usb_iface->interrupt_in);
     336}
     337
     338void remote_usbhc_control_write_setup(device_t *device, void *iface,
     339    ipc_callid_t callid, ipc_call_t *call)
     340{
     341        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     342        assert(usb_iface != NULL);
     343
     344        return remote_usbhc_out_transfer(device, callid, call,
     345            usb_iface->control_write_setup);
    276346}
    277347
    278348void remote_usbhc_control_write_data(device_t *device, void *iface,
    279             ipc_callid_t callid, ipc_call_t *call)
    280 {
    281         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    282 
    283         size_t expected_len = IPC_GET_ARG3(*call);
    284         usb_target_t target = {
    285                 .address = IPC_GET_ARG1(*call),
    286                 .endpoint = IPC_GET_ARG2(*call)
    287         };
    288 
    289         size_t len = 0;
    290         void *buffer = NULL;
    291         if (expected_len > 0) {
    292                 int rc = async_data_write_accept(&buffer, false,
    293                     1, USB_MAX_PAYLOAD_SIZE,
    294                     0, &len);
    295 
    296                 if (rc != EOK) {
    297                         ipc_answer_0(callid, rc);
    298                         return;
    299                 }
    300         }
    301 
    302         if (!usb_iface->control_write_data) {
    303                 ipc_answer_0(callid, ENOTSUP);
    304                 return;
    305         }
    306 
    307         async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    308         trans->caller = callid;
    309         trans->buffer = NULL;
    310         trans->size = 0;
    311 
    312         int rc = usb_iface->control_write_data(device, target, buffer, len,
    313             callback_out, trans);
    314 
    315         if (rc != EOK) {
    316                 ipc_answer_0(callid, rc);
    317                 free(trans);
    318         }
     349    ipc_callid_t callid, ipc_call_t *call)
     350{
     351        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     352        assert(usb_iface != NULL);
     353
     354        return remote_usbhc_out_transfer(device, callid, call,
     355            usb_iface->control_write_data);
    319356}
    320357
    321358void remote_usbhc_control_write_status(device_t *device, void *iface,
    322             ipc_callid_t callid, ipc_call_t *call)
    323 {
    324         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    325 
    326         usb_target_t target = {
    327                 .address = IPC_GET_ARG1(*call),
    328                 .endpoint = IPC_GET_ARG2(*call)
    329         };
    330 
    331         if (!usb_iface->control_write_status) {
    332                 ipc_answer_0(callid, ENOTSUP);
    333                 return;
    334         }
    335 
    336         async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    337         trans->caller = callid;
    338         trans->buffer = NULL;
    339         trans->size = 0;
    340 
    341         int rc = usb_iface->control_write_status(device, target,
    342             callback_in, trans);
    343 
    344         if (rc != EOK) {
    345                 ipc_answer_0(callid, rc);
    346                 free(trans);
    347         }
     359    ipc_callid_t callid, ipc_call_t *call)
     360{
     361        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     362        assert(usb_iface != NULL);
     363
     364        return remote_usbhc_status_transfer(device, callid, call,
     365            USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
    348366}
    349367
    350368void remote_usbhc_control_read_setup(device_t *device, void *iface,
    351             ipc_callid_t callid, ipc_call_t *call)
    352 {
    353         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    354 
    355         size_t expected_len = IPC_GET_ARG3(*call);
    356         usb_target_t target = {
    357                 .address = IPC_GET_ARG1(*call),
    358                 .endpoint = IPC_GET_ARG2(*call)
    359         };
    360 
    361         size_t len = 0;
    362         void *buffer = NULL;
    363         if (expected_len > 0) {
    364                 int rc = async_data_write_accept(&buffer, false,
    365                     1, USB_MAX_PAYLOAD_SIZE,
    366                     0, &len);
    367 
    368                 if (rc != EOK) {
    369                         ipc_answer_0(callid, rc);
    370                         return;
    371                 }
    372         }
    373 
    374         if (!usb_iface->control_read_setup) {
    375                 ipc_answer_0(callid, ENOTSUP);
    376                 return;
    377         }
    378 
    379         async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    380         trans->caller = callid;
    381         trans->buffer = NULL;
    382         trans->size = 0;
    383 
    384         int rc = usb_iface->control_read_setup(device, target, buffer, len,
    385             callback_out, trans);
    386 
    387         if (rc != EOK) {
    388                 ipc_answer_0(callid, rc);
    389                 free(trans);
    390         }
     369    ipc_callid_t callid, ipc_call_t *call)
     370{
     371        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     372        assert(usb_iface != NULL);
     373
     374        return remote_usbhc_out_transfer(device, callid, call,
     375            usb_iface->control_read_setup);
    391376}
    392377
     
    395380{
    396381        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    397 
    398         size_t len = IPC_GET_ARG3(*call);
    399         usb_target_t target = {
    400                 .address = IPC_GET_ARG1(*call),
    401                 .endpoint = IPC_GET_ARG2(*call)
    402         };
    403 
    404         if (!usb_iface->control_read_data) {
    405                 ipc_answer_0(callid, ENOTSUP);
    406                 return;
    407         }
    408 
    409         async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    410         trans->caller = callid;
    411         trans->buffer = malloc(len);
    412         trans->size = len;
    413 
    414         int rc = usb_iface->control_read_data(device, target, trans->buffer, len,
    415             callback_in, trans);
    416 
    417         if (rc != EOK) {
    418                 ipc_answer_0(callid, rc);
    419                 free(trans->buffer);
    420                 free(trans);
    421         }
     382        assert(usb_iface != NULL);
     383
     384        return remote_usbhc_in_transfer(device, callid, call,
     385            usb_iface->control_read_data);
    422386}
    423387
     
    426390{
    427391        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    428 
    429         usb_target_t target = {
    430                 .address = IPC_GET_ARG1(*call),
    431                 .endpoint = IPC_GET_ARG2(*call)
    432         };
    433 
    434         if (!usb_iface->control_read_status) {
    435                 ipc_answer_0(callid, ENOTSUP);
    436                 return;
    437         }
    438 
    439         async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    440         trans->caller = callid;
    441         trans->buffer = NULL;
    442         trans->size = 0;
    443 
    444         int rc = usb_iface->control_read_status(device, target,
    445             callback_out, trans);
    446 
    447         if (rc != EOK) {
    448                 ipc_answer_0(callid, rc);
    449                 free(trans);
    450         }
     392        assert(usb_iface != NULL);
     393
     394        return remote_usbhc_status_transfer(device, callid, call,
     395            USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
    451396}
    452397
  • uspace/lib/drv/include/usbhc_iface.h

    r36bcf84f r78f01ff9  
    166166    usb_transaction_outcome_t, size_t, void *);
    167167
     168
     169/** Out transfer processing function prototype. */
     170typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t,
     171    void *, size_t,
     172    usbhc_iface_transfer_out_callback_t, void *);
     173
     174/** Setup transfer processing function prototype. */
     175typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t;
     176
     177/** In transfer processing function prototype. */
     178typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t,
     179    void *, size_t,
     180    usbhc_iface_transfer_in_callback_t, void *);
     181
    168182/** USB devices communication interface. */
    169183typedef struct {
    170184        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
    171185
    172         int (*interrupt_out)(device_t *, usb_target_t,
    173             void *, size_t,
    174             usbhc_iface_transfer_out_callback_t, void *);
    175         int (*interrupt_in)(device_t *, usb_target_t,
    176             void *, size_t,
    177             usbhc_iface_transfer_in_callback_t, void *);
    178 
    179         int (*control_write_setup)(device_t *, usb_target_t,
    180             void *, size_t,
    181             usbhc_iface_transfer_out_callback_t, void *);
    182         int (*control_write_data)(device_t *, usb_target_t,
    183             void *, size_t,
    184             usbhc_iface_transfer_out_callback_t, void *);
     186        usbhc_iface_transfer_out_t interrupt_out;
     187        usbhc_iface_transfer_in_t interrupt_in;
     188
     189        usbhc_iface_transfer_setup_t control_write_setup;
     190        usbhc_iface_transfer_out_t control_write_data;
    185191        int (*control_write_status)(device_t *, usb_target_t,
    186192            usbhc_iface_transfer_in_callback_t, void *);
    187193
    188         int (*control_read_setup)(device_t *, usb_target_t,
    189             void *, size_t,
    190             usbhc_iface_transfer_out_callback_t, void *);
    191         int (*control_read_data)(device_t *, usb_target_t,
    192             void *, size_t,
    193             usbhc_iface_transfer_in_callback_t, void *);
     194        usbhc_iface_transfer_setup_t control_read_setup;
     195        usbhc_iface_transfer_in_t control_read_data;
    194196        int (*control_read_status)(device_t *, usb_target_t,
    195197            usbhc_iface_transfer_out_callback_t, void *);
  • uspace/lib/usb/include/usb/hcdhubd.h

    r36bcf84f r78f01ff9  
    3737
    3838#include <adt/list.h>
     39#include <bool.h>
    3940#include <driver.h>
    4041#include <usb/usb.h>
     
    175176int usb_hc_async_wait_for(usb_handle_t);
    176177
    177 int usb_hc_add_child_device(device_t *, const char *, const char *);
     178int usb_hc_add_child_device(device_t *, const char *, const char *, bool);
    178179
    179180#endif
  • uspace/lib/usb/src/hcdhubd.c

    r36bcf84f r78f01ff9  
    4040#include <bool.h>
    4141#include <errno.h>
     42#include <str_error.h>
    4243#include <usb/classes/hub.h>
    4344
     
    112113        }
    113114
    114         rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id);
     115        rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id, true);
    115116        if (rc != EOK) {
    116117                free(id);
     
    150151        match_id->id = child_info->match_id;
    151152        match_id->score = 10;
    152         printf("adding child device with match \"%s\"\n", match_id->id);
    153153        add_match_id(&child->match_ids, match_id);
    154154
     155        printf("%s: adding child device `%s' with match \"%s\"\n",
     156            hc_driver->name, child->name, match_id->id);
    155157        rc = child_device_register(child, child_info->parent);
     158        printf("%s: child device `%s' registration: %s\n",
     159            hc_driver->name, child->name, str_error(rc));
     160
    156161        if (rc != EOK) {
    157162                goto failure;
     
    173178leave:
    174179        free(arg);
    175         return rc;
     180        return EOK;
    176181}
    177182
     
    180185 * driven by the same task, the child adding is done in separate fibril.
    181186 * Not optimal, but it works.
     187 * Update: not under all circumstances the new fibril is successful either.
     188 * Thus the last parameter to let the caller choose.
    182189 *
    183190 * @param parent Parent device.
    184191 * @param name Device name.
    185192 * @param match_id Match id.
     193 * @param create_fibril Whether to run the addition in new fibril.
    186194 * @return Error code.
    187195 */
    188196int usb_hc_add_child_device(device_t *parent, const char *name,
    189     const char *match_id)
    190 {
     197    const char *match_id, bool create_fibril)
     198{
     199        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
     200            name, match_id);
     201
    191202        struct child_device_info *child_info
    192203            = malloc(sizeof(struct child_device_info));
     
    196207        child_info->match_id = match_id;
    197208
    198         fid_t fibril = fibril_create(fibril_add_child_device, child_info);
    199         if (!fibril) {
    200                 return ENOMEM;
    201         }
    202         fibril_add_ready(fibril);
     209        if (create_fibril) {
     210                fid_t fibril = fibril_create(fibril_add_child_device, child_info);
     211                if (!fibril) {
     212                        return ENOMEM;
     213                }
     214                fibril_add_ready(fibril);
     215        } else {
     216                fibril_add_child_device(child_info);
     217        }
    203218
    204219        return EOK;
  • uspace/lib/usb/src/hcdrv.c

    r36bcf84f r78f01ff9  
    5454};
    5555
    56 int usb_add_hc_device(device_t *dev)
    57 {
     56static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
    5857        usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t));
     58
    5959        list_initialize(&hc_dev->link);
     60        list_initialize(&hc_dev->hubs);
     61        list_initialize(&hc_dev->attached_devices);
    6062        hc_dev->transfer_ops = NULL;
    6163
     
    6365        dev->ops = &usb_device_ops;
    6466        hc_dev->generic->driver_data = hc_dev;
     67
     68        return hc_dev;
     69}
     70
     71int usb_add_hc_device(device_t *dev)
     72{
     73        usb_hc_device_t *hc_dev = usb_hc_device_create(dev);
    6574
    6675        int rc = hc_driver->add_hc(hc_dev);
     
    7887        list_append(&hc_dev->link, &hc_list);
    7988
    80         //add keyboard
    81         /// @TODO this is not correct code
    82 
    8389        /*
    84          * Announce presence of child device.
     90         * FIXME: the following is a workaround to force loading of USB
     91         * keyboard driver.
     92         * Will be removed as soon as the hub driver is completed and
     93         * can detect connected devices.
    8594         */
    86         device_t *kbd = NULL;
    87         match_id_t *match_id = NULL;
    88 
    89         kbd = create_device();
    90         if (kbd == NULL) {
    91                 printf("ERROR: enomem\n");
    92         }
    93         kbd->name = USB_KBD_DEVICE_NAME;
    94 
    95         match_id = create_match_id();
    96         if (match_id == NULL) {
    97                 printf("ERROR: enomem\n");
     95        printf("%s: trying to add USB HID child device...\n", hc_driver->name);
     96        rc = usb_hc_add_child_device(dev, USB_KBD_DEVICE_NAME, "usb&hid", false);
     97        if (rc != EOK) {
     98                printf("%s: adding USB HID child failed...\n", hc_driver->name);
    9899        }
    99100
    100         char *id;
    101         rc = asprintf(&id, USB_KBD_DEVICE_NAME);
    102         if (rc <= 0) {
    103                 printf("ERROR: enomem\n");
    104                 return rc;
    105         }
    106 
    107         match_id->id = id;
    108         match_id->score = 30;
    109 
    110         add_match_id(&kbd->match_ids, match_id);
    111 
    112         rc = child_device_register(kbd, dev);
    113         if (rc != EOK) {
    114                 printf("ERROR: cannot register kbd\n");
    115                 return rc;
    116         }
    117 
    118         printf("%s: registered root hub\n", dev->name);
    119101        return EOK;
    120102}
Note: See TracChangeset for help on using the changeset viewer.