Changes in / [3f3afb9:58226b4] in mainline


Ignore:
Location:
uspace
Files:
5 deleted
48 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/batch.c

    r3f3afb9 r58226b4  
    5151static void batch_control(usb_transfer_batch_t *instance,
    5252    usb_direction_t data_dir, usb_direction_t status_dir);
    53 static void batch_data(usb_transfer_batch_t *instance);
    5453static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
    5554static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
     
    135134        assert(data);
    136135        size_t tds = data->td_count - 1;
    137         usb_log_debug("Batch(%p) checking %d td(s) for completion.\n",
     136        usb_log_debug2("Batch(%p) checking %d td(s) for completion.\n",
    138137            instance, tds);
    139         usb_log_debug("ED: %x:%x:%x:%x.\n",
    140             data->ed->status, data->ed->td_head, data->ed->td_tail,
    141             data->ed->next);
    142138        size_t i = 0;
    143139        for (; i < tds; ++i) {
    144                 usb_log_debug("TD %d: %x:%x:%x:%x.\n", i,
    145                     data->tds[i].status, data->tds[i].cbp, data->tds[i].next,
    146                     data->tds[i].be);
    147                 if (!td_is_finished(&data->tds[i])) {
     140                if (!td_is_finished(&data->tds[i]))
    148141                        return false;
    149                 }
    150142                instance->error = td_error(&data->tds[i]);
    151143                /* FIXME: calculate real transfered size */
     
    185177        assert(instance->direction == USB_DIRECTION_IN);
    186178        instance->next_step = batch_call_in_and_dispose;
    187         batch_data(instance);
     179        /* TODO: implement */
    188180        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
    189181}
     
    197189            instance->buffer_size);
    198190        instance->next_step = batch_call_out_and_dispose;
    199         batch_data(instance);
     191        /* TODO: implement */
    200192        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
    201193}
     
    206198        instance->direction = USB_DIRECTION_IN;
    207199        instance->next_step = batch_call_in_and_dispose;
    208         batch_data(instance);
     200        /* TODO: implement */
    209201        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
    210202}
     
    215207        instance->direction = USB_DIRECTION_IN;
    216208        instance->next_step = batch_call_in_and_dispose;
    217         batch_data(instance);
     209        /* TODO: implement */
    218210        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
    219211}
     
    235227        ed_init(data->ed, instance->ep);
    236228        ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]);
    237         usb_log_debug("Created ED(%p): %x:%x:%x:%x.\n", data->ed,
    238             data->ed->status, data->ed->td_tail, data->ed->td_head,
    239             data->ed->next);
     229        usb_log_debug("Created ED: %x:%x:%x:%x.\n", data->ed->status,
     230            data->ed->td_tail, data->ed->td_head, data->ed->next);
    240231        int toggle = 0;
    241232        /* setup stage */
     
    276267}
    277268/*----------------------------------------------------------------------------*/
    278 void batch_data(usb_transfer_batch_t *instance)
    279 {
    280         assert(instance);
    281         ohci_batch_t *data = instance->private_data;
    282         assert(data);
    283         ed_init(data->ed, instance->ep);
    284         ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]);
    285         usb_log_debug("Created ED(%p): %x:%x:%x:%x.\n", data->ed,
    286             data->ed->status, data->ed->td_tail, data->ed->td_head,
    287             data->ed->next);
    288 
    289         /* data stage */
    290         size_t td_current = 0;
    291         size_t remain_size = instance->buffer_size;
    292         char *transfer_buffer = instance->transport_buffer;
    293         while (remain_size > 0) {
    294                 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
    295                     OHCI_TD_MAX_TRANSFER : remain_size;
    296 
    297                 td_init(&data->tds[td_current], instance->ep->direction,
    298                     transfer_buffer, transfer_size, -1);
    299                 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);
    300                 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",
    301                     data->tds[td_current].status, data->tds[td_current].cbp,
    302                     data->tds[td_current].next, data->tds[td_current].be);
    303 
    304                 transfer_buffer += transfer_size;
    305                 remain_size -= transfer_size;
    306                 assert(td_current < data->td_count);
    307                 ++td_current;
    308         }
    309 }
    310 /*----------------------------------------------------------------------------*/
    311269/** Helper function calls callback and correctly disposes of batch structure.
    312270 *
  • uspace/drv/ohci/hc.c

    r3f3afb9 r58226b4  
    108108            ret, str_error(ret));
    109109
    110         hc_gain_control(instance);
    111         ret = hc_init_memory(instance);
    112         CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures:%s.\n",
    113             ret, str_error(ret));
    114         hc_init_hw(instance);
    115         fibril_mutex_initialize(&instance->guard);
    116 
    117         rh_init(&instance->rh, dev, instance->registers);
    118 
    119110        if (!interrupts) {
    120111                instance->interrupt_emulator =
     
    123114        }
    124115
     116        hc_gain_control(instance);
     117
     118        rh_init(&instance->rh, dev, instance->registers);
     119
     120        hc_init_memory(instance);
     121        hc_init_hw(instance);
     122
     123        /* TODO: implement */
    125124        return EOK;
    126125}
     
    136135        }
    137136
    138         fibril_mutex_lock(&instance->guard);
     137        transfer_list_add_batch(
     138            instance->transfers[batch->transfer_type], batch);
     139
    139140        switch (batch->transfer_type) {
    140141        case USB_TRANSFER_CONTROL:
    141                 instance->registers->control &= ~C_CLE;
    142                 transfer_list_add_batch(
    143                     instance->transfers[batch->transfer_type], batch);
    144142                instance->registers->command_status |= CS_CLF;
    145                 usb_log_debug2("Set CS control transfer filled: %x.\n",
    146                         instance->registers->command_status);
    147                 instance->registers->control_current = 0;
    148                 instance->registers->control |= C_CLE;
    149143                break;
    150144        case USB_TRANSFER_BULK:
    151                 instance->registers->control &= ~C_BLE;
    152                 transfer_list_add_batch(
    153                     instance->transfers[batch->transfer_type], batch);
    154145                instance->registers->command_status |= CS_BLF;
    155                 usb_log_debug2("Set bulk transfer filled: %x.\n",
    156                         instance->registers->command_status);
    157                 instance->registers->control |= C_BLE;
    158                 break;
    159         case USB_TRANSFER_INTERRUPT:
    160         case USB_TRANSFER_ISOCHRONOUS:
    161                 instance->registers->control &= (~C_PLE & ~C_IE);
    162                 transfer_list_add_batch(
    163                     instance->transfers[batch->transfer_type], batch);
    164                 instance->registers->control |= C_PLE | C_IE;
    165                 usb_log_debug2("Added periodic transfer: %x.\n",
    166                     instance->registers->periodic_current);
    167146                break;
    168147        default:
    169148                break;
    170149        }
    171         fibril_mutex_unlock(&instance->guard);
    172150        return EOK;
    173151}
     
    176154{
    177155        assert(instance);
    178         if ((status & ~IS_SF) == 0) /* ignore sof status */
     156        if (status == 0)
    179157                return;
    180158        if (status & IS_RHSC)
    181159                rh_interrupt(&instance->rh);
    182160
    183         usb_log_debug("OHCI interrupt: %x.\n", status);
    184 
    185         if (status & IS_WDH) {
    186                 fibril_mutex_lock(&instance->guard);
    187                 usb_log_debug2("HCCA: %p-%p(%p).\n", instance->hcca,
    188                     instance->registers->hcca, addr_to_phys(instance->hcca));
    189                 usb_log_debug2("Periodic current: %p.\n",
    190                     instance->registers->periodic_current);
    191                 LIST_INITIALIZE(done);
    192                 transfer_list_remove_finished(
    193                     &instance->transfers_interrupt, &done);
    194                 transfer_list_remove_finished(
    195                     &instance->transfers_isochronous, &done);
    196                 transfer_list_remove_finished(
    197                     &instance->transfers_control, &done);
    198                 transfer_list_remove_finished(
    199                     &instance->transfers_bulk, &done);
    200 
    201                 while (!list_empty(&done)) {
    202                         link_t *item = done.next;
    203                         list_remove(item);
    204                         usb_transfer_batch_t *batch =
    205                             list_get_instance(item, usb_transfer_batch_t, link);
    206                         usb_transfer_batch_finish(batch);
    207                 }
    208                 fibril_mutex_unlock(&instance->guard);
     161        usb_log_info("OHCI interrupt: %x.\n", status);
     162
     163        LIST_INITIALIZE(done);
     164        transfer_list_remove_finished(&instance->transfers_interrupt, &done);
     165        transfer_list_remove_finished(&instance->transfers_isochronous, &done);
     166        transfer_list_remove_finished(&instance->transfers_control, &done);
     167        transfer_list_remove_finished(&instance->transfers_bulk, &done);
     168
     169        while (!list_empty(&done)) {
     170                link_t *item = done.next;
     171                list_remove(item);
     172                usb_transfer_batch_t *batch =
     173                    list_get_instance(item, usb_transfer_batch_t, link);
     174                usb_transfer_batch_finish(batch);
    209175        }
    210176}
     
    218184                instance->registers->interrupt_status = status;
    219185                hc_interrupt(instance, status);
    220                 async_usleep(50000);
     186                async_usleep(1000);
    221187        }
    222188        return EOK;
     
    226192{
    227193        assert(instance);
    228         /* Turn off legacy emulation */
    229         volatile uint32_t *ohci_emulation_reg =
    230             (uint32_t*)((char*)instance->registers + 0x100);
    231         usb_log_debug("OHCI legacy register %p: %x.\n",
    232                 ohci_emulation_reg, *ohci_emulation_reg);
    233         *ohci_emulation_reg = 0;
    234 
    235194        /* Interrupt routing enabled => smm driver is active */
    236195        if (instance->registers->control & C_IR) {
    237                 usb_log_debug("SMM driver: request ownership change.\n");
     196                usb_log_info("Found SMM driver requesting ownership change.\n");
    238197                instance->registers->command_status |= CS_OCR;
    239198                while (instance->registers->control & C_IR) {
    240199                        async_usleep(1000);
    241200                }
    242                 usb_log_info("SMM driver: Ownership taken.\n");
     201                usb_log_info("Ownership taken from SMM driver.\n");
    243202                return;
    244203        }
     
    248207        /* Interrupt routing disabled && status != USB_RESET => BIOS active */
    249208        if (hc_status != C_HCFS_RESET) {
    250                 usb_log_debug("BIOS driver found.\n");
     209                usb_log_info("Found BIOS driver.\n");
    251210                if (hc_status == C_HCFS_OPERATIONAL) {
    252                         usb_log_info("BIOS driver: HC operational.\n");
     211                        usb_log_info("HC operational(BIOS).\n");
    253212                        return;
    254213                }
     
    256215                instance->registers->control &= (C_HCFS_RESUME << C_HCFS_SHIFT);
    257216                async_usleep(20000);
    258                 usb_log_info("BIOS driver: HC resumed.\n");
    259217                return;
    260218        }
     
    262220        /* HC is in reset (hw startup) => no other driver
    263221         * maintain reset for at least the time specified in USB spec (50 ms)*/
    264         usb_log_info("HC found in reset.\n");
    265222        async_usleep(50000);
     223
     224        /* turn off legacy emulation */
     225        volatile uint32_t *ohci_emulation_reg =
     226            (uint32_t*)((char*)instance->registers + 0x100);
     227        usb_log_info("OHCI legacy register status %p: %x.\n",
     228                ohci_emulation_reg, *ohci_emulation_reg);
     229        *ohci_emulation_reg = 0;
     230
    266231}
    267232/*----------------------------------------------------------------------------*/
    268233void hc_init_hw(hc_t *instance)
    269234{
    270         /* OHCI guide page 42 */
    271         assert(instance);
    272         usb_log_debug2("Started hc initialization routine.\n");
    273 
    274         /* Save contents of fm_interval register */
     235        assert(instance);
    275236        const uint32_t fm_interval = instance->registers->fm_interval;
    276         usb_log_debug2("Old value of HcFmInterval: %x.\n", fm_interval);
    277 
    278         /* Reset hc */
    279         usb_log_debug2("HC reset.\n");
    280         size_t time = 0;
     237
     238        /* reset hc */
    281239        instance->registers->command_status = CS_HCR;
    282         while (instance->registers->command_status & CS_HCR) {
    283                 async_usleep(10);
    284                 time += 10;
    285         }
    286         usb_log_debug2("HC reset complete in %zu us.\n", time);
    287 
    288         /* Restore fm_interval */
     240        async_usleep(10);
     241
     242        /* restore fm_interval */
    289243        instance->registers->fm_interval = fm_interval;
    290244        assert((instance->registers->command_status & CS_HCR) == 0);
    291245
    292246        /* hc is now in suspend state */
    293         usb_log_debug2("HC should be in suspend state(%x).\n",
    294             instance->registers->control);
    295 
    296         /* Use HCCA */
    297         instance->registers->hcca = addr_to_phys(instance->hcca);
    298 
    299         /* Use queues */
    300         instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;
    301         usb_log_debug2("Bulk HEAD set to: %p(%p).\n",
    302             instance->transfers_bulk.list_head,
    303             instance->transfers_bulk.list_head_pa);
    304 
    305         instance->registers->control_head =
    306             instance->transfers_control.list_head_pa;
    307         usb_log_debug2("Control HEAD set to: %p(%p).\n",
    308             instance->transfers_control.list_head,
    309             instance->transfers_control.list_head_pa);
    310 
    311         /* Enable queues */
     247
     248        /* enable queues */
    312249        instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);
    313         usb_log_debug2("All queues enabled(%x).\n",
    314             instance->registers->control);
    315 
    316         /* Disable interrupts */
    317         instance->registers->interrupt_disable = I_SF | I_OC;
    318         usb_log_debug2("Disabling interrupts: %x.\n",
    319             instance->registers->interrupt_disable);
    320         instance->registers->interrupt_disable = I_MI;
    321         usb_log_debug2("Enabled interrupts: %x.\n",
    322             instance->registers->interrupt_enable);
    323 
    324         /* Set periodic start to 90% */
    325         uint32_t frame_length = ((fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK);
    326         instance->registers->periodic_start = (frame_length / 10) * 9;
    327         usb_log_debug2("All periodic start set to: %x(%u - 90%% of %d).\n",
    328             instance->registers->periodic_start,
    329             instance->registers->periodic_start, frame_length);
     250        /* TODO: enable interrupts */
     251        /* set periodic start to 90% */
     252        instance->registers->periodic_start = (fm_interval / 10) * 9;
    330253
    331254        instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);
    332         usb_log_info("OHCI HC up and running(%x).\n",
    333             instance->registers->control);
     255        usb_log_info("OHCI HC up and running.\n");
    334256}
    335257/*----------------------------------------------------------------------------*/
     
    355277        SETUP_TRANSFER_LIST(transfers_control, "CONTROL");
    356278        SETUP_TRANSFER_LIST(transfers_bulk, "BULK");
    357 #undef SETUP_TRANSFER_LIST
     279
    358280        transfer_list_set_next(&instance->transfers_interrupt,
    359281            &instance->transfers_isochronous);
     
    370292
    371293        return EOK;
     294#undef CHECK_RET_CLEAR_RETURN
    372295}
    373296/*----------------------------------------------------------------------------*/
     
    375298{
    376299        assert(instance);
    377         /* Init queues */
     300        /* init queues */
    378301        hc_init_transfer_lists(instance);
    379302
    380         /*Init HCCA */
     303        /* init HCCA */
    381304        instance->hcca = malloc32(sizeof(hcca_t));
    382305        if (instance->hcca == NULL)
    383306                return ENOMEM;
    384307        bzero(instance->hcca, sizeof(hcca_t));
    385         usb_log_debug2("OHCI HCCA initialized at %p.\n", instance->hcca);
     308        instance->registers->hcca = addr_to_phys(instance->hcca);
     309
     310        /* use queues */
     311        instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;
     312        instance->registers->control_head =
     313            instance->transfers_control.list_head_pa;
    386314
    387315        unsigned i = 0;
     
    390318                    instance->transfers_interrupt.list_head_pa;
    391319        }
    392         usb_log_debug2("Interrupt HEADs set to: %p(%p).\n",
    393             instance->transfers_interrupt.list_head,
    394             instance->transfers_interrupt.list_head_pa);
    395320
    396321        return EOK;
  • uspace/drv/ohci/hc.h

    r3f3afb9 r58226b4  
    6969        usb_endpoint_manager_t ep_manager;
    7070        fid_t interrupt_emulator;
    71         fibril_mutex_t guard;
    7271} hc_t;
    7372
  • uspace/drv/ohci/hw_struct/endpoint_descriptor.c

    r3f3afb9 r58226b4  
    4242        bzero(instance, sizeof(ed_t));
    4343        if (ep == NULL) {
    44                 instance->status = ED_STATUS_K_FLAG;
     44                instance->status |= ED_STATUS_K_FLAG;
    4545                return;
    4646        }
     
    5353                << ED_STATUS_MPS_SHIFT);
    5454
    55 
    5655        if (ep->speed == USB_SPEED_LOW)
    5756                instance->status |= ED_STATUS_S_FLAG;
     
    5958                instance->status |= ED_STATUS_F_FLAG;
    6059
    61         if (ep->toggle)
    62                 instance->td_head |= ED_TDHEAD_TOGGLE_CARRY;
    6360}
     61
    6462/**
    6563 * @}
  • uspace/drv/ohci/hw_struct/endpoint_descriptor.h

    r3f3afb9 r58226b4  
    5353#define ED_STATUS_D_MASK (0x3)     /* direction */
    5454#define ED_STATUS_D_SHIFT (11)
    55 #define ED_STATUS_D_OUT (0x1)
    56 #define ED_STATUS_D_IN (0x2)
     55#define ED_STATUS_D_IN (0x1)
     56#define ED_STATUS_D_OUT (0x2)
    5757#define ED_STATUS_D_TRANSFER (0x3)
    5858
     
    8484{
    8585        assert(instance);
    86         instance->td_head =
    87             ((addr_to_phys(head) & ED_TDHEAD_PTR_MASK)
    88             | (instance->td_head & ~ED_TDHEAD_PTR_MASK));
     86        instance->td_head = addr_to_phys(head) & ED_TDHEAD_PTR_MASK;
    8987        instance->td_tail = addr_to_phys(tail) & ED_TDTAIL_PTR_MASK;
    9088}
     
    9896        instance->next = pa;
    9997}
     98
    10099#endif
    101100/**
  • uspace/drv/ohci/hw_struct/hcca.h

    r3f3afb9 r58226b4  
    4343        uint32_t done_head;
    4444        uint32_t reserved[29];
    45 } __attribute__((packed, aligned)) hcca_t;
     45} __attribute__((packed)) hcca_t;
    4646
    4747#endif
  • uspace/drv/ohci/hw_struct/transfer_descriptor.c

    r3f3afb9 r58226b4  
    5353        }
    5454        if (buffer != NULL) {
    55                 assert(size != 0);
    5655                instance->cbp = addr_to_phys(buffer);
    5756                instance->be = addr_to_phys(buffer + size - 1);
  • uspace/drv/ohci/hw_struct/transfer_descriptor.h

    r3f3afb9 r58226b4  
    5050#define TD_STATUS_DP_SHIFT (19)
    5151#define TD_STATUS_DP_SETUP (0x0)
    52 #define TD_STATUS_DP_OUT (0x1)
    53 #define TD_STATUS_DP_IN (0x2)
     52#define TD_STATUS_DP_IN (0x1)
     53#define TD_STATUS_DP_OUT (0x2)
    5454#define TD_STATUS_DI_MASK (0x7) /* delay interrupt, wait DI frames before int */
    5555#define TD_STATUS_DI_SHIFT (21)
     
    8686        int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;
    8787        /* something went wrong, error code is set */
    88         if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2) {
     88        if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2 && cc != CC_NOERROR) {
    8989                return true;
    9090        }
  • uspace/drv/ohci/iface.c

    r3f3afb9 r58226b4  
    6363        }
    6464
    65         usb_log_debug("%s %d:%d %zu(%zu).\n",
    66             name, target.address, target.endpoint, size, ep->max_packet_size);
    67 
    6865        const size_t bw = bandwidth_count_usb11(
    6966            ep->speed, ep->transfer_type, size, ep->max_packet_size);
     
    7168                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    7269                    "but only %zu is reserved.\n",
    73                     target.address, target.endpoint, name, bw, res_bw);
     70                    name, target.address, target.endpoint, bw, res_bw);
    7471                return ENOSPC;
    7572        }
    76 
    77         *batch = batch_get(
    78             fun, ep, data, size, setup_data, setup_size, in, out, arg);
    79         if (!*batch)
     73        usb_log_debug("%s %d:%d %zu(%zu).\n",
     74            name, target.address, target.endpoint, size, ep->max_packet_size);
     75
     76        assert(ep->speed ==
     77            usb_device_keeper_get_speed(&(*hc)->manager, target.address));
     78//      assert(ep->max_packet_size == max_packet_size);
     79//      assert(ep->transfer_type == USB_TRANSFER_CONTROL);
     80
     81        *batch =
     82            batch_get(fun, ep, data, size, setup_data, setup_size,
     83                in, out, arg);
     84        if (!batch)
    8085                return ENOMEM;
     86        return EOK;
     87}
     88
     89
     90/** Reserve default address interface function
     91 *
     92 * @param[in] fun DDF function that was called.
     93 * @param[in] speed Speed to associate with the new default address.
     94 * @return Error code.
     95 */
     96static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
     97{
     98        assert(fun);
     99        hc_t *hc = fun_to_hc(fun);
     100        assert(hc);
     101        usb_log_debug("Default address request with speed %d.\n", speed);
     102        usb_device_keeper_reserve_default_address(&hc->manager, speed);
     103        return EOK;
     104#if 0
     105        endpoint_t *ep = malloc(sizeof(endpoint_t));
     106        if (ep == NULL)
     107                return ENOMEM;
     108        const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;
     109        endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);
     110        int ret;
     111try_retgister:
     112        ret = usb_endpoint_manager_register_ep(&hc->ep_manager,
     113            USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);
     114        if (ret == EEXISTS) {
     115                async_usleep(1000);
     116                goto try_retgister;
     117        }
     118        if (ret != EOK) {
     119                endpoint_destroy(ep);
     120        }
     121        return ret;
     122#endif
     123}
     124/*----------------------------------------------------------------------------*/
     125/** Release default address interface function
     126 *
     127 * @param[in] fun DDF function that was called.
     128 * @return Error code.
     129 */
     130static int release_default_address(ddf_fun_t *fun)
     131{
     132        assert(fun);
     133        hc_t *hc = fun_to_hc(fun);
     134        assert(hc);
     135        usb_log_debug("Default address release.\n");
     136//      return usb_endpoint_manager_unregister_ep(&hc->ep_manager,
     137//          USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);
     138        usb_device_keeper_release_default_address(&hc->manager);
    81139        return EOK;
    82140}
     
    158216        hc_t *hc = fun_to_hc(fun);
    159217        assert(hc);
    160 
     218        if (address == hc->rh.address)
     219                return EOK;
    161220        usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
    162221        if (speed >= USB_SPEED_MAX) {
    163222                speed = ep_speed;
    164223        }
    165         const size_t size = max_packet_size;
     224        const size_t size =
     225            (transfer_type == USB_TRANSFER_INTERRUPT
     226            || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
     227            max_packet_size : 0;
    166228        int ret;
    167 
    168         usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    169             address, endpoint, usb_str_transfer_type(transfer_type),
    170             usb_str_speed(speed), direction, size, max_packet_size, interval);
    171229
    172230        endpoint_t *ep = malloc(sizeof(endpoint_t));
     
    180238        }
    181239
     240        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
     241            address, endpoint, usb_str_transfer_type(transfer_type),
     242            usb_str_speed(speed), direction, size, max_packet_size, interval);
     243
    182244        ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
    183245        if (ret != EOK) {
    184246                endpoint_destroy(ep);
     247        } else {
     248                usb_device_keeper_add_ep(&hc->manager, address, ep);
    185249        }
    186250        return ret;
     
    195259        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    196260            address, endpoint, direction);
     261        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     262            address, endpoint, direction, NULL);
     263        if (ep != NULL) {
     264                usb_device_keeper_del_ep(&hc->manager, address, ep);
     265        }
    197266        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    198267            endpoint, direction);
     
    366435        if (ret != EOK)
    367436                return ret;
    368         usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);
     437        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    369438        batch_control_write(batch);
    370439        ret = hc_schedule(hc, batch);
     
    415484/*----------------------------------------------------------------------------*/
    416485usbhc_iface_t hc_iface = {
     486        .reserve_default_address = reserve_default_address,
     487        .release_default_address = release_default_address,
    417488        .request_address = request_address,
    418489        .bind_address = bind_address,
  • uspace/drv/ohci/ohci.ma

    r3f3afb9 r58226b4  
    1110 pci/ven=106b&dev=003f
    2 10 pci/ven=10de&dev=0aa5
    3 10 pci/ven=10de&dev=0aa5
  • uspace/drv/ohci/ohci_regs.h

    r3f3afb9 r58226b4  
    8484        /** Interupt enable/disable, reads give the same value, writing causes
    8585         * enable/disable */
    86         volatile uint32_t interrupt_enable;
     86        volatile uint32_t interupt_enable;
    8787        volatile uint32_t interrupt_disable;
    8888#define I_SO   (1 << 0)   /* Scheduling overrun */
     
    100100#define HCCA_PTR_MASK 0xffffff00 /* HCCA is 256B aligned */
    101101
    102         /** Currently executed periodic endpoint */
    103         const volatile uint32_t periodic_current;
     102        /** Currently executed period endpoint */
     103        const volatile uint32_t period_current;
    104104
    105105        /** The first control endpoint */
     
    120120        /** Frame time and max packet size for all transfers */
    121121        volatile uint32_t fm_interval;
    122 #define FMI_FI_MASK (0x3fff) /* Frame interval in bit times (should be 11999)*/
     122#define FMI_FI_MASK (0x1fff) /* Frame interval in bit times (should be 11999)*/
    123123#define FMI_FI_SHIFT (0)
    124124#define FMI_FSMPS_MASK (0x7fff) /* Full speed max packet size */
     
    138138        /** Remaining bit time in frame to start periodic transfers */
    139139        volatile uint32_t periodic_start;
    140 #define PS_PS_MASK (0x3fff) /* bit time when periodic get priority (0x3e67) */
     140#define PS_PS_MASK (0x1fff) /* bit time when periodic get priority (0x3e67) */
    141141
    142142        /** Threshold for starting LS transaction */
  • uspace/drv/ohci/root_hub.c

    r3f3afb9 r58226b4  
    210210        instance->registers = regs;
    211211        instance->device = dev;
    212         instance->port_count =
    213             (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;
     212        instance->port_count = instance->registers->rh_desc_a & 0xff;
    214213        rh_init_descriptors(instance);
    215214        // set port power mode to no-power-switching
  • uspace/drv/ohci/transfer_list.c

    r3f3afb9 r58226b4  
    7979        assert(instance);
    8080        assert(next);
     81        /* Set both queue_head.next to point to the follower */
    8182        ed_append_ed(instance->list_head, next->list_head);
    8283}
     
    121122        usb_transfer_batch_t *first = list_get_instance(
    122123            instance->batch_list.next, usb_transfer_batch_t, link);
    123         usb_log_debug("Batch(%p) added to list %s, first is %p(%p).\n",
    124                 batch, instance->name, first, batch_ed(first));
    125         if (last_ed == instance->list_head) {
    126                 usb_log_debug2("%s head ED(%p-%p): %x:%x:%x:%x.\n",
    127                     instance->name, last_ed, instance->list_head_pa,
    128                     last_ed->status, last_ed->td_tail, last_ed->td_head,
    129                     last_ed->next);
    130         }
     124        usb_log_debug("Batch(%p) added to queue %s, first is %p.\n",
     125                batch, instance->name, first);
    131126        fibril_mutex_unlock(&instance->guard);
    132127}
     
    143138
    144139        fibril_mutex_lock(&instance->guard);
    145         usb_log_debug2("Checking list %s for completed batches(%d).\n",
    146             instance->name, list_count(&instance->batch_list));
    147140        link_t *current = instance->batch_list.next;
    148141        while (current != &instance->batch_list) {
  • uspace/drv/ohci/utils/malloc32.h

    r3f3afb9 r58226b4  
    4141#include <as.h>
    4242
     43#define UHCI_STRCUTURES_ALIGNMENT 16
    4344#define UHCI_REQUIRED_PAGE_SIZE 4096
    4445
     
    6465 */
    6566static inline void * malloc32(size_t size)
    66         { return memalign(size, size); }
     67        { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); }
    6768/*----------------------------------------------------------------------------*/
    6869/** Physical mallocator simulator
  • uspace/drv/uhci-hcd/iface.c

    r3f3afb9 r58226b4  
    6363        }
    6464
    65         usb_log_debug("%s %d:%d %zu(%zu).\n",
    66             name, target.address, target.endpoint, size, ep->max_packet_size);
    67 
    6865        const size_t bw = bandwidth_count_usb11(
    6966            ep->speed, ep->transfer_type, size, ep->max_packet_size);
     
    7168                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    7269                    "but only %zu is reserved.\n",
    73                     target.address, target.endpoint, name, bw, res_bw);
     70                    name, target.address, target.endpoint, bw, res_bw);
    7471                return ENOSPC;
    7572        }
    76 
    77         *batch = batch_get(
    78                 fun, ep, data, size, setup_data, setup_size, in, out, arg);
    79         if (!*batch)
     73        usb_log_debug("%s %d:%d %zu(%zu).\n",
     74            name, target.address, target.endpoint, size, ep->max_packet_size);
     75
     76//      assert(ep->speed ==
     77//          usb_device_keeper_get_speed(&(*hc)->manager, target.address));
     78//      assert(ep->max_packet_size == max_packet_size);
     79//      assert(ep->transfer_type == USB_TRANSFER_CONTROL);
     80
     81        *batch =
     82            batch_get(fun, ep, data, size, setup_data, setup_size,
     83                in, out, arg);
     84        if (!batch)
    8085                return ENOMEM;
     86        return EOK;
     87}
     88
     89
     90/** Reserve default address interface function
     91 *
     92 * @param[in] fun DDF function that was called.
     93 * @param[in] speed Speed to associate with the new default address.
     94 * @return Error code.
     95 */
     96static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
     97{
     98        assert(fun);
     99        hc_t *hc = fun_to_hc(fun);
     100        assert(hc);
     101        usb_log_debug("Default address request with speed %d.\n", speed);
     102        usb_device_keeper_reserve_default_address(&hc->manager, speed);
     103        return EOK;
     104#if 0
     105        endpoint_t *ep = malloc(sizeof(endpoint_t));
     106        if (ep == NULL)
     107                return ENOMEM;
     108        const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;
     109        endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);
     110        int ret;
     111try_retgister:
     112        ret = usb_endpoint_manager_register_ep(&hc->ep_manager,
     113            USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);
     114        if (ret == EEXISTS) {
     115                async_usleep(1000);
     116                goto try_retgister;
     117        }
     118        if (ret != EOK) {
     119                endpoint_destroy(ep);
     120        }
     121        return ret;
     122#endif
     123}
     124/*----------------------------------------------------------------------------*/
     125/** Release default address interface function
     126 *
     127 * @param[in] fun DDF function that was called.
     128 * @return Error code.
     129 */
     130static int release_default_address(ddf_fun_t *fun)
     131{
     132        assert(fun);
     133        hc_t *hc = fun_to_hc(fun);
     134        assert(hc);
     135        usb_log_debug("Default address release.\n");
     136//      return usb_endpoint_manager_unregister_ep(&hc->ep_manager,
     137//          USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);
     138        usb_device_keeper_release_default_address(&hc->manager);
    81139        return EOK;
    82140}
     
    147205        hc_t *hc = fun_to_hc(fun);
    148206        assert(hc);
    149         const size_t size = max_packet_size;
    150         int ret;
    151207        usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
    152208        if (speed >= USB_SPEED_MAX) {
    153209                speed = ep_speed;
    154210        }
    155         usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    156             address, endpoint, usb_str_transfer_type(transfer_type),
    157             usb_str_speed(speed), direction, size, max_packet_size, interval);
    158 
     211        const size_t size =
     212            (transfer_type == USB_TRANSFER_INTERRUPT
     213            || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
     214            max_packet_size : 0;
     215        int ret;
    159216
    160217        endpoint_t *ep = malloc(sizeof(endpoint_t));
     
    168225        }
    169226
     227        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
     228            address, endpoint, usb_str_transfer_type(transfer_type),
     229            usb_str_speed(speed), direction, size, max_packet_size, interval);
     230
    170231        ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
    171232        if (ret != EOK) {
    172233                endpoint_destroy(ep);
     234        } else {
     235                usb_device_keeper_add_ep(&hc->manager, address, ep);
    173236        }
    174237        return ret;
     
    183246        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    184247            address, endpoint, direction);
     248        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     249            address, endpoint, direction, NULL);
     250        if (ep != NULL) {
     251                usb_device_keeper_del_ep(&hc->manager, address, ep);
     252        }
    185253        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    186254            endpoint, direction);
     
    323391        if (ret != EOK)
    324392                return ret;
    325         usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);
     393        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    326394        batch_control_write(batch);
    327395        ret = hc_schedule(hc, batch);
     
    365433/*----------------------------------------------------------------------------*/
    366434usbhc_iface_t hc_iface = {
     435        .reserve_default_address = reserve_default_address,
     436        .release_default_address = release_default_address,
    367437        .request_address = request_address,
    368438        .bind_address = bind_address,
  • uspace/drv/usbhid/Makefile

    r3f3afb9 r58226b4  
    4040        main.c \
    4141        usbhid.c \
    42         subdrivers.c \
    4342        kbd/conv.c \
    4443        kbd/kbddev.c \
    4544        kbd/kbdrepeat.c \
    4645        generic/hiddev.c \
    47         mouse/mousedev.c \
    4846        $(STOLEN_LAYOUT_SOURCES)
    4947
  • uspace/drv/usbhid/generic/hiddev.c

    r3f3afb9 r58226b4  
    3939
    4040#include "hiddev.h"
    41 #include "usbhid.h"
    4241
    4342/*----------------------------------------------------------------------------*/
     
    5554/*----------------------------------------------------------------------------*/
    5655
    57 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev,
    58     uint8_t *buffer, size_t buffer_size)
     56bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     57     size_t buffer_size, void *arg)
    5958{
    60         usb_log_debug("usb_hid_polling_callback(%p, %p, %zu)\n",
    61             hid_dev, buffer, buffer_size);
     59        usb_log_debug("usb_hid_polling_callback()\n");
    6260        usb_debug_str_buffer(buffer, buffer_size, 0);
    6361        return true;
  • uspace/drv/usbhid/generic/hiddev.h

    r3f3afb9 r58226b4  
    3434 */
    3535
    36 #ifndef USB_HID_HIDDDEV_H_
    37 #define USB_HID_HIDDDEV_H_
     36#ifndef USB_HIDD_H_
     37#define USB_HIDD_H_
    3838
    3939#include <usb/devdrv.h>
    40 
    41 struct usb_hid_dev;
    4240
    4341usb_endpoint_description_t usb_hid_generic_poll_endpoint_description;
     
    4644const char *HID_GENERIC_CLASS_NAME;
    4745
    48 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev,
    49     uint8_t *buffer, size_t buffer_size);
     46bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     47     size_t buffer_size, void *arg);
    5048
    51 #endif // USB_HID_HIDDDEV_H_
     49#endif // USB_HIDD_H_
    5250
    5351/**
  • uspace/drv/usbhid/kbd/conv.h

    r3f3afb9 r58226b4  
    3434 */
    3535
    36 #ifndef USB_HID_CONV_H_
    37 #define USB_HID_CONV_H_
     36#ifndef USB_KBD_CONV_H_
     37#define USB_KBD_CONV_H_
    3838
    3939unsigned int usbhid_parse_scancode(int scancode);
    4040
    41 #endif /* USB_HID_CONV_H_ */
     41#endif /* USB_KBD_CONV_H_ */
    4242
    4343/**
  • uspace/drv/usbhid/kbd/kbddev.c

    r3f3afb9 r58226b4  
    238238 * @param icall Call data.
    239239 */
    240 static void default_connection_handler(ddf_fun_t *fun,
     240void default_connection_handler(ddf_fun_t *fun,
    241241    ipc_callid_t icallid, ipc_call_t *icall)
    242242{
     
    856856/*----------------------------------------------------------------------------*/
    857857
    858 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, uint8_t *buffer,
    859      size_t buffer_size)
    860 {
    861         if (hid_dev == NULL || buffer == NULL) {
     858bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     859     size_t buffer_size, void *arg)
     860{
     861        if (dev == NULL || buffer == NULL || arg == NULL) {
    862862                // do not continue polling (???)
    863863                return false;
    864864        }
     865       
     866        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    865867       
    866868        // TODO: add return value from this function
     
    914916/*----------------------------------------------------------------------------*/
    915917
    916 void usb_kbd_deinit(usb_hid_dev_t *hid_dev)
     918void usb_kbd_deinit(struct usb_hid_dev_t *hid_dev)
    917919{
    918920        if (hid_dev == NULL) {
  • uspace/drv/usbhid/kbd/kbddev.h

    r3f3afb9 r58226b4  
    3434 */
    3535
    36 #ifndef USB_HID_KBDDEV_H_
    37 #define USB_HID_KBDDEV_H_
     36#ifndef USB_KBDDEV_H_
     37#define USB_KBDDEV_H_
    3838
    3939#include <stdint.h>
     
    4949#include "kbdrepeat.h"
    5050
    51 struct usb_hid_dev;
     51struct usb_hid_dev_t;
    5252
    5353/*----------------------------------------------------------------------------*/
     
    6565 */
    6666typedef struct usb_kbd_t {
     67        /** Structure holding generic USB device information. */
     68        //usbhid_dev_t *hid_dev;
     69        //usb_device_t *usb_dev;
     70       
    6771        /** Currently pressed keys (not translated to key codes). */
    6872        uint8_t *keys;
     
    8791        fibril_mutex_t *repeat_mtx;
    8892       
     93        /** Report descriptor. */
     94        //uint8_t *report_desc;
     95
     96        /** Report descriptor size. */
     97        //size_t report_desc_size;
     98       
    8999        uint8_t *output_buffer;
    90100       
     
    96106       
    97107        int32_t *led_data;
     108
     109        /** HID Report parser. */
     110        //usb_hid_report_parser_t *parser;
    98111       
    99112        /** State of the structure (for checking before use).
     
    108121/*----------------------------------------------------------------------------*/
    109122
     123//enum {
     124//      USB_KBD_POLL_EP_NO = 0,
     125//      USB_HID_POLL_EP_NO = 1,
     126//      USB_KBD_POLL_EP_COUNT = 2
     127//};
     128
     129//usb_endpoint_description_t *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1];
     130
     131//ddf_dev_ops_t keyboard_ops;
     132
    110133usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description;
    111134
     
    115138/*----------------------------------------------------------------------------*/
    116139
    117 int usb_kbd_init(struct usb_hid_dev *hid_dev);
     140//usb_kbd_t *usb_kbd_new(void);
    118141
    119 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,
    120     size_t buffer_size);
     142int usb_kbd_init(struct usb_hid_dev_t *hid_dev);
     143
     144bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     145     size_t buffer_size, void *arg);
     146
     147//void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
     148//     void *arg);
    121149
    122150int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev);
     
    126154void usb_kbd_free(usb_kbd_t **kbd_dev);
    127155
    128 void usb_kbd_push_ev(struct usb_hid_dev *hid_dev, usb_kbd_t *kbd_dev,
     156void usb_kbd_push_ev(struct usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev,
    129157    int type, unsigned int key);
    130158
    131 void usb_kbd_deinit(struct usb_hid_dev *hid_dev);
    132159
    133 int usb_kbd_set_boot_protocol(struct usb_hid_dev *hid_dev);
     160void usb_kbd_deinit(struct usb_hid_dev_t *hid_dev);
    134161
    135 #endif /* USB_HID_KBDDEV_H_ */
     162int usb_kbd_set_boot_protocol(struct usb_hid_dev_t *hid_dev);
     163
     164#endif /* USB_KBDDEV_H_ */
    136165
    137166/**
  • uspace/drv/usbhid/kbd/kbdrepeat.h

    r3f3afb9 r58226b4  
    3434 */
    3535
    36 #ifndef USB_HID_KBDREPEAT_H_
    37 #define USB_HID_KBDREPEAT_H_
     36#ifndef USB_KBDREPEAT_H_
     37#define USB_KBDREPEAT_H_
    3838
    3939struct usb_kbd_t;
     
    6262void usb_kbd_repeat_stop(struct usb_kbd_t *kbd, unsigned int key);
    6363
    64 #endif /* USB_HID_KBDREPEAT_H_ */
     64#endif /* USB_KBDREPEAT_H_ */
    6565
    6666/**
  • uspace/drv/usbhid/layout.h

    r3f3afb9 r58226b4  
    3636 */
    3737
    38 #ifndef USB_HID_LAYOUT_H_
    39 #define USB_HID_LAYOUT_H_
     38#ifndef USB_KBD_LAYOUT_H_
     39#define USB_KBD_LAYOUT_H_
    4040
    4141#include <sys/types.h>
  • uspace/drv/usbhid/main.c

    r3f3afb9 r58226b4  
    9898        /* Create the function exposed under /dev/devices. */
    9999        ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
    100             usb_hid_get_function_name(hid_dev));
     100            usb_hid_get_function_name(hid_dev->device_type));
    101101        if (hid_fun == NULL) {
    102102                usb_log_error("Could not create DDF function node.\n");
     
    122122        }
    123123       
    124         rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev));
     124        rc = ddf_fun_add_to_class(hid_fun,
     125            usb_hid_get_class_name(hid_dev->device_type));
    125126        if (rc != EOK) {
    126127                usb_log_error(
     
    141142           hid_dev->poll_pipe_index,
    142143           /* Callback when data arrives. */
    143            usb_hid_polling_callback,
     144           hid_dev->poll_callback,
    144145           /* How much data to request. */
    145146           dev->pipes[hid_dev->poll_pipe_index].pipe->max_packet_size,
  • uspace/drv/usbhid/usbhid.c

    r3f3afb9 r58226b4  
    4242#include <usb/classes/hidreq.h>
    4343#include <errno.h>
    44 #include <str_error.h>
    4544
    4645#include "usbhid.h"
     
    4847#include "kbd/kbddev.h"
    4948#include "generic/hiddev.h"
    50 #include "mouse/mousedev.h"
    51 #include "subdrivers.h"
    52 
    53 /*----------------------------------------------------------------------------*/
     49
     50/*----------------------------------------------------------------------------*/
     51
     52/** Mouse polling endpoint description for boot protocol class. */
     53static usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {
     54        .transfer_type = USB_TRANSFER_INTERRUPT,
     55        .direction = USB_DIRECTION_IN,
     56        .interface_class = USB_CLASS_HID,
     57        .interface_subclass = USB_HID_SUBCLASS_BOOT,
     58        .interface_protocol = USB_HID_PROTOCOL_MOUSE,
     59        .flags = 0
     60};
    5461
    5562/* Array of endpoints expected on the device, NULL terminated. */
     
    6168};
    6269
    63 static const int USB_HID_MAX_SUBDRIVERS = 10;
    64 
    65 /*----------------------------------------------------------------------------*/
    66 
    67 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    68 {
    69         assert(hid_dev->subdriver_count == 0);
    70        
    71         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    72             sizeof(usb_hid_subdriver_t));
    73         if (hid_dev->subdrivers == NULL) {
    74                 return ENOMEM;
    75         }
    76        
    77         // set the init callback
    78         hid_dev->subdrivers[0].init = usb_kbd_init;
    79        
    80         // set the polling callback
    81         hid_dev->subdrivers[0].poll = usb_kbd_polling_callback;
    82        
    83         // set the polling ended callback
    84         hid_dev->subdrivers[0].poll_end = NULL;
    85        
    86         // set the deinit callback
    87         hid_dev->subdrivers[0].deinit = usb_kbd_deinit;
    88        
    89         // set subdriver count
    90         hid_dev->subdriver_count = 1;
    91        
    92         return EOK;
    93 }
    94 
    95 /*----------------------------------------------------------------------------*/
    96 
    97 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    98 {
    99         assert(hid_dev->subdriver_count == 0);
    100        
    101         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    102             sizeof(usb_hid_subdriver_t));
    103         if (hid_dev->subdrivers == NULL) {
    104                 return ENOMEM;
    105         }
    106        
    107         // set the init callback
    108         hid_dev->subdrivers[0].init = usb_mouse_init;
    109        
    110         // set the polling callback
    111         hid_dev->subdrivers[0].poll = usb_mouse_polling_callback;
    112        
    113         // set the polling ended callback
    114         hid_dev->subdrivers[0].poll_end = NULL;
    115        
    116         // set the deinit callback
    117         hid_dev->subdrivers[0].deinit = usb_mouse_deinit;
    118        
    119         // set subdriver count
    120         hid_dev->subdriver_count = 1;
    121        
    122         return EOK;
    123 }
    124 
    125 /*----------------------------------------------------------------------------*/
    126 
    127 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev)
    128 {
    129         assert(hid_dev->subdriver_count == 0);
    130        
    131         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    132             sizeof(usb_hid_subdriver_t));
    133         if (hid_dev->subdrivers == NULL) {
    134                 return ENOMEM;
    135         }
    136        
    137         // set the init callback
    138         hid_dev->subdrivers[0].init = NULL;
    139        
    140         // set the polling callback
    141         hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback;
    142        
    143         // set the polling ended callback
    144         hid_dev->subdrivers[0].poll_end = NULL;
    145        
    146         // set the deinit callback
    147         hid_dev->subdrivers[0].deinit = NULL;
    148        
    149         // set subdriver count
    150         hid_dev->subdriver_count = 1;
    151        
    152         return EOK;
    153 }
    154 
    155 /*----------------------------------------------------------------------------*/
    156 
    157 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev,
    158     const usb_hid_subdriver_mapping_t *mapping)
    159 {
    160         return false;
    161 }
    162 
    163 /*----------------------------------------------------------------------------*/
    164 
    165 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
    166     const usb_hid_subdriver_usage_t *path, int path_size, int compare)
    167 {
    168         assert(hid_dev != NULL);
    169         assert(path != NULL);
    170        
    171         usb_hid_report_path_t *usage_path = usb_hid_report_path();
    172         if (usage_path == NULL) {
    173                 usb_log_debug("Failed to create usage path.\n");
    174                 return false;
    175         }
    176         int i;
    177         for (i = 0; i < path_size; ++i) {
    178                 if (usb_hid_report_path_append_item(usage_path,
    179                     path[i].usage_page, path[i].usage) != EOK) {
    180                         usb_log_debug("Failed to append to usage path.\n");
    181                         usb_hid_report_path_free(usage_path);
    182                         return false;
    183                 }
    184         }
    185        
    186         assert(hid_dev->parser != NULL);
    187        
    188         usb_log_debug("Compare flags: %d\n", compare);
    189         size_t size = usb_hid_report_input_length(hid_dev->parser, usage_path,
    190             compare);
    191         usb_log_debug("Size of the input report: %d\n", size);
    192        
    193         usb_hid_report_path_free(usage_path);
    194        
    195         return (size > 0);
    196 }
    197 
    198 /*----------------------------------------------------------------------------*/
    199 
    200 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
    201     const usb_hid_subdriver_t **subdrivers, int count)
    202 {
    203         int i;
    204        
    205         if (count <= 0) {
    206                 hid_dev->subdriver_count = 0;
    207                 hid_dev->subdrivers = NULL;
    208                 return EOK;
    209         }
    210        
    211         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count *
    212             sizeof(usb_hid_subdriver_t));
    213         if (hid_dev->subdrivers == NULL) {
    214                 return ENOMEM;
    215         }
    216        
    217         for (i = 0; i < count; ++i) {
    218                 hid_dev->subdrivers[i].init = subdrivers[i]->init;
    219                 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit;
    220                 hid_dev->subdrivers[i].poll = subdrivers[i]->poll;
    221                 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end;
    222         }
    223        
    224         hid_dev->subdriver_count = count;
    225        
    226         return EOK;
    227 }
    228 
    229 /*----------------------------------------------------------------------------*/
    230 
    231 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev)
    232 {
    233         const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
    234        
    235         int i = 0, count = 0;
    236         const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i];
    237        
    238         while (count < USB_HID_MAX_SUBDRIVERS &&
    239             (mapping->usage_path != NULL
    240             || mapping->vendor_id != NULL
    241             || mapping->product_id != NULL)) {
    242                 // check the vendor & product ID
    243                 if (mapping->vendor_id != NULL && mapping->product_id == NULL) {
    244                         usb_log_warning("Missing Product ID for Vendor ID %s\n",
    245                             mapping->vendor_id);
    246                         return EINVAL;
    247                 }
    248                 if (mapping->product_id != NULL && mapping->vendor_id == NULL) {
    249                         usb_log_warning("Missing Vendor ID for Product ID %s\n",
    250                             mapping->product_id);
    251                         return EINVAL;
    252                 }
    253                
    254                 if (mapping->vendor_id != NULL) {
    255                         assert(mapping->product_id != NULL);
    256                         usb_log_debug("Comparing device against vendor ID %s"
    257                             " and product ID %s.\n", mapping->vendor_id,
    258                             mapping->product_id);
    259                         if (usb_hid_ids_match(hid_dev, mapping)) {
    260                                 usb_log_debug("Matched.\n");
    261                                 subdrivers[count++] = &mapping->subdriver;
    262                                 // skip the checking of usage path
    263                                 goto next;
    264                         }
    265                 }
    266                
    267                 if (mapping->usage_path != NULL) {
    268                         usb_log_debug("Comparing device against usage path.\n");
    269                         if (usb_hid_path_matches(hid_dev,
    270                             mapping->usage_path, mapping->path_size,
    271                             mapping->compare)) {
    272                                 subdrivers[count++] = &mapping->subdriver;
    273                         } else {
    274                                 usb_log_debug("Not matched.\n");
    275                         }
    276                 }
    277         next:
    278                 mapping = &usb_hid_subdrivers[++i];
    279         }
    280        
    281         // we have all subdrivers determined, save them into the hid device
    282         return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    283 }
    284 
    285 /*----------------------------------------------------------------------------*/
    286 
    287 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    288 {
    289         int rc = EOK;
    290        
    291         if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
    292                 usb_log_debug("Found keyboard endpoint.\n");
    293                 // save the pipe index
    294                 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
    295         } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
    296                 usb_log_debug("Found mouse endpoint.\n");
    297                 // save the pipe index
    298                 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
    299         } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
    300                 usb_log_debug("Found generic HID endpoint.\n");
    301                 // save the pipe index
    302                 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
    303         } else {
    304                 usb_log_error("None of supported endpoints found - probably"
    305                     " not a supported device.\n");
    306                 rc = ENOTSUP;
    307         }
    308        
    309         return rc;
    310 }
     70static const char *HID_MOUSE_FUN_NAME = "mouse";
     71static const char *HID_MOUSE_CLASS_NAME = "mouse";
    31172
    31273/*----------------------------------------------------------------------------*/
     
    33091        }
    33192       
    332         hid_dev->poll_pipe_index = -1;
    333        
    33493        return hid_dev;
    33594}
     
    33796/*----------------------------------------------------------------------------*/
    33897
     98static bool usb_dummy_polling_callback(usb_device_t *dev, uint8_t *buffer,
     99     size_t buffer_size, void *arg)
     100{
     101        usb_log_debug("Dummy polling callback.\n");
     102        return false;
     103}
     104
     105/*----------------------------------------------------------------------------*/
     106
     107static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
     108{
     109        if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
     110                usb_log_debug("Found keyboard endpoint.\n");
     111               
     112                // save the pipe index and device type
     113                hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
     114                hid_dev->device_type = USB_HID_PROTOCOL_KEYBOARD;
     115               
     116                // set the polling callback
     117                hid_dev->poll_callback = usb_kbd_polling_callback;
     118
     119        } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
     120                usb_log_debug("Found mouse endpoint.\n");
     121               
     122                // save the pipe index and device type
     123                hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
     124                hid_dev->device_type = USB_HID_PROTOCOL_MOUSE;
     125               
     126                // set the polling callback
     127                hid_dev->poll_callback = usb_dummy_polling_callback;
     128               
     129        } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
     130                usb_log_debug("Found generic HID endpoint.\n");
     131               
     132                // save the pipe index and device type
     133                hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
     134                hid_dev->device_type = USB_HID_PROTOCOL_NONE;
     135               
     136                // set the polling callback
     137                hid_dev->poll_callback = usb_hid_polling_callback;
     138               
     139        } else {
     140                usb_log_warning("None of supported endpoints found - probably"
     141                    " not a supported device.\n");
     142                return ENOTSUP;
     143        }
     144       
     145        return EOK;
     146}
     147
     148/*----------------------------------------------------------------------------*/
     149
     150static int usb_hid_init_parser(usb_hid_dev_t *hid_dev)
     151{
     152        /* Initialize the report parser. */
     153        int rc = usb_hid_parser_init(hid_dev->parser);
     154        if (rc != EOK) {
     155                usb_log_error("Failed to initialize report parser.\n");
     156                return rc;
     157        }
     158       
     159        /* Get the report descriptor and parse it. */
     160        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
     161            hid_dev->parser);
     162       
     163        if (rc != EOK) {
     164                usb_log_warning("Could not process report descriptor.\n");
     165               
     166                if (hid_dev->device_type == USB_HID_PROTOCOL_KEYBOARD) {
     167                        usb_log_warning("Falling back to boot protocol.\n");
     168                       
     169                        rc = usb_kbd_set_boot_protocol(hid_dev);
     170                       
     171                } else if (hid_dev->device_type == USB_HID_PROTOCOL_MOUSE) {
     172                        usb_log_warning("No boot protocol for mouse yet.\n");
     173                        rc = ENOTSUP;
     174                }
     175        }
     176       
     177        return rc;
     178}
     179
     180/*----------------------------------------------------------------------------*/
     181
    339182int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    340183{
    341         int rc, i;
     184        int rc;
    342185       
    343186        usb_log_debug("Initializing HID structure...\n");
     
    360203        rc = usb_hid_check_pipes(hid_dev, dev);
    361204        if (rc != EOK) {
    362                 usb_hid_free(&hid_dev);
    363205                return rc;
    364206        }
    365207       
    366         /* Initialize the report parser. */
    367         rc = usb_hid_parser_init(hid_dev->parser);
     208        rc = usb_hid_init_parser(hid_dev);
    368209        if (rc != EOK) {
    369                 usb_log_error("Failed to initialize report parser.\n");
    370                 usb_hid_free(&hid_dev);
     210                usb_log_error("Failed to initialize HID parser.\n");
    371211                return rc;
    372212        }
    373213       
    374         /* Get the report descriptor and parse it. */
    375         rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    376             hid_dev->parser);
    377        
    378         bool fallback = false;
    379        
    380         if (rc == EOK) {
    381                 // try to find subdrivers that may want to handle this device
    382                 rc = usb_hid_find_subdrivers(hid_dev);
    383                 if (rc != EOK || hid_dev->subdriver_count == 0) {
    384                         // try to fall back to the boot protocol if available
    385                         usb_log_info("No subdrivers found to handle this"
    386                             " device.\n");
    387                         fallback = true;
     214        switch (hid_dev->device_type) {
     215        case USB_HID_PROTOCOL_KEYBOARD:
     216                // initialize the keyboard structure
     217                rc = usb_kbd_init(hid_dev);
     218                if (rc != EOK) {
     219                        usb_log_warning("Failed to initialize KBD structure."
     220                            "\n");
    388221                }
    389         } else {
    390                 usb_log_error("Failed to parse Report descriptor.\n");
    391                 // try to fall back to the boot protocol if available
    392                 fallback = true;
    393         }
    394        
    395         // TODO: remove the mouse hack
    396         if (hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO ||
    397             fallback) {
    398                 // fall back to boot protocol
    399                 switch (hid_dev->poll_pipe_index) {
    400                 case USB_HID_KBD_POLL_EP_NO:
    401                         usb_log_info("Falling back to kbd boot protocol.\n");
    402                         rc = usb_kbd_set_boot_protocol(hid_dev);
    403                         if (rc == EOK) {
    404                                 rc = usb_hid_set_boot_kbd_subdriver(hid_dev);
    405                         }
    406                         break;
    407                 case USB_HID_MOUSE_POLL_EP_NO:
    408                         usb_log_info("Falling back to mouse boot protocol.\n");
    409                         rc = usb_mouse_set_boot_protocol(hid_dev);
    410                         if (rc == EOK) {
    411                                 rc = usb_hid_set_boot_mouse_subdriver(hid_dev);
    412                         }
    413                         break;
    414                 default:
    415                         assert(hid_dev->poll_pipe_index
    416                             == USB_HID_GENERIC_POLL_EP_NO);
    417                        
    418                         /* TODO: this has no meaning if the report descriptor
    419                                  is not parsed */
    420                         usb_log_info("Falling back to generic HID driver.\n");
    421                         rc = usb_hid_set_generic_hid_subdriver(hid_dev);
    422                 }
    423         }
    424        
    425         if (rc != EOK) {
    426                 usb_log_error("No subdriver for handling this device could be"
    427                     " initialized: %s.\n", str_error(rc));
    428                 usb_hid_free(&hid_dev);
    429         } else {
    430                 bool ok = false;
    431                
    432                 usb_log_debug("Subdriver count: %d\n",
    433                     hid_dev->subdriver_count);
    434                
    435                 for (i = 0; i < hid_dev->subdriver_count; ++i) {
    436                         if (hid_dev->subdrivers[i].init != NULL) {
    437                                 usb_log_debug("Initializing subdriver %d.\n",i);
    438                                 rc = hid_dev->subdrivers[i].init(hid_dev);
    439                                 if (rc != EOK) {
    440                                         usb_log_warning("Failed to initialize"
    441                                             " HID subdriver structure.\n");
    442                                 } else {
    443                                         // at least one subdriver initialized
    444                                         ok = true;
    445                                 }
    446                         } else {
    447                                 ok = true;
    448                         }
    449                 }
    450                
    451                 rc = (ok) ? EOK : -1;   // what error to report
     222                break;
     223        case USB_HID_PROTOCOL_MOUSE:
     224                break;
     225        default:
     226//              usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     227//                  hid_dev->usb_dev->interface_no, 0);
     228                break;
    452229        }
    453230       
    454231        return rc;
    455 }
    456 
    457 /*----------------------------------------------------------------------------*/
    458 
    459 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    460     size_t buffer_size, void *arg)
    461 {
    462         int i;
    463        
    464         if (dev == NULL || arg == NULL || buffer == NULL) {
    465                 usb_log_error("Missing arguments to polling callback.\n");
    466                 return false;
    467         }
    468        
    469         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    470        
    471         bool cont = false;
    472        
    473         // continue if at least one of the subdrivers want to continue
    474         for (i = 0; i < hid_dev->subdriver_count; ++i) {
    475                 if (hid_dev->subdrivers[i].poll != NULL
    476                     && hid_dev->subdrivers[i].poll(hid_dev, buffer,
    477                     buffer_size)) {
    478                         cont = true;
    479                 }
    480         }
    481        
    482         return cont;
    483232}
    484233
     
    488237     void *arg)
    489238{
    490         int i;
    491        
    492239        if (dev == NULL || arg == NULL) {
    493240                return;
     
    496243        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    497244       
    498         for (i = 0; i < hid_dev->subdriver_count; ++i) {
    499                 if (hid_dev->subdrivers[i].poll_end != NULL) {
    500                         hid_dev->subdrivers[i].poll_end(hid_dev, reason);
    501                 }
    502         }
    503        
    504245        usb_hid_free(&hid_dev);
    505246}
     
    507248/*----------------------------------------------------------------------------*/
    508249
    509 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
    510 {
    511         switch (hid_dev->poll_pipe_index) {
    512         case USB_HID_KBD_POLL_EP_NO:
     250const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type)
     251{
     252        switch (device_type) {
     253        case USB_HID_PROTOCOL_KEYBOARD:
    513254                return HID_KBD_FUN_NAME;
    514255                break;
    515         case USB_HID_MOUSE_POLL_EP_NO:
     256        case USB_HID_PROTOCOL_MOUSE:
    516257                return HID_MOUSE_FUN_NAME;
    517258                break;
     
    523264/*----------------------------------------------------------------------------*/
    524265
    525 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
    526 {
    527         // this means that only boot protocol keyboards will be connected
    528         // to the console; there is probably no better way to do this
    529        
    530         switch (hid_dev->poll_pipe_index) {
    531         case USB_HID_KBD_POLL_EP_NO:
     266const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type)
     267{
     268        switch (device_type) {
     269        case USB_HID_PROTOCOL_KEYBOARD:
    532270                return HID_KBD_CLASS_NAME;
    533271                break;
    534         case USB_HID_MOUSE_POLL_EP_NO:
     272        case USB_HID_PROTOCOL_MOUSE:
    535273                return HID_MOUSE_CLASS_NAME;
    536274                break;
     
    544282void usb_hid_free(usb_hid_dev_t **hid_dev)
    545283{
    546         int i;
    547        
    548284        if (hid_dev == NULL || *hid_dev == NULL) {
    549285                return;
    550286        }
    551287       
    552         assert((*hid_dev)->subdrivers != NULL
    553             || (*hid_dev)->subdriver_count == 0);
    554        
    555         for (i = 0; i < (*hid_dev)->subdriver_count; ++i) {
    556                 if ((*hid_dev)->subdrivers[i].deinit != NULL) {
    557                         (*hid_dev)->subdrivers[i].deinit(*hid_dev);
    558                 }
    559         }
    560        
    561         // free the subdrivers info
    562         if ((*hid_dev)->subdrivers != NULL) {
    563                 free((*hid_dev)->subdrivers);
     288        switch ((*hid_dev)->device_type) {
     289        case USB_HID_PROTOCOL_KEYBOARD:
     290                usb_kbd_deinit(*hid_dev);
     291                break;
     292        case USB_HID_PROTOCOL_MOUSE:
     293                break;
     294        default:
     295                break;
    564296        }
    565297
  • uspace/drv/usbhid/usbhid.h

    r3f3afb9 r58226b4  
    3434 */
    3535
    36 #ifndef USB_HID_USBHID_H_
    37 #define USB_HID_USBHID_H_
     36#ifndef USB_USBHID_H_
     37#define USB_USBHID_H_
    3838
    3939#include <stdint.h>
     
    4545#include <usb/classes/hid.h>
    4646
    47 struct usb_hid_dev;
    48 
    49 typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *);
    50 typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *);
    51 typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, uint8_t *, size_t);
    52 typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, bool reason);
    53 
    54 // TODO: add function and class name??
    55 typedef struct usb_hid_subdriver {     
    56         /** Function to be called when initializing HID device. */
    57         usb_hid_driver_init_t init;
    58         /** Function to be called when destroying the HID device structure. */
    59         usb_hid_driver_deinit_t deinit;
    60         /** Function to be called when data arrives from the device. */
    61         usb_hid_driver_poll poll;
    62         /** Function to be called when polling ends. */
    63         usb_hid_driver_poll_ended poll_end;
    64 } usb_hid_subdriver_t;
    65 
    6647/*----------------------------------------------------------------------------*/
    6748/**
    6849 * Structure for holding general HID device data.
    6950 */
    70 typedef struct usb_hid_dev {
     51typedef struct usb_hid_dev_t {
    7152        /** Structure holding generic USB device information. */
    7253        usb_device_t *usb_dev;
     
    7859        int poll_pipe_index;
    7960       
    80         /** Subdrivers. */
    81         usb_hid_subdriver_t *subdrivers;
    82        
    83         /** Number of subdrivers. */
    84         int subdriver_count;
     61        /** Function to be called when data arrives from the device. */
     62        usb_polling_callback_t poll_callback;
    8563       
    8664        /** Report descriptor. */
     
    9573        /** Arbitrary data (e.g. a special structure for handling keyboard). */
    9674        void *data;
     75       
     76        /** Type of the device (keyboard, mouse, generic HID device). */
     77        usb_hid_iface_protocol_t device_type;
    9778} usb_hid_dev_t;
    9879
     
    11495int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev);
    11596
    116 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    117     size_t buffer_size, void *arg);
    118 
    11997void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason,
    12098     void *arg);
    12199
    122 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
     100const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type);
    123101
    124 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
     102const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type);
    125103
    126104void usb_hid_free(usb_hid_dev_t **hid_dev);
    127105
    128 #endif /* USB_HID_USBHID_H_ */
     106#endif /* USB_USBHID_H_ */
    129107
    130108/**
  • uspace/drv/usbhid/usbhid.ma

    r3f3afb9 r58226b4  
    11100 usb&interface&class=HID&subclass=0x01&protocol=0x01
    2 1000 usb&interface&class=HID&subclass=0x01&protocol=0x02
     2100 usb&interface&class=HID&subclass=0x01&protocol=0x02
    33100 usb&interface&class=HID
  • uspace/drv/usbhub/ports.c

    r3f3afb9 r58226b4  
    181181                 */
    182182        } else {
    183                 // TODO: is this really reason to print a warning?
    184                 usb_log_warning("Device removed before being registered.\n");
    185 
    186                 /*
    187                  * Device was removed before port reset completed.
    188                  * We will announce a failed port reset to unblock the
    189                  * port reset callback from new device wrapper.
    190                  */
    191                 usb_hub_port_t *the_port = hub->ports + port;
    192                 fibril_mutex_lock(&the_port->reset_mutex);
    193                 the_port->reset_completed = true;
    194                 the_port->reset_okay = false;
    195                 fibril_condvar_broadcast(&the_port->reset_cv);
    196                 fibril_mutex_unlock(&the_port->reset_mutex);
     183                usb_log_warning("this is strange, disconnected device had "
     184                        "no address\n");
     185                //device was disconnected before it`s port was reset -
     186                //return default address
     187                usb_hub_release_default_address(hub);
    197188        }
    198189}
     
    216207                fibril_mutex_lock(&the_port->reset_mutex);
    217208                the_port->reset_completed = true;
    218                 the_port->reset_okay = true;
    219209                fibril_condvar_broadcast(&the_port->reset_cv);
    220210                fibril_mutex_unlock(&the_port->reset_mutex);
     
    329319        }
    330320
    331         if (my_port->reset_okay) {
    332                 return EOK;
    333         } else {
    334                 return ESTALL;
    335         }
     321        return EOK;
    336322}
    337323
  • uspace/drv/usbhub/ports.h

    r3f3afb9 r58226b4  
    5151         */
    5252        bool reset_completed;
    53         /** Whether to announce the port reset as successful. */
    54         bool reset_okay;
    5553
    5654        /** Information about attached device. */
  • uspace/drv/usbhub/usbhub.c

    r3f3afb9 r58226b4  
    179179}
    180180
     181/**
     182 * release default address used by given hub
     183 *
     184 * Also unsets hub->is_default_address_used. Convenience wrapper function.
     185 * @note hub->connection MUST be open for communication
     186 * @param hub hub representation
     187 * @return error code
     188 */
     189int usb_hub_release_default_address(usb_hub_info_t * hub) {
     190        int opResult = usb_hc_release_default_address(&hub->connection);
     191        if (opResult != EOK) {
     192                usb_log_error("could not release default address, errno %d\n",
     193                    opResult);
     194                return opResult;
     195        }
     196        hub->is_default_address_used = false;
     197        return EOK;
     198}
     199
    181200
    182201//*********************************************
     
    247266        for (port = 0; port < hub_info->port_count + 1; port++) {
    248267                usb_hub_port_init(&hub_info->ports[port]);
    249         }
    250         for (port = 0; port < hub_info->port_count; port++) {
    251268                opResult = usb_hub_set_port_feature(hub_info->control_pipe,
    252                     port+1, USB_HUB_FEATURE_PORT_POWER);
     269                    port, USB_HUB_FEATURE_PORT_POWER);
    253270                if (opResult != EOK) {
    254271                        usb_log_error("cannot power on port %d;  %d\n",
    255                             port+1, opResult);
     272                            port, opResult);
    256273                }
    257274        }
  • uspace/drv/usbhub/usbhub.h

    r3f3afb9 r58226b4  
    9898    uint8_t *change_bitmap, size_t change_bitmap_size, void *arg);
    9999
     100int usb_hub_release_default_address(usb_hub_info_t * hub);
     101
    100102#endif
    101103/**
  • uspace/drv/vhc/connhost.c

    r3f3afb9 r58226b4  
    324324}
    325325
     326static int reserve_default_address(ddf_fun_t *fun, usb_speed_t ignored)
     327{
     328        usb_address_keeping_reserve_default(&addresses);
     329        return EOK;
     330}
     331
     332static int release_default_address(ddf_fun_t *fun)
     333{
     334        usb_address_keeping_release_default(&addresses);
     335        return EOK;
     336}
     337
    326338static int request_address(ddf_fun_t *fun, usb_speed_t ignored,
    327339    usb_address_t *address)
     
    376388
    377389usbhc_iface_t vhc_iface = {
     390        .reserve_default_address = reserve_default_address,
     391        .release_default_address = release_default_address,
    378392        .request_address = request_address,
    379393        .bind_address = bind_address,
  • uspace/lib/drv/generic/remote_usbhc.c

    r3f3afb9 r58226b4  
    5050static void remote_usbhc_control_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    5151static void remote_usbhc_control_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     52static void remote_usbhc_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     53static void remote_usbhc_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    5254static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    5355static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     
    5961/** Remote USB host controller interface operations. */
    6062static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
     63        remote_usbhc_reserve_default_address,
     64        remote_usbhc_release_default_address,
     65
    6166        remote_usbhc_request_address,
    6267        remote_usbhc_bind_address,
     
    122127
    123128        return trans;
     129}
     130
     131void remote_usbhc_reserve_default_address(ddf_fun_t *fun, void *iface,
     132    ipc_callid_t callid, ipc_call_t *call)
     133{
     134        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     135
     136        if (!usb_iface->reserve_default_address) {
     137                async_answer_0(callid, ENOTSUP);
     138                return;
     139        }
     140       
     141        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
     142       
     143        int rc = usb_iface->reserve_default_address(fun, speed);
     144
     145        async_answer_0(callid, rc);
     146}
     147
     148void remote_usbhc_release_default_address(ddf_fun_t *fun, void *iface,
     149    ipc_callid_t callid, ipc_call_t *call)
     150{
     151        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     152
     153        if (!usb_iface->release_default_address) {
     154                async_answer_0(callid, ENOTSUP);
     155                return;
     156        }
     157
     158        int rc = usb_iface->release_default_address(fun);
     159
     160        async_answer_0(callid, rc);
    124161}
    125162
  • uspace/lib/drv/include/usbhc_iface.h

    r3f3afb9 r58226b4  
    8484 */
    8585typedef enum {
     86        /** Reserve usage of default address.
     87         * This call informs the host controller that the caller will be
     88         * using default USB address. It is duty of the HC driver to ensure
     89         * that only single entity will have it reserved.
     90         * The address is returned via IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS.
     91         * The caller can start using the address after receiving EOK
     92         * answer.
     93         */
     94        IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS,
     95
     96        /** Release usage of default address.
     97         * @see IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS
     98         */
     99        IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS,
     100
    86101        /** Asks for address assignment by host controller.
    87102         * Answer:
  • uspace/lib/usb/Makefile

    r3f3afb9 r58226b4  
    3434SOURCES = \
    3535        src/addrkeep.c \
    36         src/altiface.c \
    3736        src/class.c \
    3837        src/ddfiface.c \
  • uspace/lib/usb/include/usb/devdrv.h

    r3f3afb9 r58226b4  
    174174    usb_endpoint_mapping_t **, size_t *);
    175175int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
    176 int usb_device_create(ddf_dev_t *, usb_endpoint_description_t **, usb_device_t **, const char **);
    177176
    178177size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
    179 int usb_alternate_interfaces_create(uint8_t *, size_t, int,
    180     usb_alternate_interfaces_t **);
    181178
    182179#endif
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r3f3afb9 r58226b4  
    7171void usb_device_keeper_init(usb_device_keeper_t *instance);
    7272
     73void usb_device_keeper_add_ep(
     74    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
     75void usb_device_keeper_del_ep(
     76    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
     77
    7378void usb_device_keeper_reserve_default_address(
    7479    usb_device_keeper_t *instance, usb_speed_t speed);
  • uspace/lib/usb/include/usb/host/endpoint.h

    r3f3afb9 r58226b4  
    5454        fibril_condvar_t avail;
    5555        volatile bool active;
     56        link_t same_device_eps;
    5657} endpoint_t;
    5758
     
    7071void endpoint_toggle_set(endpoint_t *instance, int toggle);
    7172
    72 void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target);
     73void endpoint_toggle_reset(link_t *ep);
     74
     75void endpoint_toggle_reset_filtered(link_t *ep, usb_endpoint_t epn);
     76
    7377#endif
    7478/**
  • uspace/lib/usb/include/usb/host/usb_endpoint_manager.h

    r3f3afb9 r58226b4  
    7878    size_t *bw);
    7979
    80 void usb_endpoint_manager_reset_if_need(
    81     usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
    8280#endif
    8381/**
  • uspace/lib/usb/include/usb/hub.h

    r3f3afb9 r58226b4  
    5959} usb_hc_attached_device_t;
    6060
     61int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t);
     62int usb_hc_release_default_address(usb_hc_connection_t *);
     63
    6164usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
    6265int usb_hc_register_device(usb_hc_connection_t *,
  • uspace/lib/usb/include/usb/request.h

    r3f3afb9 r58226b4  
    5050/** USB endpoint status - endpoint is halted (stalled). */
    5151#define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0))
    52 
    53 /** USB feature selector - endpoint halt (stall). */
    54 #define USB_FEATURE_SELECTOR_ENDPOINT_HALT (0)
    55 
    56 /** USB feature selector - device remote wake-up. */
    57 #define USB_FEATURE_SELECTOR_REMOTE_WAKEUP (1)
    5852
    5953/** Standard device request. */
     
    141135    char **);
    142136
    143 int usb_request_clear_endpoint_halt(usb_pipe_t *, uint16_t);
    144 
    145137#endif
    146138/**
  • uspace/lib/usb/src/devdrv.c

    r3f3afb9 r58226b4  
    100100    usb_device_t *dev, int alternate_setting)
    101101{
    102         if (endpoints == NULL) {
    103                 dev->pipes = NULL;
    104                 dev->pipes_count = 0;
    105                 return EOK;
    106         }
    107 
    108102        usb_endpoint_mapping_t *pipes;
    109103        size_t pipes_count;
     
    115109
    116110        if (rc != EOK) {
     111                usb_log_error(
     112                    "Failed to create endpoint pipes for `%s': %s.\n",
     113                    dev->ddf_dev->name, str_error(rc));
    117114                return rc;
    118115        }
     
    120117        dev->pipes = pipes;
    121118        dev->pipes_count = pipes_count;
     119
     120        return EOK;
     121}
     122
     123/** Initialize all endpoint pipes.
     124 *
     125 * @param drv The driver.
     126 * @param dev The device to be initialized.
     127 * @return Error code.
     128 */
     129static int initialize_pipes(usb_device_t *dev)
     130{
     131        int rc;
     132
     133        rc = usb_device_connection_initialize_from_device(&dev->wire,
     134            dev->ddf_dev);
     135        if (rc != EOK) {
     136                usb_log_error(
     137                    "Failed initializing connection on device `%s'. %s.\n",
     138                    dev->ddf_dev->name, str_error(rc));
     139                return rc;
     140        }
     141
     142        rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,
     143            &dev->wire);
     144        if (rc != EOK) {
     145                usb_log_error("Failed to initialize default control pipe " \
     146                    "on device `%s': %s.\n",
     147                    dev->ddf_dev->name, str_error(rc));
     148                return rc;
     149        }
     150
     151        rc = usb_pipe_probe_default_control(&dev->ctrl_pipe);
     152        if (rc != EOK) {
     153                usb_log_error(
     154                    "Probing default control pipe on device `%s' failed: %s.\n",
     155                    dev->ddf_dev->name, str_error(rc));
     156                return rc;
     157        }
     158
     159        /* Get our interface. */
     160        dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
     161
     162        /*
     163         * We will do some querying of the device, it is worth to prepare
     164         * the long transfer.
     165         */
     166        rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe);
     167        if (rc != EOK) {
     168                usb_log_error("Failed to start transfer: %s.\n",
     169                    str_error(rc));
     170                return rc;
     171        }
     172
     173        /* Retrieve the descriptors. */
     174        rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,
     175            &dev->descriptors);
     176        if (rc != EOK) {
     177                usb_log_error("Failed to retrieve standard device " \
     178                    "descriptors of %s: %s.\n",
     179                    dev->ddf_dev->name, str_error(rc));
     180                return rc;
     181        }
     182
     183
     184        if (driver->endpoints != NULL) {
     185                rc = initialize_other_pipes(driver->endpoints, dev, 0);
     186        }
     187
     188        usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     189
     190        /* Rollback actions. */
     191        if (rc != EOK) {
     192                if (dev->descriptors.configuration != NULL) {
     193                        free(dev->descriptors.configuration);
     194                }
     195        }
     196
     197        return rc;
     198}
     199
     200/** Count number of alternate settings of a interface.
     201 *
     202 * @param config_descr Full configuration descriptor.
     203 * @param config_descr_size Size of @p config_descr in bytes.
     204 * @param interface_no Interface number.
     205 * @return Number of alternate interfaces for @p interface_no interface.
     206 */
     207size_t usb_interface_count_alternates(uint8_t *config_descr,
     208    size_t config_descr_size, uint8_t interface_no)
     209{
     210        assert(config_descr != NULL);
     211        assert(config_descr_size > 0);
     212
     213        usb_dp_parser_t dp_parser = {
     214                .nesting = usb_dp_standard_descriptor_nesting
     215        };
     216        usb_dp_parser_data_t dp_data = {
     217                .data = config_descr,
     218                .size = config_descr_size,
     219                .arg = NULL
     220        };
     221
     222        size_t alternate_count = 0;
     223
     224        uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
     225            &dp_data, config_descr);
     226        while (iface_ptr != NULL) {
     227                usb_standard_interface_descriptor_t *iface
     228                    = (usb_standard_interface_descriptor_t *) iface_ptr;
     229                if (iface->descriptor_type == USB_DESCTYPE_INTERFACE) {
     230                        if (iface->interface_number == interface_no) {
     231                                alternate_count++;
     232                        }
     233                }
     234                iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
     235                    config_descr, iface_ptr);
     236        }
     237
     238        return alternate_count;
     239}
     240
     241/** Initialize structures related to alternate interfaces.
     242 *
     243 * @param dev Device where alternate settings shall be initialized.
     244 * @return Error code.
     245 */
     246static int initialize_alternate_interfaces(usb_device_t *dev)
     247{
     248        if (dev->interface_no < 0) {
     249                dev->alternate_interfaces = NULL;
     250                return EOK;
     251        }
     252
     253        usb_alternate_interfaces_t *alternates
     254            = malloc(sizeof(usb_alternate_interfaces_t));
     255
     256        if (alternates == NULL) {
     257                return ENOMEM;
     258        }
     259
     260        alternates->alternative_count
     261            = usb_interface_count_alternates(dev->descriptors.configuration,
     262            dev->descriptors.configuration_size, dev->interface_no);
     263
     264        if (alternates->alternative_count == 0) {
     265                free(alternates);
     266                return ENOENT;
     267        }
     268
     269        alternates->alternatives = malloc(alternates->alternative_count
     270            * sizeof(usb_alternate_interface_descriptors_t));
     271        if (alternates->alternatives == NULL) {
     272                free(alternates);
     273                return ENOMEM;
     274        }
     275
     276        alternates->current = 0;
     277
     278        usb_dp_parser_t dp_parser = {
     279                .nesting = usb_dp_standard_descriptor_nesting
     280        };
     281        usb_dp_parser_data_t dp_data = {
     282                .data = dev->descriptors.configuration,
     283                .size = dev->descriptors.configuration_size,
     284                .arg = NULL
     285        };
     286
     287        usb_alternate_interface_descriptors_t *cur_alt_iface
     288            = &alternates->alternatives[0];
     289
     290        uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
     291            &dp_data, dp_data.data);
     292        while (iface_ptr != NULL) {
     293                usb_standard_interface_descriptor_t *iface
     294                    = (usb_standard_interface_descriptor_t *) iface_ptr;
     295                if ((iface->descriptor_type != USB_DESCTYPE_INTERFACE)
     296                    || (iface->interface_number != dev->interface_no)) {
     297                        iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser,
     298                            &dp_data,
     299                            dp_data.data, iface_ptr);
     300                        continue;
     301                }
     302
     303                cur_alt_iface->interface = iface;
     304                cur_alt_iface->nested_descriptors = iface_ptr + sizeof(*iface);
     305
     306                /* Find next interface to count size of nested descriptors. */
     307                iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
     308                    dp_data.data, iface_ptr);
     309                if (iface_ptr == NULL) {
     310                        uint8_t *next = dp_data.data + dp_data.size;
     311                        cur_alt_iface->nested_descriptors_size
     312                            = next - cur_alt_iface->nested_descriptors;
     313                } else {
     314                        cur_alt_iface->nested_descriptors_size
     315                            = iface_ptr - cur_alt_iface->nested_descriptors;
     316                }
     317
     318                cur_alt_iface++;
     319        }
     320
     321        dev->alternate_interfaces = alternates;
    122322
    123323        return EOK;
     
    139339        int rc;
    140340
    141         usb_device_t *dev = NULL;
    142         const char *err_msg = NULL;
    143         rc = usb_device_create(gen_dev, driver->endpoints, &dev, &err_msg);
    144         if (rc != EOK) {
    145                 usb_log_error("USB device `%s' creation failed (%s): %s.\n",
    146                     gen_dev->name, err_msg, str_error(rc));
    147                 return rc;
    148         }
     341        usb_device_t *dev = malloc(sizeof(usb_device_t));
     342        if (dev == NULL) {
     343                usb_log_error("Out of memory when adding device `%s'.\n",
     344                    gen_dev->name);
     345                return ENOMEM;
     346        }
     347
     348
     349        dev->ddf_dev = gen_dev;
     350        dev->ddf_dev->driver_data = dev;
     351        dev->driver_data = NULL;
     352        dev->descriptors.configuration = NULL;
     353
     354        dev->pipes_count = 0;
     355        dev->pipes = NULL;
     356
     357        rc = initialize_pipes(dev);
     358        if (rc != EOK) {
     359                free(dev);
     360                return rc;
     361        }
     362
     363        (void) initialize_alternate_interfaces(dev);
    149364
    150365        return driver->ops->add_device(dev);
     
    180395 * with usb_pipe_initialize_from_configuration().
    181396 *
    182  * @warning This is a wrapper function that does several operations that
    183  * can fail and that cannot be rollbacked easily. That means that a failure
    184  * during the SET_INTERFACE request would result in having a device with
    185  * no pipes at all (except the default control one). That is because the old
    186  * pipes needs to be unregistered at HC first and the new ones could not
    187  * be created.
    188  *
    189397 * @param dev USB device.
    190398 * @param alternate_setting Alternate setting to choose.
     
    201409        int rc;
    202410
     411        /* TODO: more transactional behavior. */
     412
    203413        /* Destroy existing pipes. */
    204414        rc = destroy_current_pipes(dev);
     
    222432/** Retrieve basic descriptors from the device.
    223433 *
    224  * @param[in] ctrl_pipe Control endpoint pipe.
     434 * @param[in] ctrl_pipe Control pipe with opened session.
    225435 * @param[out] descriptors Where to store the descriptors.
    226436 * @return Error code.
     
    230440{
    231441        assert(descriptors != NULL);
     442        assert(usb_pipe_is_session_started(ctrl_pipe));
    232443
    233444        descriptors->configuration = NULL;
    234445
    235446        int rc;
    236 
    237         /* It is worth to start a long transfer. */
    238         rc = usb_pipe_start_long_transfer(ctrl_pipe);
    239         if (rc != EOK) {
    240                 return rc;
    241         }
    242447
    243448        /* Get the device descriptor. */
    244449        rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
    245450        if (rc != EOK) {
    246                 goto leave;
     451                return rc;
    247452        }
    248453
     
    251456            ctrl_pipe, 0, (void **) &descriptors->configuration,
    252457            &descriptors->configuration_size);
    253 
    254 leave:
    255         usb_pipe_end_long_transfer(ctrl_pipe);
    256 
    257         return rc;
     458        if (rc != EOK) {
     459                return rc;
     460        }
     461
     462        return EOK;
    258463}
    259464
     
    436641}
    437642
    438 /** Initialize control pipe in a device.
    439  *
    440  * @param dev USB device in question.
    441  * @param errmsg Where to store error context.
    442  * @return
    443  */
    444 static int init_wire_and_ctrl_pipe(usb_device_t *dev, const char **errmsg)
    445 {
    446         int rc;
    447 
    448         rc = usb_device_connection_initialize_from_device(&dev->wire,
    449             dev->ddf_dev);
    450         if (rc != EOK) {
    451                 *errmsg = "device connection initialization";
    452                 return rc;
    453         }
    454 
    455         rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,
    456             &dev->wire);
    457         if (rc != EOK) {
    458                 *errmsg = "default control pipe initialization";
    459                 return rc;
    460         }
    461 
    462         return EOK;
    463 }
    464 
    465 
    466 /** Create new instance of USB device.
    467  *
    468  * @param[in] ddf_dev Generic DDF device backing the USB one.
    469  * @param[in] endpoints NULL terminated array of endpoints (NULL for none).
    470  * @param[out] dev_ptr Where to store pointer to the new device.
    471  * @param[out] errstr_ptr Where to store description of context
    472  *      (in case error occurs).
    473  * @return Error code.
    474  */
    475 int usb_device_create(ddf_dev_t *ddf_dev,
    476     usb_endpoint_description_t **endpoints,
    477     usb_device_t **dev_ptr, const char **errstr_ptr)
    478 {
    479         assert(dev_ptr != NULL);
    480         assert(ddf_dev != NULL);
    481 
    482         int rc;
    483 
    484         usb_device_t *dev = malloc(sizeof(usb_device_t));
    485         if (dev == NULL) {
    486                 *errstr_ptr = "structure allocation";
    487                 return ENOMEM;
    488         }
    489 
    490         // FIXME: proper deallocation in case of errors
    491 
    492         dev->ddf_dev = ddf_dev;
    493         dev->driver_data = NULL;
    494         dev->descriptors.configuration = NULL;
    495         dev->alternate_interfaces = NULL;
    496 
    497         dev->pipes_count = 0;
    498         dev->pipes = NULL;
    499 
    500         /* Initialize backing wire and control pipe. */
    501         rc = init_wire_and_ctrl_pipe(dev, errstr_ptr);
    502         if (rc != EOK) {
    503                 return rc;
    504         }
    505 
    506         /* Get our interface. */
    507         dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
    508 
    509         /* Retrieve standard descriptors. */
    510         rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,
    511             &dev->descriptors);
    512         if (rc != EOK) {
    513                 *errstr_ptr = "descriptor retrieval";
    514                 return rc;
    515         }
    516 
    517         /* Create alternate interfaces. */
    518         rc = usb_alternate_interfaces_create(dev->descriptors.configuration,
    519             dev->descriptors.configuration_size, dev->interface_no,
    520             &dev->alternate_interfaces);
    521         if (rc != EOK) {
    522                 /* We will try to silently ignore this. */
    523                 dev->alternate_interfaces = NULL;
    524         }
    525 
    526         rc = initialize_other_pipes(endpoints, dev, 0);
    527         if (rc != EOK) {
    528                 *errstr_ptr = "pipes initialization";
    529                 return rc;
    530         }
    531 
    532         *errstr_ptr = NULL;
    533         *dev_ptr = dev;
    534 
    535         return EOK;
    536 }
    537 
    538643/**
    539644 * @}
  • uspace/lib/usb/src/hidparser.c

    r3f3afb9 r58226b4  
    900900        item->usage_page = usage_page;
    901901       
    902         usb_log_debug("Appending usage %d, usage page %d\n", usage, usage_page);
    903        
    904902        list_append (&usage_path->link, &item->link);
    905903        usage_path->depth++;
  • uspace/lib/usb/src/host/device_keeper.c

    r3f3afb9 r58226b4  
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
     56                instance->devices[i].control_used = 0;
    5657                instance->devices[i].handle = 0;
    5758                instance->devices[i].speed = USB_SPEED_MAX;
     59                list_initialize(&instance->devices[i].endpoints);
    5860        }
    5961        // TODO: is this hack enough?
     
    6264}
    6365/*----------------------------------------------------------------------------*/
     66void usb_device_keeper_add_ep(
     67    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)
     68{
     69        assert(instance);
     70        fibril_mutex_lock(&instance->guard);
     71        assert(instance->devices[address].occupied);
     72        list_append(&ep->same_device_eps, &instance->devices[address].endpoints);
     73        fibril_mutex_unlock(&instance->guard);
     74}
     75/*----------------------------------------------------------------------------*/
     76void usb_device_keeper_del_ep(
     77    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)
     78{
     79        assert(instance);
     80        fibril_mutex_lock(&instance->guard);
     81        assert(instance->devices[address].occupied);
     82        list_remove(&ep->same_device_eps);
     83        list_initialize(&ep->same_device_eps);
     84        fibril_mutex_unlock(&instance->guard);
     85}
     86/*----------------------------------------------------------------------------*/
    6487/** Attempt to obtain address 0, blocks.
    6588 *
     
    94117}
    95118/*----------------------------------------------------------------------------*/
     119/** Check setup packet data for signs of toggle reset.
     120 *
     121 * @param[in] instance Device keeper structure to use.
     122 * @param[in] target Device to receive setup packet.
     123 * @param[in] data Setup packet data.
     124 *
     125 * Really ugly one.
     126 */
     127void usb_device_keeper_reset_if_need(
     128    usb_device_keeper_t *instance, usb_target_t target, const uint8_t *data)
     129{
     130        assert(instance);
     131        fibril_mutex_lock(&instance->guard);
     132        if (target.endpoint > 15 || target.endpoint < 0
     133            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     134            || !instance->devices[target.address].occupied) {
     135                fibril_mutex_unlock(&instance->guard);
     136                usb_log_error("Invalid data when checking for toggle reset.\n");
     137                return;
     138        }
     139
     140        switch (data[1])
     141        {
     142        case 0x01: /*clear feature*/
     143                /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
     144                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     145                        link_t *current =
     146                            instance->devices[target.address].endpoints.next;
     147                        while (current !=
     148                           &instance->devices[target.address].endpoints)
     149                        {
     150                        /* endpoint number is < 16, thus first byte is enough */
     151                                endpoint_toggle_reset_filtered(
     152                                    current, data[4]);
     153                                current = current->next;
     154                        }
     155                }
     156        break;
     157
     158        case 0x9: /* set configuration */
     159        case 0x11: /* set interface */
     160                /* target must be device */
     161                if ((data[0] & 0xf) == 0) {
     162                        link_t *current =
     163                            instance->devices[target.address].endpoints.next;
     164                        while (current !=
     165                           &instance->devices[target.address].endpoints)
     166                        {
     167                                endpoint_toggle_reset(current);
     168                                current = current->next;
     169                        }
     170                }
     171        break;
     172        }
     173        fibril_mutex_unlock(&instance->guard);
     174}
    96175/*----------------------------------------------------------------------------*/
    97176/** Get a free USB address
  • uspace/lib/usb/src/host/endpoint.c

    r3f3afb9 r58226b4  
    5353        fibril_mutex_initialize(&instance->guard);
    5454        fibril_condvar_initialize(&instance->avail);
     55        link_initialize(&instance->same_device_eps);
    5556        return EOK;
    5657}
     
    6061        assert(instance);
    6162        assert(!instance->active);
     63        list_remove(&instance->same_device_eps);
    6264        free(instance);
    6365}
     
    9597}
    9698/*----------------------------------------------------------------------------*/
    97 void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target)
     99void endpoint_toggle_reset(link_t *ep)
    98100{
     101        endpoint_t *instance =
     102            list_get_instance(ep, endpoint_t, same_device_eps);
    99103        assert(instance);
    100         if (instance->address == target.address &&
    101             (instance->endpoint == target.endpoint || target.endpoint == 0))
     104        instance->toggle = 0;
     105}
     106/*----------------------------------------------------------------------------*/
     107void endpoint_toggle_reset_filtered(link_t *ep, usb_endpoint_t epn)
     108{
     109        endpoint_t *instance =
     110            list_get_instance(ep, endpoint_t, same_device_eps);
     111        assert(instance);
     112        if (instance->endpoint == epn)
    102113                instance->toggle = 0;
    103114}
  • uspace/lib/usb/src/host/usb_endpoint_manager.c

    r3f3afb9 r58226b4  
    3131#include <errno.h>
    3232
    33 #include <usb/debug.h>
    3433#include <usb/host/usb_endpoint_manager.h>
    3534
     
    8180        endpoint_destroy(node->ep);
    8281        free(node);
    83 }
    84 /*----------------------------------------------------------------------------*/
    85 static void node_toggle_reset_filtered(link_t *item, void *arg)
    86 {
    87         assert(item);
    88         node_t *node = hash_table_get_instance(item, node_t, link);
    89         usb_target_t *target = arg;
    90         endpoint_toggle_reset_filtered(node->ep, *target);
    9182}
    9283/*----------------------------------------------------------------------------*/
     
    239230        return node->ep;
    240231}
    241 /*----------------------------------------------------------------------------*/
    242 /** Check setup packet data for signs of toggle reset.
    243  *
    244  * @param[in] instance Device keeper structure to use.
    245  * @param[in] target Device to receive setup packet.
    246  * @param[in] data Setup packet data.
    247  *
    248  * Really ugly one.
    249  */
    250 void usb_endpoint_manager_reset_if_need(
    251     usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data)
    252 {
    253         assert(instance);
    254         if (target.endpoint > 15 || target.endpoint < 0
    255             || target.address >= USB11_ADDRESS_MAX || target.address < 0) {
    256                 usb_log_error("Invalid data when checking for toggle reset.\n");
    257                 return;
    258         }
    259 
    260         switch (data[1])
    261         {
    262         case 0x01: /*clear feature*/
    263                 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
    264                 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
    265                         /* endpoint number is < 16, thus first byte is enough */
    266                         usb_target_t reset_target =
    267                             { .address = target.address, data[4] };
    268                         fibril_mutex_lock(&instance->guard);
    269                         hash_table_apply(&instance->ep_table,
    270                             node_toggle_reset_filtered, &reset_target);
    271                         fibril_mutex_unlock(&instance->guard);
    272                 }
    273         break;
    274 
    275         case 0x9: /* set configuration */
    276         case 0x11: /* set interface */
    277                 /* target must be device */
    278                 if ((data[0] & 0xf) == 0) {
    279                         usb_target_t reset_target =
    280                             { .address = target.address, 0 };
    281                         fibril_mutex_lock(&instance->guard);
    282                         hash_table_apply(&instance->ep_table,
    283                             node_toggle_reset_filtered, &reset_target);
    284                         fibril_mutex_unlock(&instance->guard);
    285                 }
    286         break;
    287         }
    288 }
  • uspace/lib/usb/src/hub.c

    r3f3afb9 r58226b4  
    4242#include <usb/debug.h>
    4343
    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))
    48 
    4944/** Check that HC connection is alright.
    5045 *
     
    5853                } \
    5954        } while (false)
     55
     56
     57/** Tell host controller to reserve default address.
     58 * @deprecated
     59 *
     60 * @param connection Opened connection to host controller.
     61 * @param speed Speed of the device that will respond on the default address.
     62 * @return Error code.
     63 */
     64int usb_hc_reserve_default_address(usb_hc_connection_t *connection,
     65    usb_speed_t speed)
     66{
     67        CHECK_CONNECTION(connection);
     68
     69        usb_log_warning("usb_hc_reserve_default_address() considered obsolete");
     70
     71        return async_req_2_0(connection->hc_phone,
     72            DEV_IFACE_ID(USBHC_DEV_IFACE),
     73            IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed);
     74}
     75
     76/** Tell host controller to release default address.
     77 * @deprecated
     78 *
     79 * @param connection Opened connection to host controller.
     80 * @return Error code.
     81 */
     82int usb_hc_release_default_address(usb_hc_connection_t *connection)
     83{
     84        CHECK_CONNECTION(connection);
     85
     86        usb_log_warning("usb_hc_release_default_address() considered obsolete");
     87
     88        return async_req_1_0(connection->hc_phone,
     89            DEV_IFACE_ID(USBHC_DEV_IFACE),
     90            IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
     91}
    6092
    6193/** Ask host controller for free address assignment.
     
    237269                if (rc != EOK) {
    238270                        /* Do not overheat the CPU ;-). */
    239                         async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);
     271                        async_usleep(10);
    240272                }
    241273        } while (rc != EOK);
  • uspace/lib/usb/src/request.c

    r3f3afb9 r58226b4  
    871871}
    872872
    873 /** Clear halt bit of an endpoint pipe (after pipe stall).
    874  *
    875  * @param pipe Control pipe.
    876  * @param ep_index Endpoint index (in native endianness).
    877  * @return Error code.
    878  */
    879 int usb_request_clear_endpoint_halt(usb_pipe_t *pipe, uint16_t ep_index)
    880 {
    881         return usb_request_clear_feature(pipe,
    882             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,
    883             uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),
    884             uint16_host2usb(ep_index));
    885 }
    886 
    887873/**
    888874 * @}
Note: See TracChangeset for help on using the changeset viewer.