Changeset e05d6c3 in mainline


Ignore:
Timestamp:
2011-04-15T07:45:26Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3a85a2b
Parents:
a39cfb8 (diff), e583fd4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge with usb/development

Location:
uspace
Files:
1 added
22 edited

Legend:

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

    ra39cfb8 re05d6c3  
    161161                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    162162                            instance, i, data->tds[i]->status);
     163                        /* Make sure TD queue is empty (one TD),
     164                         * ED should be marked as halted */
     165                        data->ed->td_tail =
     166                            (data->ed->td_head & ED_TDTAIL_PTR_MASK);
     167                        ++i;
    163168                        break;
    164169                }
     
    169174        assert(hcd_ep);
    170175        hcd_ep->td = data->tds[i];
     176        /* Clear possible ED HALT */
     177        data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
     178        uint32_t pa = addr_to_phys(hcd_ep->td);
     179        assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK));
     180        assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK));
    171181
    172182        return true;
  • uspace/drv/ohci/hcd_endpoint.c

    ra39cfb8 re05d6c3  
    3535#include "hcd_endpoint.h"
    3636
     37static void hcd_ep_toggle_set(void *hcd_ep, int toggle)
     38{
     39        hcd_endpoint_t *instance = hcd_ep;
     40        assert(instance);
     41        assert(instance->ed);
     42        ed_toggle_set(instance->ed, toggle);
     43}
     44static int hcd_ep_toggle_get(void *hcd_ep)
     45{
     46        hcd_endpoint_t *instance = hcd_ep;
     47        assert(instance);
     48        assert(instance->ed);
     49        return ed_toggle_get(instance->ed);
     50}
     51
     52
    3753hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep)
    3854{
     
    5773        ed_init(hcd_ep->ed, ep);
    5874        ed_set_td(hcd_ep->ed, hcd_ep->td);
    59         endpoint_set_hc_data(ep, hcd_ep, NULL, NULL);
     75        endpoint_set_hc_data(ep, hcd_ep, hcd_ep_toggle_get, hcd_ep_toggle_set);
    6076
    6177        return hcd_ep;
  • uspace/drv/ohci/hw_struct/endpoint_descriptor.h

    ra39cfb8 re05d6c3  
    7373#define ED_TDHEAD_ZERO_SHIFT (2)
    7474#define ED_TDHEAD_TOGGLE_CARRY (0x2)
     75#define ED_TDHEAD_HALTED_FLAG (0x1)
    7576
    7677        volatile uint32_t next;
     
    106107        instance->next = pa;
    107108}
     109
     110static inline int ed_toggle_get(ed_t *instance)
     111{
     112        assert(instance);
     113        return (instance->td_head & ED_TDHEAD_TOGGLE_CARRY) ? 1 : 0;
     114}
     115
     116static inline void ed_toggle_set(ed_t *instance, int toggle)
     117{
     118        assert(instance);
     119        assert(toggle == 0 || toggle == 1);
     120        if (toggle == 1) {
     121                instance->td_head |= ED_TDHEAD_TOGGLE_CARRY;
     122        } else {
     123                /* clear halted flag when reseting toggle */
     124                instance->td_head &= ~ED_TDHEAD_TOGGLE_CARRY;
     125                instance->td_head &= ~ED_TDHEAD_HALTED_FLAG;
     126        }
     127}
    108128#endif
    109129/**
  • uspace/drv/ohci/ohci_regs.h

    ra39cfb8 re05d6c3  
    5555#define C_HCFS_MASK        (0x3) /* Host controller functional state */
    5656#define C_HCFS_RESET       (0x0)
    57 #define C_HCFS_OPERATIONAL (0x1)
    58 #define C_HCFS_RESUME      (0x2)
     57#define C_HCFS_RESUME      (0x1)
     58#define C_HCFS_OPERATIONAL (0x2)
    5959#define C_HCFS_SUSPEND     (0x3)
    6060#define C_HCFS_SHIFT       (6)
  • uspace/drv/ohci/root_hub.h

    ra39cfb8 re05d6c3  
    5454        /** hubs descriptors */
    5555        usb_device_descriptors_t descriptors;
     56        /** interrupt transfer waiting for an actual interrupt to occur */
     57        usb_transfer_batch_t * unfinished_interrupt_transfer;
    5658} rh_t;
    5759
  • uspace/drv/uhci-hcd/hc.c

    ra39cfb8 re05d6c3  
    247247{
    248248        assert(instance);
    249 #define CHECK_RET_CLEAR_RETURN(ret, message...) \
     249#define SETUP_TRANSFER_LIST(type, name) \
     250do { \
     251        int ret = transfer_list_init(&instance->transfers_##type, name); \
    250252        if (ret != EOK) { \
    251                 usb_log_error(message); \
     253                usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \
     254                    ret, name, str_error(ret)); \
    252255                transfer_list_fini(&instance->transfers_bulk_full); \
    253256                transfer_list_fini(&instance->transfers_control_full); \
     
    255258                transfer_list_fini(&instance->transfers_interrupt); \
    256259                return ret; \
    257         } else (void) 0
    258 
    259         /* initialize TODO: check errors */
    260         int ret;
    261         ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
    262         CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list.");
    263 
    264         ret = transfer_list_init(
    265             &instance->transfers_control_full, "CONTROL_FULL");
    266         CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list.");
    267 
    268         ret = transfer_list_init(
    269             &instance->transfers_control_slow, "CONTROL_SLOW");
    270         CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list.");
    271 
    272         ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT");
    273         CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list.");
    274 
     260        } \
     261} while (0)
     262
     263        SETUP_TRANSFER_LIST(bulk_full, "BULK FULL");
     264        SETUP_TRANSFER_LIST(control_full, "CONTROL FULL");
     265        SETUP_TRANSFER_LIST(control_slow, "CONTROL LOW");
     266        SETUP_TRANSFER_LIST(interrupt, "INTERRUPT");
     267#undef SETUP_TRANSFER_LIST
     268        /* Connect lists into one schedule */
    275269        transfer_list_set_next(&instance->transfers_control_full,
    276270                &instance->transfers_bulk_full);
     
    337331        assert(instance);
    338332//      status |= 1; //Uncomment to work around qemu hang
    339         /* TODO: Resume interrupts are not supported */
    340333        /* Lower 2 bits are transaction error and transaction complete */
    341         if (status & 0x3) {
     334        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
    342335                LIST_INITIALIZE(done);
    343336                transfer_list_remove_finished(
     
    358351                }
    359352        }
    360         /* bits 4 and 5 indicate hc error */
    361         if (status & 0x18) {
     353        /* Resume interrupts are not supported */
     354
     355        /* Bits 4 and 5 indicate hc error */
     356        if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
    362357                usb_log_error("UHCI hardware failure!.\n");
    363358                ++instance->hw_failures;
     
    389384
    390385        while (1) {
    391                 /* read and ack interrupts */
     386                /* Readd and clear status register */
    392387                uint16_t status = pio_read_16(&instance->registers->usbsts);
    393                 pio_write_16(&instance->registers->usbsts, 0x1f);
     388                pio_write_16(&instance->registers->usbsts, status);
    394389                if (status != 0)
    395390                        usb_log_debug2("UHCI status: %x.\n", status);
    396391                hc_interrupt(instance, status);
    397                 async_usleep(UHCI_CLEANER_TIMEOUT);
     392                async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
    398393        }
    399394        return EOK;
  • uspace/drv/uhci-hcd/hc.h

    ra39cfb8 re05d6c3  
    8888
    8989#define UHCI_FRAME_LIST_COUNT 1024
    90 #define UHCI_CLEANER_TIMEOUT 10000
     90#define UHCI_INT_EMULATOR_TIMEOUT 10000
    9191#define UHCI_DEBUGER_TIMEOUT 5000000
    9292#define UHCI_ALLOWED_HW_FAIL 5
  • uspace/drv/uhci-hcd/main.c

    ra39cfb8 re05d6c3  
    7878        device->driver_data = uhci;
    7979
    80         usb_log_info("Controlling new UHCI device `%s'.\n", device->name);
     80        usb_log_info("Controlling new UHCI device '%s'.\n", device->name);
    8181
    8282        return EOK;
  • uspace/drv/uhci-rhd/port.c

    ra39cfb8 re05d6c3  
    6868 * @return Error code. (Always EOK)
    6969 */
    70 static inline void uhci_port_write_status(
    71     uhci_port_t *port, port_status_t value)
    72 {
    73         assert(port);
    74         pio_write_16(port->address, value);
     70static inline void uhci_port_write_status(uhci_port_t *port, port_status_t val)
     71{
     72        assert(port);
     73        pio_write_16(port->address, val);
    7574}
    7675/*----------------------------------------------------------------------------*/
     
    101100        port->rh = rh;
    102101
    103         int rc = usb_hc_connection_initialize_from_device(
    104             &port->hc_connection, rh);
    105         if (rc != EOK) {
     102        int ret =
     103            usb_hc_connection_initialize_from_device(&port->hc_connection, rh);
     104        if (ret != EOK) {
    106105                usb_log_error("Failed to initialize connection to HC.");
    107                 return rc;
     106                return ret;
    108107        }
    109108
     
    238237        /* Enable the port. */
    239238        uhci_port_set_enabled(port, true);
    240 
    241239        return EOK;
    242240}
     
    271269        usb_log_info("New device at port %u, address %d (handle %llu).\n",
    272270            port->number, dev_addr, port->attached_device);
    273 
    274271        return EOK;
    275272}
     
    313310        /* Write new value. */
    314311        uhci_port_write_status(port, port_status);
     312
     313        /* Wait for port to become enabled */
     314        do {
     315                async_usleep(1000);
     316                port_status = uhci_port_read_status(port);
     317        } while ((port_status & STATUS_CONNECTED) &&
     318            !(port_status & STATUS_ENABLED));
    315319
    316320        usb_log_debug("%s: %sabled port.\n",
  • uspace/drv/uhci-rhd/port.h

    ra39cfb8 re05d6c3  
    5454#define STATUS_SUSPEND   (1 << 12)
    5555
     56/** UHCI port structure */
    5657typedef struct uhci_port
    5758{
  • uspace/drv/uhci-rhd/root_hub.c

    ra39cfb8 re05d6c3  
    3333 */
    3434#include <errno.h>
     35#include <str_error.h>
    3536#include <ddi.h>
    3637#include <usb/debug.h>
     
    4344 * @param[in] addr Address of I/O registers.
    4445 * @param[in] size Size of available I/O space.
    45  * @param[in] rh Pointer to ddf instance of the root hub driver.
     46 * @param[in] rh Pointer to DDF instance of the root hub driver.
    4647 * @return Error code.
    4748 */
     
    5859        if (ret < 0) {
    5960                usb_log_error(
    60                     "Failed(%d) to gain access to port registers at %p\n",
    61                     ret, regs);
     61                    "Failed(%d) to gain access to port registers at %p: %s.\n",
     62                    ret, regs, str_error(ret));
    6263                return ret;
    6364        }
     
    6667        unsigned i = 0;
    6768        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    68                 /* NOTE: mind pointer arithmetics here */
    6969                ret = uhci_port_init(
    70                     &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
     70                    &instance->ports[i], &regs[i], i, ROOT_HUB_WAIT_USEC, rh);
    7171                if (ret != EOK) {
    7272                        unsigned j = 0;
  • uspace/drv/uhci-rhd/root_hub.h

    ra39cfb8 re05d6c3  
    4242#define ROOT_HUB_WAIT_USEC 250000 /* 250 miliseconds */
    4343
     44/** UHCI root hub drvier structure */
    4445typedef struct root_hub {
     46        /** Ports provided by the hub */
    4547        uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT];
    46         devman_handle_t hc_handle;
    4748} uhci_root_hub_t;
    4849
    4950int uhci_root_hub_init(
    50   uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh);
     51    uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh);
    5152
    5253void uhci_root_hub_fini(uhci_root_hub_t *instance);
  • uspace/drv/usbhid/main.c

    ra39cfb8 re05d6c3  
    4242
    4343#include <usb/devdrv.h>
     44#include <usb/devpoll.h>
    4445
    4546#include "usbhid.h"
  • uspace/drv/usbhub/usbhub.c

    ra39cfb8 re05d6c3  
    4545#include <usb/request.h>
    4646#include <usb/classes/hub.h>
     47#include <usb/devpoll.h>
    4748#include <stdio.h>
    4849
  • uspace/drv/usbkbd/main.c

    ra39cfb8 re05d6c3  
    4242
    4343#include <usb/devdrv.h>
     44#include <usb/devpoll.h>
    4445
    4546#include "kbddev.h"
  • uspace/drv/usbmouse/main.c

    ra39cfb8 re05d6c3  
    3636#include "mouse.h"
    3737#include <usb/debug.h>
     38#include <usb/devpoll.h>
    3839#include <errno.h>
    3940#include <str_error.h>
  • uspace/lib/usb/include/usb/devdrv.h

    ra39cfb8 re05d6c3  
    162162    usb_endpoint_description_t **);
    163163
    164 typedef bool (*usb_polling_callback_t)(usb_device_t *,
    165     uint8_t *, size_t, void *);
    166 typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
    167 
    168 int usb_device_auto_poll(usb_device_t *, size_t,
    169     usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
    170 
    171164int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
    172165int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
  • uspace/lib/usb/include/usb/pipes.h

    ra39cfb8 re05d6c3  
    9999        /** Number of active transfers over the pipe. */
    100100        int refcount;
     101
     102        /** Whether to automatically reset halt on the endpoint.
     103         * Valid only for control endpoint zero.
     104         */
     105        bool auto_reset_halt;
    101106} usb_pipe_t;
    102107
  • uspace/lib/usb/src/devpoll.c

    ra39cfb8 re05d6c3  
    3333 * USB device driver framework - automatic interrupt polling.
    3434 */
    35 #include <usb/devdrv.h>
     35#include <usb/devpoll.h>
    3636#include <usb/request.h>
    3737#include <usb/debug.h>
     38#include <usb/classes/classes.h>
    3839#include <errno.h>
    3940#include <str_error.h>
     
    4546/** Data needed for polling. */
    4647typedef struct {
     48        int debug;
     49        size_t max_failures;
     50        useconds_t delay;
     51        bool auto_clear_halt;
     52        bool (*on_data)(usb_device_t *, uint8_t *, size_t, void *);
     53        void (*on_polling_end)(usb_device_t *, bool, void *);
     54        bool (*on_error)(usb_device_t *, int, void *);
     55
    4756        usb_device_t *dev;
    4857        size_t pipe_index;
    49         usb_polling_callback_t callback;
    50         usb_polling_terminted_callback_t terminated_callback;
    5158        size_t request_size;
    5259        uint8_t *buffer;
     
    5461} polling_data_t;
    5562
     63
    5664/** Polling fibril.
    5765 *
     
    6775            = polling_data->dev->pipes[polling_data->pipe_index].pipe;
    6876       
    69         usb_log_debug("Pipe interface number: %d, protocol: %d, subclass: %d, max packet size: %d\n",
    70             polling_data->dev->pipes[polling_data->pipe_index].interface_no,
    71             polling_data->dev->pipes[polling_data->pipe_index].description->interface_protocol,
    72             polling_data->dev->pipes[polling_data->pipe_index].description->interface_subclass,
    73             pipe->max_packet_size);
     77        if (polling_data->debug > 0) {
     78                usb_endpoint_mapping_t *mapping
     79                    = &polling_data->dev->pipes[polling_data->pipe_index];
     80                usb_log_debug("Poll0x%x: started polling of `%s' - " \
     81                    "interface %d (%s,%d,%d), %zuB/%zu.\n",
     82                    polling_data,
     83                    polling_data->dev->ddf_dev->name,
     84                    (int) mapping->interface->interface_number,
     85                    usb_str_class(mapping->interface->interface_class),
     86                    (int) mapping->interface->interface_subclass,
     87                    (int) mapping->interface->interface_protocol,
     88                    polling_data->request_size, pipe->max_packet_size);
     89        }
    7490
    7591        size_t failed_attempts = 0;
    76         while (failed_attempts < MAX_FAILED_ATTEMPTS) {
     92        while (failed_attempts <= polling_data->max_failures) {
    7793                int rc;
    7894
     
    8197                    polling_data->request_size, &actual_size);
    8298
    83                
    84 //              if (rc == ESTALL) {
    85 //                      usb_log_debug("Seding clear feature...\n");
    86 //                      usb_request_clear_feature(pipe, USB_REQUEST_TYPE_STANDARD,
    87 //                        USB_REQUEST_RECIPIENT_ENDPOINT, 0, pipe->endpoint_no);
    88 //                      continue;
    89 //              }
     99                if (polling_data->debug > 1) {
     100                        if (rc == EOK) {
     101                                usb_log_debug(
     102                                    "Poll0x%x: received: '%s' (%zuB).\n",
     103                                    polling_data,
     104                                    usb_debug_str_buffer(polling_data->buffer,
     105                                        actual_size, 16),
     106                                    actual_size);
     107                        } else {
     108                                usb_log_debug(
     109                                    "Poll0x%x: polling failed: %s.\n",
     110                                    polling_data, str_error(rc));
     111                        }
     112                }
     113
     114                /* If the pipe stalled, we can try to reset the stall. */
     115                if ((rc == ESTALL) && (polling_data->auto_clear_halt)) {
     116                        /*
     117                         * We ignore error here as this is usually a futile
     118                         * attempt anyway.
     119                         */
     120                        usb_request_clear_endpoint_halt(
     121                            &polling_data->dev->ctrl_pipe,
     122                            pipe->endpoint_no);
     123                }
    90124
    91125                if (rc != EOK) {
     126                        if (polling_data->on_error != NULL) {
     127                                bool cont = polling_data->on_error(
     128                                    polling_data->dev, rc,
     129                                    polling_data->custom_arg);
     130                                if (!cont) {
     131                                        failed_attempts
     132                                            = polling_data->max_failures;
     133                                }
     134                        }
    92135                        failed_attempts++;
    93136                        continue;
     
    95138
    96139                /* We have the data, execute the callback now. */
    97                 bool carry_on = polling_data->callback(polling_data->dev,
     140                bool carry_on = polling_data->on_data(polling_data->dev,
    98141                    polling_data->buffer, actual_size,
    99142                    polling_data->custom_arg);
     
    106149                /* Reset as something might be only a temporary problem. */
    107150                failed_attempts = 0;
    108         }
    109 
    110         if (failed_attempts > 0) {
    111                 usb_log_error(
    112                     "Polling of device `%s' terminated: recurring failures.\n",
    113                     polling_data->dev->ddf_dev->name);
    114         }
    115 
    116         if (polling_data->terminated_callback != NULL) {
    117                 polling_data->terminated_callback(polling_data->dev,
     151
     152                /* Take a rest before next request. */
     153                async_usleep(polling_data->delay);
     154        }
     155
     156        if (polling_data->on_polling_end != NULL) {
     157                polling_data->on_polling_end(polling_data->dev,
    118158                    failed_attempts > 0, polling_data->custom_arg);
     159        }
     160
     161        if (polling_data->debug > 0) {
     162                if (failed_attempts > 0) {
     163                        usb_log_error(
     164                            "Polling of device `%s' terminated: %s.\n",
     165                            polling_data->dev->ddf_dev->name,
     166                            "recurring failures");
     167                } else {
     168                        usb_log_debug(
     169                            "Polling of device `%s' terminated by user.\n",
     170                            polling_data->dev->ddf_dev->name
     171                        );
     172                }
    119173        }
    120174
     
    159213        }
    160214
     215        usb_device_auto_polling_t *auto_polling
     216            = malloc(sizeof(usb_device_auto_polling_t));
     217        if (auto_polling == NULL) {
     218                return ENOMEM;
     219        }
     220
     221        auto_polling->debug = 1;
     222        auto_polling->auto_clear_halt = true;
     223        auto_polling->delay = 0;
     224        auto_polling->max_failures = MAX_FAILED_ATTEMPTS;
     225        auto_polling->on_data = callback;
     226        auto_polling->on_polling_end = terminated_callback;
     227        auto_polling->on_error = NULL;
     228
     229        int rc = usb_device_auto_polling(dev, pipe_index, auto_polling,
     230           request_size, arg);
     231
     232        free(auto_polling);
     233
     234        return rc;
     235}
     236
     237/** Start automatic device polling over interrupt in pipe.
     238 *
     239 * The polling settings is copied thus it is okay to destroy the structure
     240 * after this function returns.
     241 *
     242 * @warning There is no guarantee when the request to the device
     243 * will be sent for the first time (it is possible that this
     244 * first request would be executed prior to return from this function).
     245 *
     246 * @param dev Device to be periodically polled.
     247 * @param pipe_index Index of the endpoint pipe used for polling.
     248 * @param polling Polling settings.
     249 * @param request_size How many bytes to ask for in each request.
     250 * @param arg Custom argument (passed as is to the callbacks).
     251 * @return Error code.
     252 * @retval EOK New fibril polling the device was already started.
     253 */
     254int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
     255    usb_device_auto_polling_t *polling,
     256    size_t request_size, void *arg)
     257{
     258        if (dev == NULL) {
     259                return EBADMEM;
     260        }
     261        if (pipe_index >= dev->pipes_count) {
     262                return EINVAL;
     263        }
     264        if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
     265            || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
     266                return EINVAL;
     267        }
     268        if ((polling == NULL) || (polling->on_data == NULL)) {
     269                return EBADMEM;
     270        }
     271
    161272        polling_data_t *polling_data = malloc(sizeof(polling_data_t));
    162273        if (polling_data == NULL) {
     
    164275        }
    165276
    166         /* Allocate now to prevent immediate failure in the polling fibril. */
    167         polling_data->buffer = malloc(request_size);
     277        /* Fill-in the data. */
     278        polling_data->buffer = malloc(sizeof(request_size));
    168279        if (polling_data->buffer == NULL) {
    169280                free(polling_data);
    170281                return ENOMEM;
    171282        }
     283        polling_data->request_size = request_size;
    172284        polling_data->dev = dev;
    173285        polling_data->pipe_index = pipe_index;
    174         polling_data->callback = callback;
    175         polling_data->terminated_callback = terminated_callback;
    176         polling_data->request_size = request_size;
    177286        polling_data->custom_arg = arg;
     287
     288        polling_data->debug = polling->debug;
     289        polling_data->max_failures = polling->max_failures;
     290        if (polling->delay >= 0) {
     291                polling_data->delay = (useconds_t) polling->delay;
     292        } else {
     293                polling_data->delay = (useconds_t) dev->pipes[pipe_index]
     294                    .descriptor->poll_interval;
     295        }
     296        polling_data->auto_clear_halt = polling->auto_clear_halt;
     297
     298        polling_data->on_data = polling->on_data;
     299        polling_data->on_polling_end = polling->on_polling_end;
     300        polling_data->on_error = polling->on_error;
    178301
    179302        fid_t fibril = fibril_create(polling_fibril, polling_data);
     
    181304                free(polling_data->buffer);
    182305                free(polling_data);
    183                 /* FIXME: better error code. */
    184306                return ENOMEM;
    185307        }
    186308        fibril_add_ready(fibril);
    187309
    188         /* The allocated buffer etc. will be freed by the fibril. */
     310        /* Fibril launched. That fibril will free the allocated data. */
    189311
    190312        return EOK;
  • uspace/lib/usb/src/host/endpoint.c

    ra39cfb8 re05d6c3  
    123123        if (instance->address == target.address &&
    124124            (instance->endpoint == target.endpoint || target.endpoint == 0))
    125                 instance->toggle = 0;
     125                endpoint_toggle_set(instance, 0);
    126126}
    127127/**
  • uspace/lib/usb/src/pipesinit.c

    ra39cfb8 re05d6c3  
    365365        pipe->direction = direction;
    366366        pipe->refcount = 0;
     367        pipe->auto_reset_halt = false;
    367368
    368369        return EOK;
     
    385386            0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE,
    386387            USB_DIRECTION_BOTH);
     388
     389        pipe->auto_reset_halt = true;
    387390
    388391        return rc;
  • uspace/lib/usb/src/pipesio.c

    ra39cfb8 re05d6c3  
    4949#include <assert.h>
    5050#include <usbhc_iface.h>
     51#include <usb/request.h>
    5152#include "pipepriv.h"
    5253
     
    307308}
    308309
     310/** Try to clear endpoint halt of default control pipe.
     311 *
     312 * @param pipe Pipe for control endpoint zero.
     313 */
     314static void clear_self_endpoint_halt(usb_pipe_t *pipe)
     315{
     316        assert(pipe != NULL);
     317
     318        if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) {
     319                return;
     320        }
     321
     322
     323        /* Prevent indefinite recursion. */
     324        pipe->auto_reset_halt = false;
     325        usb_request_clear_endpoint_halt(pipe, 0);
     326        pipe->auto_reset_halt = true;
     327}
     328
    309329
    310330/** Request a control read transfer, no checking of input parameters.
     
    436456            setup_buffer, setup_buffer_size,
    437457            data_buffer, data_buffer_size, &act_size);
     458
     459        if (rc == ESTALL) {
     460                clear_self_endpoint_halt(pipe);
     461        }
    438462
    439463        pipe_drop_ref(pipe);
     
    563587            setup_buffer, setup_buffer_size, data_buffer, data_buffer_size);
    564588
     589        if (rc == ESTALL) {
     590                clear_self_endpoint_halt(pipe);
     591        }
     592
    565593        pipe_drop_ref(pipe);
    566594
Note: See TracChangeset for help on using the changeset viewer.