Changeset c6f82e5 in mainline


Ignore:
Timestamp:
2018-01-19T20:56:14Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7ec7b7e
Parents:
69b2dfee
Message:

libusbhost: do not try to handle the toggle bit in a generic way

Location:
uspace
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/ehci_bus.c

    r69b2dfee rc6f82e5  
    4343#include "hc.h"
    4444
    45 /** Callback to set toggle on ED.
     45/**
     46 * Callback to set toggle on ED.
    4647 *
    4748 * @param[in] hcd_ep hcd endpoint structure
    4849 * @param[in] toggle new value of toggle bit
    4950 */
    50 static void ehci_ep_toggle_reset(endpoint_t *ep)
     51void ehci_ep_toggle_reset(endpoint_t *ep)
    5152{
    5253        ehci_endpoint_t *instance = ehci_endpoint_get(ep);
     
    5455                usb_log_warning("EP(%p): Resetting toggle bit for transfer directed EP", instance);
    5556        qh_toggle_set(instance->qh, 0);
    56         ep->toggle = 0;
    5757}
    5858
     
    169169        .interrupt = ehci_hc_interrupt,
    170170        .status = ehci_hc_status,
     171
    171172        .endpoint_destroy = ehci_endpoint_destroy,
    172173        .endpoint_create = ehci_endpoint_create,
    173174        .endpoint_register = ehci_register_ep,
    174175        .endpoint_unregister = ehci_unregister_ep,
    175         .endpoint_toggle_reset = ehci_ep_toggle_reset,
    176176        .endpoint_count_bw = bandwidth_count_usb20,
     177
    177178        .batch_create = ehci_create_batch,
    178179        .batch_destroy = ehci_destroy_batch,
  • uspace/drv/bus/usb/ehci/ehci_bus.h

    r69b2dfee rc6f82e5  
    6868} ehci_bus_t;
    6969
     70void ehci_ep_toggle_reset(endpoint_t *);
    7071void ehci_bus_prepare_ops(void);
    7172
  • uspace/drv/bus/usb/ehci/hc.c

    r69b2dfee rc6f82e5  
    4545#include <usb/debug.h>
    4646#include <usb/usb.h>
     47#include <usb/host/utility.h>
    4748
    4849#include "ehci_batch.h"
     
    379380                                list_remove(current);
    380381                                endpoint_del_ref(&ep->base);
     382                                hc_reset_toggles(&batch->base, &ehci_ep_toggle_reset);
    381383                                usb_transfer_batch_finish(&batch->base);
    382384                        }
  • uspace/drv/bus/usb/ohci/hc.c

    r69b2dfee rc6f82e5  
    4545
    4646#include <usb/debug.h>
     47#include <usb/host/utility.h>
    4748#include <usb/usb.h>
    4849
     
    377378                                list_remove(current);
    378379                                endpoint_del_ref(&ep->base);
     380                                hc_reset_toggles(&batch->base, &ohci_ep_toggle_reset);
    379381                                usb_transfer_batch_finish(&batch->base);
    380382                        }
  • uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c

    r69b2dfee rc6f82e5  
    100100        OHCI_MEM32_WR(instance->td_head, pa & ED_TDHEAD_PTR_MASK);
    101101        OHCI_MEM32_WR(instance->td_tail, pa & ED_TDTAIL_PTR_MASK);
    102 
    103         /* Set toggle bit */
    104         if (ep->toggle)
    105                 OHCI_MEM32_SET(instance->td_head, ED_TDHEAD_TOGGLE_CARRY);
    106 
    107102}
    108103/**
  • uspace/drv/bus/usb/ohci/ohci_bus.c

    r69b2dfee rc6f82e5  
    4343#include "hc.h"
    4444
    45 /** Callback to reset toggle on ED.
     45/**
     46 * Callback to reset toggle on ED.
    4647 *
    4748 * @param[in] hcd_ep hcd endpoint structure
    4849 * @param[in] toggle new value of toggle bit
    4950 */
    50 static void ohci_ep_toggle_reset(endpoint_t *ep)
     51void ohci_ep_toggle_reset(endpoint_t *ep)
    5152{
    5253        ohci_endpoint_t *instance = ohci_endpoint_get(ep);
    5354        assert(instance);
    5455        assert(instance->ed);
    55         ep->toggle = 0;
    5656        ed_toggle_set(instance->ed, 0);
    5757}
     
    179179        .endpoint_unregister = ohci_unregister_ep,
    180180        .endpoint_count_bw = bandwidth_count_usb11,
    181         .endpoint_toggle_reset = ohci_ep_toggle_reset,
     181
    182182        .batch_create = ohci_create_batch,
    183183        .batch_destroy = ohci_destroy_batch,
  • uspace/drv/bus/usb/ohci/ohci_bus.h

    r69b2dfee rc6f82e5  
    6565
    6666int ohci_bus_init(ohci_bus_t *, hc_t *);
     67void ohci_ep_toggle_reset(endpoint_t *);
    6768
    6869/** Get and convert assigned ohci_endpoint_t structure
  • uspace/drv/bus/usb/uhci/hc.h

    r69b2dfee rc6f82e5  
    127127} hc_t;
    128128
     129typedef struct uhci_endpoint {
     130        endpoint_t base;
     131
     132        bool toggle;
     133} uhci_endpoint_t;
     134
    129135static inline hc_t *hcd_to_hc(hc_device_t *hcd)
    130136{
  • uspace/drv/bus/usb/uhci/transfer_list.c

    r69b2dfee rc6f82e5  
    4141#include <usb/host/usb_transfer_batch.h>
    4242#include <usb/host/utils/malloc32.h>
     43#include <usb/host/utility.h>
    4344
    4445#include "hw_struct/link_pointer.h"
    4546#include "transfer_list.h"
     47#include "hc.h"
    4648
    4749/** Initialize transfer list structures.
     
    155157}
    156158
     159/**
     160 * Reset toggle on endpoint callback.
     161 */
     162static void uhci_reset_toggle(endpoint_t *ep)
     163{
     164        uhci_endpoint_t *uhci_ep = (uhci_endpoint_t *) ep;
     165        uhci_ep->toggle = 0;
     166}
     167
    157168/** Add completed batches to the provided list.
    158169 *
     
    176187                        fibril_mutex_lock(&batch->base.ep->guard);
    177188                        assert(batch->base.ep->active_batch == &batch->base);
     189                        hc_reset_toggles(&batch->base, &uhci_reset_toggle);
    178190                        endpoint_deactivate_locked(batch->base.ep);
    179191                        transfer_list_remove_batch(instance, batch);
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r69b2dfee rc6f82e5  
    4646
    4747#include "uhci_batch.h"
     48#include "hc.h"
    4849#include "hw_struct/transfer_descriptor.h"
    4950
     
    164165        batch->transfered_size = 0;
    165166
     167        uhci_endpoint_t *uhci_ep = (uhci_endpoint_t *) batch->ep;
     168
    166169        for (size_t i = 0;i < uhci_batch->td_count; ++i) {
    167170                if (td_is_active(&uhci_batch->tds[i])) {
     
    178181                        td_print_status(&uhci_batch->tds[i]);
    179182
    180                         batch->ep->toggle = td_toggle(&uhci_batch->tds[i]);
     183                        uhci_ep->toggle = td_toggle(&uhci_batch->tds[i]);
    181184                        goto substract_ret;
    182185                }
     
    230233        const size_t mps = uhci_batch->base.ep->max_packet_size;
    231234
    232         int toggle = uhci_batch->base.ep->toggle;
     235        uhci_endpoint_t *uhci_ep = (uhci_endpoint_t *) uhci_batch->base.ep;
     236
     237        int toggle = uhci_ep->toggle;
    233238        assert(toggle == 0 || toggle == 1);
    234239
     
    254259        }
    255260        td_set_ioc(&uhci_batch->tds[td - 1]);
    256         uhci_batch->base.ep->toggle = toggle;
     261        uhci_ep->toggle = toggle;
    257262        usb_log_debug2(
    258263            "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.", \
  • uspace/lib/usbhost/include/usb/host/bus.h

    r69b2dfee rc6f82e5  
    115115        void (*endpoint_unregister)(endpoint_t *);
    116116        void (*endpoint_destroy)(endpoint_t *);                 /**< Optional */
    117         void (*endpoint_toggle_reset)(endpoint_t *);            /**< Optional */
    118117        ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);    /**< Optional */
    119118        usb_transfer_batch_t *(*batch_create)(endpoint_t *);    /**< Optional */
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    r69b2dfee rc6f82e5  
    6161        /** Reserved bandwidth. */
    6262        size_t bandwidth;
    63         /** Value of the toggle bit. Untouched by the library. */
    64         unsigned toggle:1;
    6563        /** The currently active transfer batch. Write using methods, read under guard. */
    6664        usb_transfer_batch_t *active_batch;
  • uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h

    r69b2dfee rc6f82e5  
    5252typedef struct bus bus_t;
    5353
    54 /** How many toggles need to be reset */
    55 typedef enum {
    56         RESET_NONE,
    57         RESET_EP,
    58         RESET_ALL
    59 } toggle_reset_mode_t;
    60 
    6154/** Structure stores additional data needed for communication with EP */
    6255typedef struct usb_transfer_batch {
     
    8174                uint64_t packed;
    8275        } setup;
    83 
    84         /** Resetting the Toggle */
    85         toggle_reset_mode_t toggle_reset_mode;
    8676
    8777        /** Place for data to send/receive */
  • uspace/lib/usbhost/include/usb/host/utility.h

    r69b2dfee rc6f82e5  
    4444#include <usb/request.h>
    4545
     46typedef void (*endpoint_reset_toggle_t)(endpoint_t *);
     47
    4648int hc_get_ep0_max_packet_size(uint16_t *, bus_t *, device_t *);
    47 toggle_reset_mode_t hc_get_request_toggle_reset_mode(const usb_device_request_setup_packet_t *request);
     49void hc_reset_toggles(const usb_transfer_batch_t *batch, endpoint_reset_toggle_t);
    4850int hc_setup_virtual_root_hub(hc_device_t *);
    4951int hc_get_device_desc(device_t *, usb_standard_device_descriptor_t *);
  • uspace/lib/usbhost/src/endpoint.c

    r69b2dfee rc6f82e5  
    121121}
    122122
    123 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode);
    124 
    125123/**
    126124 * Wait until the endpoint have no transfer scheduled.
     
    166164        assert(ep);
    167165        assert(fibril_mutex_is_locked(&ep->guard));
    168 
    169         if (ep->active_batch && ep->active_batch->error == EOK)
    170                 endpoint_toggle_reset(ep, ep->active_batch->toggle_reset_mode);
    171 
    172166        ep->active_batch = NULL;
    173167        fibril_condvar_signal(&ep->avail);
    174 }
    175 
    176 /**
    177  * The transfer on an endpoint can trigger a reset of the toggle bit. This
    178  * function calls the respective bus callbacks to resolve it.
    179  *
    180  * @param ep The endpoint that triggered the reset
    181  * @param mode Whether to reset no, one or all endpoints on a device.
    182  */
    183 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode)
    184 {
    185         assert(ep);
    186 
    187         if (mode == RESET_NONE)
    188                 return;
    189 
    190         const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_toggle_reset);
    191         if (!ops)
    192                 return;
    193 
    194 
    195         if (mode == RESET_ALL) {
    196                 const device_t *dev = ep->device;
    197                 for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {
    198                         if (dev->endpoints[i])
    199                                 ops->endpoint_toggle_reset(dev->endpoints[i]);
    200                 }
    201         } else {
    202                 ops->endpoint_toggle_reset(ep);
    203         }
    204168}
    205169
     
    282246        batch->on_complete_data = arg;
    283247
    284         /* Check for commands that reset toggle bit */
    285         if (ep->transfer_type == USB_TRANSFER_CONTROL)
    286                 batch->toggle_reset_mode
    287                         = hc_get_request_toggle_reset_mode(&batch->setup.packet);
    288 
    289248        const int ret = ops->batch_schedule(batch);
    290249        if (ret != EOK) {
  • uspace/lib/usbhost/src/utility.c

    r69b2dfee rc6f82e5  
    3737#include <usb/debug.h>
    3838#include <usb/descriptor.h>
     39#include <usb/request.h>
    3940
    4041#include "ddf_helpers.h"
     
    101102}
    102103
    103 /** Check setup packet data for signs of toggle reset.
    104  *
    105  * @param[in] requst Setup requst data.
    106  *
    107  * @retval -1 No endpoints need reset.
    108  * @retval 0 All endpoints need reset.
    109  * @retval >0 Specified endpoint needs reset.
    110  *
    111  */
    112 toggle_reset_mode_t hc_get_request_toggle_reset_mode(const usb_device_request_setup_packet_t *request)
    113 {
    114         assert(request);
     104int hc_get_device_desc(device_t *device, usb_standard_device_descriptor_t *desc)
     105{
     106        const usb_target_t control_ep = {{
     107                .address = device->address,
     108                .endpoint = 0,
     109        }};
     110
     111        /* Get std device descriptor */
     112        const usb_device_request_setup_packet_t get_device_desc =
     113            GET_DEVICE_DESC(sizeof(*desc));
     114
     115        usb_log_debug("Device(%d): Requesting full device descriptor.",
     116            device->address);
     117        ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN,
     118            (char *) desc, sizeof(*desc), *(uint64_t *)&get_device_desc,
     119            "read device descriptor");
     120
     121        if (got < 0)
     122                return got;
     123
     124        return got == sizeof(*desc) ? EOK : EOVERFLOW;
     125}
     126
     127int hc_get_hub_desc(device_t *device, usb_hub_descriptor_header_t *desc)
     128{
     129        const usb_target_t control_ep = {{
     130                .address = device->address,
     131                .endpoint = 0,
     132        }};
     133
     134        const usb_device_request_setup_packet_t get_hub_desc = {
     135                .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST
     136                    | (USB_REQUEST_TYPE_CLASS << 5)
     137                    | USB_REQUEST_RECIPIENT_DEVICE,
     138                .request = USB_DEVREQ_GET_DESCRIPTOR, \
     139                .value = uint16_host2usb(USB_DESCTYPE_HUB << 8), \
     140                .length = sizeof(*desc),
     141        };
     142
     143        usb_log_debug("Device(%d): Requesting hub descriptor.",
     144            device->address);
     145        ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN,
     146            (char *) desc, sizeof(*desc), *(uint64_t *)&get_hub_desc,
     147            "get hub descriptor");
     148
     149        if (got < 0)
     150                return got;
     151
     152        return got == sizeof(*desc) ? EOK : EOVERFLOW;
     153}
     154
     155int hc_device_explore(device_t *device)
     156{
     157        int err;
     158        usb_standard_device_descriptor_t desc = { 0 };
     159
     160        if ((err = hc_get_device_desc(device, &desc))) {
     161                usb_log_error("Device(%d): Failed to get dev descriptor: %s",
     162                    device->address, str_error(err));
     163                return err;
     164        }
     165
     166        if ((err = hcd_ddf_setup_match_ids(device, &desc))) {
     167                usb_log_error("Device(%d): Failed to setup match ids: %s", device->address, str_error(err));
     168                return err;
     169        }
     170
     171        return EOK;
     172}
     173
     174/** Announce root hub to the DDF
     175 *
     176 * @param[in] device Host controller ddf device
     177 * @return Error code
     178 */
     179int hc_setup_virtual_root_hub(hc_device_t *hcd)
     180{
     181        int err;
     182
     183        assert(hcd);
     184
     185        device_t *dev = hcd_ddf_fun_create(hcd, USB_SPEED_MAX);
     186        if (!dev) {
     187                usb_log_error("Failed to create function for the root hub.");
     188                return ENOMEM;
     189        }
     190
     191        ddf_fun_set_name(dev->fun, "roothub");
     192
     193        /* Assign an address to the device */
     194        if ((err = bus_device_enumerate(dev))) {
     195                usb_log_error("Failed to enumerate roothub device: %s", str_error(err));
     196                goto err_usb_dev;
     197        }
     198
     199        if ((err = ddf_fun_bind(dev->fun))) {
     200                usb_log_error("Failed to register roothub: %s.", str_error(err));
     201                goto err_enumerated;
     202        }
     203
     204        return EOK;
     205
     206err_enumerated:
     207        bus_device_gone(dev);
     208err_usb_dev:
     209        hcd_ddf_fun_destroy(dev);
     210        return err;
     211}
     212
     213/** How many toggles need to be reset */
     214typedef enum {
     215        RESET_NONE,
     216        RESET_EP,
     217        RESET_ALL
     218} toggle_reset_mode_t;
     219
     220/**
     221 * Check setup packet data for signs of toggle reset.
     222 *
     223 * @param[in] batch USB batch
     224 */
     225static toggle_reset_mode_t get_request_toggle_reset_mode(const usb_transfer_batch_t *batch)
     226{
     227        if (batch->ep->transfer_type != USB_TRANSFER_CONTROL
     228            || batch->dir != USB_DIRECTION_OUT)
     229                return RESET_NONE;
     230
     231        const usb_device_request_setup_packet_t *request = &batch->setup.packet;
     232
    115233        switch (request->request)
    116234        {
     
    139257}
    140258
    141 int hc_get_device_desc(device_t *device, usb_standard_device_descriptor_t *desc)
    142 {
    143         const usb_target_t control_ep = {{
    144                 .address = device->address,
    145                 .endpoint = 0,
    146         }};
    147 
    148         /* Get std device descriptor */
    149         const usb_device_request_setup_packet_t get_device_desc =
    150             GET_DEVICE_DESC(sizeof(*desc));
    151 
    152         usb_log_debug("Device(%d): Requesting full device descriptor.",
    153             device->address);
    154         ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN,
    155             (char *) desc, sizeof(*desc), *(uint64_t *)&get_device_desc,
    156             "read device descriptor");
    157 
    158         if (got < 0)
    159                 return got;
    160 
    161         return got == sizeof(*desc) ? EOK : EOVERFLOW;
    162 }
    163 
    164 int hc_get_hub_desc(device_t *device, usb_hub_descriptor_header_t *desc)
    165 {
    166         const usb_target_t control_ep = {{
    167                 .address = device->address,
    168                 .endpoint = 0,
    169         }};
    170 
    171         const usb_device_request_setup_packet_t get_hub_desc = {
    172                 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST
    173                     | (USB_REQUEST_TYPE_CLASS << 5)
    174                     | USB_REQUEST_RECIPIENT_DEVICE,
    175                 .request = USB_DEVREQ_GET_DESCRIPTOR, \
    176                 .value = uint16_host2usb(USB_DESCTYPE_HUB << 8), \
    177                 .length = sizeof(*desc),
    178         };
    179 
    180         usb_log_debug("Device(%d): Requesting hub descriptor.",
    181             device->address);
    182         ssize_t got = bus_device_send_batch_sync(device, control_ep, USB_DIRECTION_IN,
    183             (char *) desc, sizeof(*desc), *(uint64_t *)&get_hub_desc,
    184             "get hub descriptor");
    185 
    186         if (got < 0)
    187                 return got;
    188 
    189         return got == sizeof(*desc) ? EOK : EOVERFLOW;
    190 }
    191 
    192 int hc_device_explore(device_t *device)
    193 {
    194         int err;
    195         usb_standard_device_descriptor_t desc = { 0 };
    196 
    197         if ((err = hc_get_device_desc(device, &desc))) {
    198                 usb_log_error("Device(%d): Failed to get dev descriptor: %s",
    199                     device->address, str_error(err));
    200                 return err;
    201         }
    202 
    203         if ((err = hcd_ddf_setup_match_ids(device, &desc))) {
    204                 usb_log_error("Device(%d): Failed to setup match ids: %s", device->address, str_error(err));
    205                 return err;
    206         }
    207 
    208         return EOK;
    209 }
    210 
    211 /** Announce root hub to the DDF
    212  *
    213  * @param[in] device Host controller ddf device
    214  * @return Error code
    215  */
    216 int hc_setup_virtual_root_hub(hc_device_t *hcd)
    217 {
    218         int err;
    219 
    220         assert(hcd);
    221 
    222         device_t *dev = hcd_ddf_fun_create(hcd, USB_SPEED_MAX);
    223         if (!dev) {
    224                 usb_log_error("Failed to create function for the root hub.");
    225                 return ENOMEM;
    226         }
    227 
    228         ddf_fun_set_name(dev->fun, "roothub");
    229 
    230         /* Assign an address to the device */
    231         if ((err = bus_device_enumerate(dev))) {
    232                 usb_log_error("Failed to enumerate roothub device: %s", str_error(err));
    233                 goto err_usb_dev;
    234         }
    235 
    236         if ((err = ddf_fun_bind(dev->fun))) {
    237                 usb_log_error("Failed to register roothub: %s.", str_error(err));
    238                 goto err_enumerated;
    239         }
    240 
    241         return EOK;
    242 
    243 err_enumerated:
    244         bus_device_gone(dev);
    245 err_usb_dev:
    246         hcd_ddf_fun_destroy(dev);
    247         return err;
     259void hc_reset_toggles(const usb_transfer_batch_t *batch, endpoint_reset_toggle_t reset_cb)
     260{
     261        assert(reset_cb);
     262        assert(batch->ep);
     263        assert(batch->ep->device);
     264
     265        if (batch->error != EOK)
     266                return;
     267
     268        toggle_reset_mode_t mode = get_request_toggle_reset_mode(batch);
     269
     270        if (mode == RESET_NONE)
     271                return;
     272
     273        if (mode == RESET_ALL) {
     274                const device_t *dev = batch->ep->device;
     275                for (usb_endpoint_t i = 0; i < 2 * USB_ENDPOINT_MAX; ++i) {
     276                        if (dev->endpoints[i])
     277                                reset_cb(dev->endpoints[i]);
     278                }
     279        } else {
     280                reset_cb(batch->ep);
     281        }
    248282}
    249283
Note: See TracChangeset for help on using the changeset viewer.