Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset f11c288 in mainline


Ignore:
Timestamp:
2011-04-09T22:20:02Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial
Children:
0748854, d32ed36
Parents:
709e868 (diff), a19a2d7 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Fix crash on endpoint_t instance removal

Remove unused default address handling (support in device_keeper_t will be removed later)
Add tons of OHCI debug output (still not working), and some fixes found by using that debug output.

Location:
uspace
Files:
14 edited

Legend:

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

    r709e868 rf11c288  
    227227        ed_init(data->ed, instance->ep);
    228228        ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]);
    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);
     229        usb_log_debug("Created ED(%p): %x:%x:%x:%x.\n", data->ed,
     230            data->ed->status, data->ed->td_tail, data->ed->td_head,
     231            data->ed->next);
    231232        int toggle = 0;
    232233        /* setup stage */
  • uspace/drv/ohci/hc.c

    r709e868 rf11c288  
    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
     116        rh_init(&instance->rh, dev, instance->registers);
     117
    110118        if (!interrupts) {
    111119                instance->interrupt_emulator =
     
    114122        }
    115123
    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 */
    124124        return EOK;
    125125}
     
    140140        switch (batch->transfer_type) {
    141141        case USB_TRANSFER_CONTROL:
     142                instance->registers->control &= ~C_CLE;
    142143                instance->registers->command_status |= CS_CLF;
     144                usb_log_debug2("Set control transfer filled: %x.\n",
     145                        instance->registers->command_status);
     146                instance->registers->control |= C_CLE;
    143147                break;
    144148        case USB_TRANSFER_BULK:
    145149                instance->registers->command_status |= CS_BLF;
     150                usb_log_debug2("Set bulk transfer filled: %x.\n",
     151                        instance->registers->command_status);
    146152                break;
    147153        default:
     
    154160{
    155161        assert(instance);
    156         if (status == 0)
     162        if ((status & ~IS_SF) == 0) /* ignore sof status */
    157163                return;
    158164        if (status & IS_RHSC)
     
    160166
    161167        usb_log_info("OHCI interrupt: %x.\n", status);
     168
    162169
    163170        LIST_INITIALIZE(done);
     
    192199{
    193200        assert(instance);
     201        /* Turn off legacy emulation */
     202        volatile uint32_t *ohci_emulation_reg =
     203            (uint32_t*)((char*)instance->registers + 0x100);
     204        usb_log_debug("OHCI legacy register %p: %x.\n",
     205                ohci_emulation_reg, *ohci_emulation_reg);
     206        *ohci_emulation_reg = 0;
     207
    194208        /* Interrupt routing enabled => smm driver is active */
    195209        if (instance->registers->control & C_IR) {
    196                 usb_log_info("Found SMM driver requesting ownership change.\n");
     210                usb_log_debug("SMM driver: request ownership change.\n");
    197211                instance->registers->command_status |= CS_OCR;
    198212                while (instance->registers->control & C_IR) {
    199213                        async_usleep(1000);
    200214                }
    201                 usb_log_info("Ownership taken from SMM driver.\n");
     215                usb_log_info("SMM driver: Ownership taken.\n");
    202216                return;
    203217        }
     
    207221        /* Interrupt routing disabled && status != USB_RESET => BIOS active */
    208222        if (hc_status != C_HCFS_RESET) {
    209                 usb_log_info("Found BIOS driver.\n");
     223                usb_log_debug("BIOS driver found.\n");
    210224                if (hc_status == C_HCFS_OPERATIONAL) {
    211                         usb_log_info("HC operational(BIOS).\n");
     225                        usb_log_info("BIOS driver: HC operational.\n");
    212226                        return;
    213227                }
     
    215229                instance->registers->control &= (C_HCFS_RESUME << C_HCFS_SHIFT);
    216230                async_usleep(20000);
     231                usb_log_info("BIOS driver: HC resumed.\n");
    217232                return;
    218233        }
     
    220235        /* HC is in reset (hw startup) => no other driver
    221236         * maintain reset for at least the time specified in USB spec (50 ms)*/
     237        usb_log_info("HC found in reset.\n");
    222238        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 
    231239}
    232240/*----------------------------------------------------------------------------*/
    233241void hc_init_hw(hc_t *instance)
    234242{
    235         assert(instance);
     243        /* OHCI guide page 42 */
     244        assert(instance);
     245        usb_log_debug2("Started hc initialization routine.\n");
     246
     247        /* Save contents of fm_interval register */
    236248        const uint32_t fm_interval = instance->registers->fm_interval;
    237 
    238         /* reset hc */
     249        usb_log_debug2("Old value of HcFmInterval: %x.\n", fm_interval);
     250
     251        /* Reset hc */
     252        usb_log_debug2("HC reset.\n");
     253        size_t time = 0;
    239254        instance->registers->command_status = CS_HCR;
    240         async_usleep(10);
    241 
    242         /* restore fm_interval */
     255        while (instance->registers->command_status & CS_HCR) {
     256                async_usleep(10);
     257                time += 10;
     258        }
     259        usb_log_debug2("HC reset complete in %zu us.\n", time);
     260
     261        /* Restore fm_interval */
    243262        instance->registers->fm_interval = fm_interval;
    244263        assert((instance->registers->command_status & CS_HCR) == 0);
    245264
    246265        /* hc is now in suspend state */
    247 
    248         /* enable queues */
     266        usb_log_debug2("HC should be in suspend state(%x).\n",
     267            instance->registers->control);
     268
     269        /* Enable queues */
    249270        instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);
    250         /* TODO: enable interrupts */
    251         /* set periodic start to 90% */
    252         instance->registers->periodic_start = (fm_interval / 10) * 9;
     271        usb_log_debug2("All queues enabled(%x).\n",
     272            instance->registers->control);
     273
     274        /* Disable interrupts */
     275        instance->registers->interrupt_disable = I_SF | I_OC;
     276        usb_log_debug2("Disabling interrupts: %x.\n",
     277            instance->registers->interrupt_disable);
     278        instance->registers->interrupt_disable = I_MI;
     279        usb_log_debug2("Enabled interrupts: %x.\n",
     280            instance->registers->interrupt_enable);
     281
     282        /* Set periodic start to 90% */
     283        uint32_t frame_length = ((fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK);
     284        instance->registers->periodic_start = (frame_length / 10) * 9;
     285        usb_log_debug2("All periodic start set to: %x(%u - 90%% of %d).\n",
     286            instance->registers->periodic_start,
     287            instance->registers->periodic_start, frame_length);
    253288
    254289        instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);
    255         usb_log_info("OHCI HC up and running.\n");
     290        usb_log_info("OHCI HC up and running(%x).\n",
     291            instance->registers->control);
    256292}
    257293/*----------------------------------------------------------------------------*/
     
    298334{
    299335        assert(instance);
    300         /* init queues */
     336        /* Init queues */
    301337        hc_init_transfer_lists(instance);
    302338
    303         /* init HCCA */
     339        /*Init HCCA */
    304340        instance->hcca = malloc32(sizeof(hcca_t));
    305341        if (instance->hcca == NULL)
     
    307343        bzero(instance->hcca, sizeof(hcca_t));
    308344        instance->registers->hcca = addr_to_phys(instance->hcca);
    309 
    310         /* use queues */
     345        usb_log_debug2("OHCI HCCA initialized at %p(%p).\n",
     346            instance->hcca, instance->registers->hcca);
     347
     348        /* Use queues */
    311349        instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;
     350        usb_log_debug2("Bulk HEAD set to: %p(%p).\n",
     351            instance->transfers_bulk.list_head,
     352            instance->transfers_bulk.list_head_pa);
     353
    312354        instance->registers->control_head =
    313355            instance->transfers_control.list_head_pa;
     356        usb_log_debug2("Control HEAD set to: %p(%p).\n",
     357            instance->transfers_control.list_head,
     358            instance->transfers_control.list_head_pa);
    314359
    315360        unsigned i = 0;
     
    318363                    instance->transfers_interrupt.list_head_pa;
    319364        }
     365        usb_log_debug2("Interrupt HEADs set to: %p(%p).\n",
     366            instance->transfers_interrupt.list_head,
     367            instance->transfers_interrupt.list_head_pa);
    320368
    321369        return EOK;
  • uspace/drv/ohci/hw_struct/endpoint_descriptor.c

    r709e868 rf11c288  
    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        }
     
    5757        if (ep->transfer_type == USB_TRANSFER_ISOCHRONOUS)
    5858                instance->status |= ED_STATUS_F_FLAG;
    59 
    6059}
    61 
    6260/**
    6361 * @}
  • uspace/drv/ohci/iface.c

    r709e868 rf11c288  
    7474            name, target.address, target.endpoint, size, ep->max_packet_size);
    7575
    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)
     76        *batch = batch_get(
     77            fun, ep, data, size, setup_data, setup_size, in, out, arg);
     78        if (!*batch)
    8579                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  */
    96 static 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;
    111 try_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  */
    130 static 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);
    13980        return EOK;
    14081}
     
    245186        if (ret != EOK) {
    246187                endpoint_destroy(ep);
    247         } else {
    248                 usb_device_keeper_add_ep(&hc->manager, address, ep);
    249188        }
    250189        return ret;
     
    259198        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    260199            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         }
    266200        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    267201            endpoint, direction);
     
    435369        if (ret != EOK)
    436370                return ret;
    437         usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
     371        usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);
    438372        batch_control_write(batch);
    439373        ret = hc_schedule(hc, batch);
     
    484418/*----------------------------------------------------------------------------*/
    485419usbhc_iface_t hc_iface = {
    486         .reserve_default_address = reserve_default_address,
    487         .release_default_address = release_default_address,
    488420        .request_address = request_address,
    489421        .bind_address = bind_address,
  • uspace/drv/ohci/ohci_regs.h

    r709e868 rf11c288  
    8484        /** Interupt enable/disable, reads give the same value, writing causes
    8585         * enable/disable */
    86         volatile uint32_t interupt_enable;
     86        volatile uint32_t interrupt_enable;
    8787        volatile uint32_t interrupt_disable;
    8888#define I_SO   (1 << 0)   /* Scheduling overrun */
     
    120120        /** Frame time and max packet size for all transfers */
    121121        volatile uint32_t fm_interval;
    122 #define FMI_FI_MASK (0x1fff) /* Frame interval in bit times (should be 11999)*/
     122#define FMI_FI_MASK (0x3fff) /* 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 (0x1fff) /* bit time when periodic get priority (0x3e67) */
     140#define PS_PS_MASK (0x3fff) /* bit time when periodic get priority (0x3e67) */
    141141
    142142        /** Threshold for starting LS transaction */
  • uspace/drv/ohci/root_hub.c

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

    r709e868 rf11c288  
    122122        usb_transfer_batch_t *first = list_get_instance(
    123123            instance->batch_list.next, usb_transfer_batch_t, link);
    124         usb_log_debug("Batch(%p) added to queue %s, first is %p.\n",
    125                 batch, instance->name, first);
     124        usb_log_debug("Batch(%p) added to list %s, first is %p(%p).\n",
     125                batch, instance->name, first, batch_ed(first));
     126        if (last_ed == instance->list_head) {
     127                usb_log_debug2("%s head ED: %x:%x:%x:%x.\n", instance->name,
     128                        last_ed->status, last_ed->td_tail, last_ed->td_head,
     129                        last_ed->next);
     130        }
    126131        fibril_mutex_unlock(&instance->guard);
    127132}
  • uspace/drv/uhci-hcd/iface.c

    r709e868 rf11c288  
    7474            name, target.address, target.endpoint, size, ep->max_packet_size);
    7575
    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)
     76        *batch = batch_get(
     77                fun, ep, data, size, setup_data, setup_size, in, out, arg);
     78        if (!*batch)
    8579                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  */
    96 static 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;
    111 try_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  */
    130 static 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);
    13980        return EOK;
    14081}
     
    232173        if (ret != EOK) {
    233174                endpoint_destroy(ep);
    234         } else {
    235                 usb_device_keeper_add_ep(&hc->manager, address, ep);
    236175        }
    237176        return ret;
     
    246185        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    247186            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         }
    253187        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    254188            endpoint, direction);
     
    391325        if (ret != EOK)
    392326                return ret;
    393         usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
     327        usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);
    394328        batch_control_write(batch);
    395329        ret = hc_schedule(hc, batch);
     
    433367/*----------------------------------------------------------------------------*/
    434368usbhc_iface_t hc_iface = {
    435         .reserve_default_address = reserve_default_address,
    436         .release_default_address = release_default_address,
    437369        .request_address = request_address,
    438370        .bind_address = bind_address,
  • uspace/lib/usb/include/usb/host/device_keeper.h

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

    r709e868 rf11c288  
    5454        fibril_condvar_t avail;
    5555        volatile bool active;
    56         link_t same_device_eps;
    5756} endpoint_t;
    5857
     
    7170void endpoint_toggle_set(endpoint_t *instance, int toggle);
    7271
    73 void endpoint_toggle_reset(link_t *ep);
    74 
    75 void endpoint_toggle_reset_filtered(link_t *ep, usb_endpoint_t epn);
    76 
     72void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target);
    7773#endif
    7874/**
  • uspace/lib/usb/include/usb/host/usb_endpoint_manager.h

    r709e868 rf11c288  
    7878    size_t *bw);
    7979
     80void usb_endpoint_manager_reset_if_need(
     81    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
    8082#endif
    8183/**
  • uspace/lib/usb/src/host/device_keeper.c

    r709e868 rf11c288  
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
    56                 instance->devices[i].control_used = 0;
    5756                instance->devices[i].handle = 0;
    5857                instance->devices[i].speed = USB_SPEED_MAX;
    59                 list_initialize(&instance->devices[i].endpoints);
    6058        }
    6159        // TODO: is this hack enough?
    6260        // (it is needed to allow smooth registration at default address)
    6361        instance->devices[0].occupied = true;
    64 }
    65 /*----------------------------------------------------------------------------*/
    66 void 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 /*----------------------------------------------------------------------------*/
    76 void 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);
    8562}
    8663/*----------------------------------------------------------------------------*/
     
    11794}
    11895/*----------------------------------------------------------------------------*/
    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  */
    127 void 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 }
    17596/*----------------------------------------------------------------------------*/
    17697/** Get a free USB address
  • uspace/lib/usb/src/host/endpoint.c

    r709e868 rf11c288  
    5353        fibril_mutex_initialize(&instance->guard);
    5454        fibril_condvar_initialize(&instance->avail);
    55         link_initialize(&instance->same_device_eps);
    5655        return EOK;
    5756}
     
    6160        assert(instance);
    6261        assert(!instance->active);
    63         list_remove(&instance->same_device_eps);
    6462        free(instance);
    6563}
     
    9795}
    9896/*----------------------------------------------------------------------------*/
    99 void endpoint_toggle_reset(link_t *ep)
     97void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target)
    10098{
    101         endpoint_t *instance =
    102             list_get_instance(ep, endpoint_t, same_device_eps);
    10399        assert(instance);
    104         instance->toggle = 0;
    105 }
    106 /*----------------------------------------------------------------------------*/
    107 void 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)
     100        if (instance->address == target.address &&
     101            instance->endpoint == target.endpoint)
    113102                instance->toggle = 0;
    114103}
  • uspace/lib/usb/src/host/usb_endpoint_manager.c

    r709e868 rf11c288  
    3131#include <errno.h>
    3232
     33#include <usb/debug.h>
    3334#include <usb/host/usb_endpoint_manager.h>
    3435
     
    8081        endpoint_destroy(node->ep);
    8182        free(node);
     83}
     84/*----------------------------------------------------------------------------*/
     85static 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);
    8291}
    8392/*----------------------------------------------------------------------------*/
     
    230239        return node->ep;
    231240}
     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 */
     250void 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}
Note: See TracChangeset for help on using the changeset viewer.