Changes in / [a43f1d18:f35b294] in mainline


Ignore:
Location:
uspace
Files:
6 deleted
35 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/dev.c

    ra43f1d18 rf35b294  
    5050
    5151        int rc;
    52         bool transfer_started = false;
    5352
    5453        rc = usb_device_connection_initialize(&dev->wire, hc_handle, dev_addr);
     
    7776        }
    7877
    79         rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe);
     78        rc = usb_pipe_start_session(&dev->ctrl_pipe);
    8079        if (rc != EOK) {
    8180                fprintf(stderr,
    82                     NAME ": failed to start transfer on control pipe: %s.\n",
     81                    NAME ": failed to start session on control pipe: %s.\n",
    8382                    str_error(rc));
    8483                goto leave;
    8584        }
    86         transfer_started = true;
    8785
    8886        rc = usb_request_get_device_descriptor(&dev->ctrl_pipe,
     
    109107
    110108leave:
    111         if (transfer_started) {
    112                 usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     109        if (usb_pipe_is_session_started(&dev->ctrl_pipe)) {
     110                usb_pipe_end_session(&dev->ctrl_pipe);
    113111        }
    114112
     
    120118void destroy_device(usbinfo_device_t *dev)
    121119{
    122         usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     120        usb_pipe_end_session(&dev->ctrl_pipe);
    123121        free(dev);
    124122}
  • uspace/doc/doxygroups.h

    ra43f1d18 rf35b294  
    269269
    270270        /**
    271          * @defgroup drvusbohci OHCI driver
    272          * @ingroup usb
    273          * @brief Driver for OHCI host controller.
    274          */
    275 
    276         /**
    277271         * @defgroup drvusbehci EHCI driver
    278272         * @ingroup usb
     
    281275
    282276        /**
    283          * @defgroup drvusbfallback USB fallback driver
     277         * @defgroup drvusbfallback USB fallback driver.
    284278         * @ingroup usb
    285279         * @brief Fallback driver for any USB device.
  • uspace/drv/ehci-hcd/hc_iface.c

    ra43f1d18 rf35b294  
    123123 * @param[in] fun Device function the action was invoked on.
    124124 * @param[in] address USB address of the device.
    125  * @param[in] speed Endpoint speed (invalid means to use device one).
    126125 * @param[in] endpoint Endpoint number.
    127126 * @param[in] transfer_type USB transfer type.
     
    132131 */
    133132static int register_endpoint(ddf_fun_t *fun,
    134     usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
     133    usb_address_t address, usb_endpoint_t endpoint,
    135134    usb_transfer_type_t transfer_type, usb_direction_t direction,
    136135    size_t max_packet_size, unsigned int interval)
     
    166165 * @param[in] fun Device function the action was invoked on.
    167166 * @param[in] target Target pipe (address and endpoint number) specification.
     167 * @param[in] max_packet_size Max packet size for the transfer.
    168168 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    169169 *      by the caller).
     
    174174 */
    175175static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    176     void *data, size_t size,
     176    size_t max_packet_size, void *data, size_t size,
    177177    usbhc_iface_transfer_out_callback_t callback, void *arg)
    178178{
     
    191191 * @param[in] fun Device function the action was invoked on.
    192192 * @param[in] target Target pipe (address and endpoint number) specification.
     193 * @param[in] max_packet_size Max packet size for the transfer.
    193194 * @param[in] data Buffer where to store the data (in USB endianess,
    194195 *      allocated and deallocated by the caller).
     
    199200 */
    200201static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    201     void *data, size_t size,
     202    size_t max_packet_size, void *data, size_t size,
    202203    usbhc_iface_transfer_in_callback_t callback, void *arg)
    203204{
     
    216217 * @param[in] fun Device function the action was invoked on.
    217218 * @param[in] target Target pipe (address and endpoint number) specification.
     219 * @param[in] max_packet_size Max packet size for the transfer.
    218220 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    219221 *      by the caller).
     
    224226 */
    225227static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    226     void *data, size_t size,
     228    size_t max_packet_size, void *data, size_t size,
    227229    usbhc_iface_transfer_out_callback_t callback, void *arg)
    228230{
     
    241243 * @param[in] fun Device function the action was invoked on.
    242244 * @param[in] target Target pipe (address and endpoint number) specification.
     245 * @param[in] max_packet_size Max packet size for the transfer.
    243246 * @param[in] data Buffer where to store the data (in USB endianess,
    244247 *      allocated and deallocated by the caller).
     
    249252 */
    250253static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    251     void *data, size_t size,
     254    size_t max_packet_size, void *data, size_t size,
    252255    usbhc_iface_transfer_in_callback_t callback, void *arg)
    253256{
     
    266269 * @param[in] fun Device function the action was invoked on.
    267270 * @param[in] target Target pipe (address and endpoint number) specification.
     271 * @param[in] max_packet_size Max packet size for the transfer.
    268272 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    269273 *      and deallocated by the caller).
     
    277281 */
    278282static int control_write(ddf_fun_t *fun, usb_target_t target,
     283    size_t max_packet_size,
    279284    void *setup_packet, size_t setup_packet_size,
    280285    void *data_buffer, size_t data_buffer_size,
     
    295300 * @param[in] fun Device function the action was invoked on.
    296301 * @param[in] target Target pipe (address and endpoint number) specification.
     302 * @param[in] max_packet_size Max packet size for the transfer.
    297303 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    298304 *      and deallocated by the caller).
     
    306312 */
    307313static int control_read(ddf_fun_t *fun, usb_target_t target,
     314    size_t max_packet_size,
    308315    void *setup_packet, size_t setup_packet_size,
    309316    void *data_buffer, size_t data_buffer_size,
  • uspace/drv/ohci/Makefile

    ra43f1d18 rf35b294  
    3333
    3434SOURCES = \
     35        iface.c \
    3536        batch.c \
     37        main.c \
    3638        hc.c \
    37         iface.c \
    38         main.c \
    3939        ohci.c \
    40         pci.c \
    4140        root_hub.c \
    42         transfer_list.c \
    43         hw_struct/endpoint_descriptor.c \
    44         hw_struct/transfer_descriptor.c
    45 
     41        pci.c
    4642
    4743include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/ohci/batch.c

    ra43f1d18 rf35b294  
    4040#include "batch.h"
    4141#include "utils/malloc32.h"
    42 #include "hw_struct/endpoint_descriptor.h"
    43 #include "hw_struct/transfer_descriptor.h"
    4442
    45 typedef struct ohci_batch {
    46         ed_t *ed;
    47         td_t *tds;
    48         size_t td_count;
    49 } ohci_batch_t;
    50 
    51 static void batch_control(usb_transfer_batch_t *instance,
    52     usb_direction_t data_dir, usb_direction_t status_dir);
    5343static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
    5444static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
    5545
    5646#define DEFAULT_ERROR_COUNT 3
    57 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
    58     char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
     47usb_transfer_batch_t * batch_get(
     48    ddf_fun_t *fun,
     49                usb_target_t target,
     50    usb_transfer_type_t transfer_type,
     51                size_t max_packet_size,
     52    usb_speed_t speed,
     53                char *buffer,
     54                size_t buffer_size,
     55                char *setup_buffer,
     56                size_t setup_size,
    5957    usbhc_iface_transfer_in_callback_t func_in,
    60     usbhc_iface_transfer_out_callback_t func_out, void *arg)
     58    usbhc_iface_transfer_out_callback_t func_out,
     59                void *arg,
     60                usb_device_keeper_t *manager
     61                )
    6162{
    6263#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
     
    7273        CHECK_NULL_DISPOSE_RETURN(instance,
    7374            "Failed to allocate batch instance.\n");
    74         usb_target_t target =
    75             { .address = ep->address, .endpoint = ep->endpoint };
    76         usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
    77             ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
    78             func_in, func_out, arg, fun, ep, NULL);
    79 
    80         ohci_batch_t *data = malloc(sizeof(ohci_batch_t));
    81         CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
    82         bzero(data, sizeof(ohci_batch_t));
    83         instance->private_data = data;
    84 
    85         /* we needs + 1 transfer descriptor as the last one won't be executed */
    86         data->td_count = 1 +
    87             ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER);
    88         if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    89                 data->td_count += 2;
    90         }
    91 
    92         data->tds = malloc32(sizeof(td_t) * data->td_count);
    93         CHECK_NULL_DISPOSE_RETURN(data->tds,
    94             "Failed to allocate transfer descriptors.\n");
    95         bzero(data->tds, sizeof(td_t) * data->td_count);
    96 
    97         data->ed = malloc32(sizeof(ed_t));
    98         CHECK_NULL_DISPOSE_RETURN(data->ed,
    99             "Failed to allocate endpoint descriptor.\n");
     75        usb_transfer_batch_init(instance, target, transfer_type, speed,
     76            max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
     77            func_in, func_out, arg, fun, NULL, NULL);
    10078
    10179        if (buffer_size > 0) {
     
    11290        }
    11391
     92
    11493        return instance;
    11594}
     
    11897{
    11998        assert(instance);
    120         ohci_batch_t *data = instance->private_data;
    121         assert(data);
    122         free32(data->ed);
    123         free32(data->tds);
     99        free32(instance->transport_buffer);
    124100        free32(instance->setup_buffer);
    125         free32(instance->transport_buffer);
    126         free(data);
    127101        free(instance);
    128 }
    129 /*----------------------------------------------------------------------------*/
    130 bool batch_is_complete(usb_transfer_batch_t *instance)
    131 {
    132         assert(instance);
    133         ohci_batch_t *data = instance->private_data;
    134         assert(data);
    135         size_t tds = data->td_count - 1;
    136         usb_log_debug2("Batch(%p) checking %d td(s) for completion.\n",
    137             instance, tds);
    138         size_t i = 0;
    139         for (; i < tds; ++i) {
    140                 if (!td_is_finished(&data->tds[i]))
    141                         return false;
    142                 instance->error = td_error(&data->tds[i]);
    143                 /* FIXME: calculate real transfered size */
    144                 instance->transfered_size = instance->buffer_size;
    145                 if (instance->error != EOK) {
    146                         usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    147                             instance, i, data->tds[i].status);
    148                         return true;
    149 //                      endpoint_toggle_set(instance->ep,
    150                 }
    151         }
    152         return true;
    153102}
    154103/*----------------------------------------------------------------------------*/
     
    160109            instance->buffer_size);
    161110        instance->next_step = batch_call_out_and_dispose;
    162         batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN);
     111        /* TODO: implement */
    163112        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
    164113}
     
    168117        assert(instance);
    169118        instance->next_step = batch_call_in_and_dispose;
    170         batch_control(instance, USB_DIRECTION_IN, USB_DIRECTION_OUT);
     119        /* TODO: implement */
    171120        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    172121}
     
    175124{
    176125        assert(instance);
    177         assert(instance->direction == USB_DIRECTION_IN);
     126        instance->direction = USB_DIRECTION_IN;
    178127        instance->next_step = batch_call_in_and_dispose;
    179128        /* TODO: implement */
     
    184133{
    185134        assert(instance);
    186         assert(instance->direction == USB_DIRECTION_OUT);
     135        instance->direction = USB_DIRECTION_OUT;
    187136        /* We are data out, we are supposed to provide data */
    188137        memcpy(instance->transport_buffer, instance->buffer,
     
    211160}
    212161/*----------------------------------------------------------------------------*/
    213 ed_t * batch_ed(usb_transfer_batch_t *instance)
    214 {
    215         assert(instance);
    216         ohci_batch_t *data = instance->private_data;
    217         assert(data);
    218         return data->ed;
    219 }
    220 /*----------------------------------------------------------------------------*/
    221 void batch_control(usb_transfer_batch_t *instance,
    222     usb_direction_t data_dir, usb_direction_t status_dir)
    223 {
    224         assert(instance);
    225         ohci_batch_t *data = instance->private_data;
    226         assert(data);
    227         ed_init(data->ed, instance->ep);
    228         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);
    231         int toggle = 0;
    232         /* setup stage */
    233         td_init(&data->tds[0], USB_DIRECTION_BOTH, instance->setup_buffer,
    234                 instance->setup_size, toggle);
    235         td_set_next(&data->tds[0], &data->tds[1]);
    236         usb_log_debug("Created SETUP TD: %x:%x:%x:%x.\n", data->tds[0].status,
    237             data->tds[0].cbp, data->tds[0].next, data->tds[0].be);
    238 
    239         /* data stage */
    240         size_t td_current = 1;
    241         size_t remain_size = instance->buffer_size;
    242         char *transfer_buffer = instance->transport_buffer;
    243         while (remain_size > 0) {
    244                 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
    245                     OHCI_TD_MAX_TRANSFER : remain_size;
    246                 toggle = 1 - toggle;
    247 
    248                 td_init(&data->tds[td_current], data_dir, transfer_buffer,
    249                     transfer_size, toggle);
    250                 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);
    251                 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",
    252                     data->tds[td_current].status, data->tds[td_current].cbp,
    253                     data->tds[td_current].next, data->tds[td_current].be);
    254 
    255                 transfer_buffer += transfer_size;
    256                 remain_size -= transfer_size;
    257                 assert(td_current < data->td_count - 2);
    258                 ++td_current;
    259         }
    260 
    261         /* status stage */
    262         assert(td_current == data->td_count - 2);
    263         td_init(&data->tds[td_current], status_dir, NULL, 0, 1);
    264         usb_log_debug("Created STATUS TD: %x:%x:%x:%x.\n",
    265             data->tds[td_current].status, data->tds[td_current].cbp,
    266             data->tds[td_current].next, data->tds[td_current].be);
    267 }
    268 /*----------------------------------------------------------------------------*/
    269162/** Helper function calls callback and correctly disposes of batch structure.
    270163 *
  • uspace/drv/ohci/batch.h

    ra43f1d18 rf35b294  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbuhcihc
     28/** @addtogroup drvusbohci
    2929 * @{
    3030 */
    3131/** @file
    32  * @brief UHCI driver USB transaction structure
     32 * @brief OHCI driver USB transaction structure
    3333 */
    34 #ifndef DRV_UHCI_BATCH_H
    35 #define DRV_UHCI_BATCH_H
     34#ifndef DRV_OHCI_BATCH_H
     35#define DRV_OHCI_BATCH_H
     36
    3637
    3738#include <usbhc_iface.h>
    3839#include <usb/usb.h>
    3940#include <usb/host/device_keeper.h>
    40 #include <usb/host/endpoint.h>
    4141#include <usb/host/batch.h>
    4242
    43 #include "hw_struct/endpoint_descriptor.h"
    44 
    4543usb_transfer_batch_t * batch_get(
    46     ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
    47     char *setup_buffer, size_t setup_size,
     44    ddf_fun_t *fun,
     45                usb_target_t target,
     46    usb_transfer_type_t transfer_type,
     47                size_t max_packet_size,
     48    usb_speed_t speed,
     49                char *buffer,
     50                size_t size,
     51                char *setup_buffer,
     52                size_t setup_size,
    4853    usbhc_iface_transfer_in_callback_t func_in,
    4954    usbhc_iface_transfer_out_callback_t func_out,
    50     void *arg);
     55                void *arg,
     56                usb_device_keeper_t *manager
     57                );
    5158
    5259void batch_dispose(usb_transfer_batch_t *instance);
    53 
    54 bool batch_is_complete(usb_transfer_batch_t *instance);
    5560
    5661void batch_control_write(usb_transfer_batch_t *instance);
     
    6570
    6671void batch_bulk_out(usb_transfer_batch_t *instance);
    67 
    68 ed_t * batch_ed(usb_transfer_batch_t *instance);
    6972#endif
    7073/**
  • uspace/drv/ohci/hc.c

    ra43f1d18 rf35b294  
    4747static void hc_gain_control(hc_t *instance);
    4848static void hc_init_hw(hc_t *instance);
    49 static int hc_init_transfer_lists(hc_t *instance);
    50 static int hc_init_memory(hc_t *instance);
    5149/*----------------------------------------------------------------------------*/
    5250int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
     
    6159            &instance->manager, hub_address, hub_fun->handle);
    6260
    63         endpoint_t *ep = malloc(sizeof(endpoint_t));
    64         assert(ep);
    65         int ret = endpoint_init(ep, hub_address, 0, USB_DIRECTION_BOTH,
    66             USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64);
    67         assert(ret == EOK);
    68         ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, 0);
    69         assert(ret == EOK);
    70 
    7161        char *match_str = NULL;
    72         ret = asprintf(&match_str, "usb&class=hub");
    73 //      ret = (match_str == NULL) ? ret : EOK;
     62        int ret = asprintf(&match_str, "usb&class=hub");
     63        ret = (match_str == NULL) ? ret : EOK;
    7464        if (ret < 0) {
    75                 usb_log_error(
    76                     "Failed(%d) to create root hub match-id string.\n", ret);
     65                usb_log_error("Failed to create root hub match-id string.\n");
    7766                return ret;
    7867        }
     
    118107        rh_init(&instance->rh, dev, instance->registers);
    119108
    120         hc_init_memory(instance);
    121109        hc_init_hw(instance);
    122110
     
    129117        assert(instance);
    130118        assert(batch);
    131 
    132         /* check for root hub communication */
    133119        if (batch->target.address == instance->rh.address) {
    134120                return rh_request(&instance->rh, batch);
    135121        }
    136 
    137         transfer_list_add_batch(
    138             instance->transfers[batch->transfer_type], batch);
    139 
    140         switch (batch->transfer_type) {
    141         case USB_TRANSFER_CONTROL:
    142                 instance->registers->command_status |= CS_CLF;
    143                 break;
    144         case USB_TRANSFER_BULK:
    145                 instance->registers->command_status |= CS_BLF;
    146                 break;
    147         default:
    148                 break;
    149         }
    150         return EOK;
     122        /* TODO: implement */
     123        return ENOTSUP;
    151124}
    152125/*----------------------------------------------------------------------------*/
     
    161134        usb_log_info("OHCI interrupt: %x.\n", status);
    162135
    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);
    175         }
     136        /* TODO: Check for further interrupt causes */
     137        /* TODO: implement */
    176138}
    177139/*----------------------------------------------------------------------------*/
     
    235197        assert(instance);
    236198        const uint32_t fm_interval = instance->registers->fm_interval;
    237 
    238         /* reset hc */
    239199        instance->registers->command_status = CS_HCR;
    240200        async_usleep(10);
    241 
    242         /* restore fm_interval */
    243201        instance->registers->fm_interval = fm_interval;
    244202        assert((instance->registers->command_status & CS_HCR) == 0);
    245 
    246203        /* hc is now in suspend state */
    247 
    248         /* enable queues */
    249         instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);
     204        /* TODO: init HCCA block */
     205        /* TODO: init queues */
     206        /* TODO: enable queues */
    250207        /* TODO: enable interrupts */
    251         /* set periodic start to 90% */
    252         instance->registers->periodic_start = (fm_interval / 10) * 9;
     208        /* TODO: set periodic start to 90% */
    253209
    254210        instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);
    255211        usb_log_info("OHCI HC up and running.\n");
    256212}
    257 /*----------------------------------------------------------------------------*/
    258 int hc_init_transfer_lists(hc_t *instance)
    259 {
    260         assert(instance);
    261 
    262 #define SETUP_TRANSFER_LIST(type, name) \
    263 do { \
    264         int ret = transfer_list_init(&instance->type, name); \
    265         if (ret != EOK) { \
    266                 usb_log_error("Failed(%d) to setup %s transfer list.\n", \
    267                     ret, name); \
    268                 transfer_list_fini(&instance->transfers_isochronous); \
    269                 transfer_list_fini(&instance->transfers_interrupt); \
    270                 transfer_list_fini(&instance->transfers_control); \
    271                 transfer_list_fini(&instance->transfers_bulk); \
    272         } \
    273 } while (0)
    274 
    275         SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS");
    276         SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT");
    277         SETUP_TRANSFER_LIST(transfers_control, "CONTROL");
    278         SETUP_TRANSFER_LIST(transfers_bulk, "BULK");
    279 
    280         transfer_list_set_next(&instance->transfers_interrupt,
    281             &instance->transfers_isochronous);
    282 
    283         /* Assign pointers to be used during scheduling */
    284         instance->transfers[USB_TRANSFER_INTERRUPT] =
    285           &instance->transfers_interrupt;
    286         instance->transfers[USB_TRANSFER_ISOCHRONOUS] =
    287           &instance->transfers_interrupt;
    288         instance->transfers[USB_TRANSFER_CONTROL] =
    289           &instance->transfers_control;
    290         instance->transfers[USB_TRANSFER_BULK] =
    291           &instance->transfers_bulk;
    292 
    293         return EOK;
    294 #undef CHECK_RET_CLEAR_RETURN
    295 }
    296 /*----------------------------------------------------------------------------*/
    297 int hc_init_memory(hc_t *instance)
    298 {
    299         assert(instance);
    300         /* init queues */
    301         hc_init_transfer_lists(instance);
    302 
    303         /* init HCCA */
    304         instance->hcca = malloc32(sizeof(hcca_t));
    305         if (instance->hcca == NULL)
    306                 return ENOMEM;
    307         bzero(instance->hcca, sizeof(hcca_t));
    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;
    314 
    315         unsigned i = 0;
    316         for (; i < 32; ++i) {
    317                 instance->hcca->int_ep[i] =
    318                     instance->transfers_interrupt.list_head_pa;
    319         }
    320 
    321         return EOK;
    322 }
    323213/**
    324214 * @}
  • uspace/drv/ohci/hc.h

    ra43f1d18 rf35b294  
    4848#include "ohci_regs.h"
    4949#include "root_hub.h"
    50 #include "transfer_list.h"
    5150#include "hw_struct/hcca.h"
    5251
     
    5554        usb_address_t rh_address;
    5655        rh_t rh;
    57 
    58         hcca_t *hcca;
    59 
    60         transfer_list_t transfers_isochronous;
    61         transfer_list_t transfers_interrupt;
    62         transfer_list_t transfers_control;
    63         transfer_list_t transfers_bulk;
    64 
    65         transfer_list_t *transfers[4];
    66 
    6756        ddf_fun_t *ddf_instance;
    6857        usb_device_keeper_t manager;
  • uspace/drv/ohci/hw_struct/completion_codes.h

    ra43f1d18 rf35b294  
    3535#define DRV_OHCI_HW_STRUCT_COMPLETION_CODES_H
    3636
    37 #include <errno.h>
    38 
    3937#define CC_NOERROR (0x0)
    4038#define CC_CRC (0x1)
     
    5250#define CC_NOACCESS2 (0xf)
    5351
    54 inline static int cc_to_rc(int cc)
    55 {
    56         switch (cc) {
    57         case CC_NOERROR:
    58                 return EOK;
    59 
    60         case CC_CRC:
    61                 return EBADCHECKSUM;
    62 
    63         case CC_PIDUNEXPECTED:
    64         case CC_PIDFAIL:
    65         case CC_BITSTUFF:
    66                 return EIO;
    67 
    68         case CC_TOGGLE:
    69         case CC_STALL:
    70                 return ESTALL;
    71 
    72         case CC_NORESPONSE:
    73                 return ETIMEOUT;
    74 
    75         case CC_DATAOVERRRUN:
    76         case CC_DATAUNDERRRUN:
    77         case CC_BUFFEROVERRRUN:
    78         case CC_BUFFERUNDERRUN:
    79                 return EOVERFLOW;
    80 
    81         case CC_NOACCESS1:
    82         case CC_NOACCESS2:
    83         default:
    84                 return ENOTSUP;
    85         }
    86 }
    87 
    8852#endif
    8953/**
  • uspace/drv/ohci/hw_struct/endpoint_descriptor.h

    ra43f1d18 rf35b294  
    3535#define DRV_OHCI_HW_STRUCT_ENDPOINT_DESCRIPTOR_H
    3636
    37 #include <assert.h>
    3837#include <stdint.h>
    39 
    40 #include <usb/host/endpoint.h>
    41 
    42 #include "utils/malloc32.h"
    43 #include "transfer_descriptor.h"
    4438
    4539#include "completion_codes.h"
     
    5044#define ED_STATUS_FA_SHIFT (0)
    5145#define ED_STATUS_EN_MASK (0xf)    /* USB endpoint address */
    52 #define ED_STATUS_EN_SHIFT (7)
     46#define ED_STATUS_EN_SHIFT (6)
    5347#define ED_STATUS_D_MASK (0x3)     /* direction */
    54 #define ED_STATUS_D_SHIFT (11)
     48#define ED_STATUS_D_SHIFT (10)
    5549#define ED_STATUS_D_IN (0x1)
    5650#define ED_STATUS_D_OUT (0x2)
    57 #define ED_STATUS_D_TRANSFER (0x3)
    5851
    59 #define ED_STATUS_S_FLAG (1 << 13) /* speed flag: 1 = low */
     52#define ED_STATUS_S_FLAG (1 << 13) /* speed flag */
    6053#define ED_STATUS_K_FLAG (1 << 14) /* skip flag (no not execute this ED) */
    6154#define ED_STATUS_F_FLAG (1 << 15) /* format: 1 = isochronous*/
     
    7871#define ED_NEXT_PTR_SHIFT (0)
    7972} __attribute__((packed)) ed_t;
    80 
    81 void ed_init(ed_t *instance, endpoint_t *ep);
    82 
    83 static inline void ed_add_tds(ed_t *instance, td_t *head, td_t *tail)
    84 {
    85         assert(instance);
    86         instance->td_head = addr_to_phys(head) & ED_TDHEAD_PTR_MASK;
    87         instance->td_tail = addr_to_phys(tail) & ED_TDTAIL_PTR_MASK;
    88 }
    89 
    90 static inline void ed_append_ed(ed_t *instance, ed_t *next)
    91 {
    92         assert(instance);
    93         assert(next);
    94         uint32_t pa = addr_to_phys(next);
    95         assert((pa & ED_NEXT_PTR_MASK) << ED_NEXT_PTR_SHIFT == pa);
    96         instance->next = pa;
    97 }
    98 
    9973#endif
    10074/**
  • uspace/drv/ohci/hw_struct/transfer_descriptor.h

    ra43f1d18 rf35b294  
    3535#define DRV_OHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H
    3636
    37 #include <bool.h>
    3837#include <stdint.h>
    39 #include "utils/malloc32.h"
    4038
    4139#include "completion_codes.h"
    42 
    43 /* OHCI TDs can handle up to 8KB buffers */
    44 #define OHCI_TD_MAX_TRANSFER (8 * 1024)
    4540
    4641typedef struct td {
     
    5752#define TD_STATUS_T_MASK (0x3)  /* data toggle 1x = use ED toggle carry */
    5853#define TD_STATUS_T_SHIFT (24)
    59 #define TD_STATUS_T_0 (0x2)
    60 #define TD_STATUS_T_1 (0x3)
    6154#define TD_STATUS_EC_MASK (0x3) /* error count */
    6255#define TD_STATUS_EC_SHIFT (26)
     
    7164        volatile uint32_t be; /* buffer end, address of the last byte */
    7265} __attribute__((packed)) td_t;
    73 
    74 void td_init(
    75     td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle);
    76 
    77 inline static void td_set_next(td_t *instance, td_t *next)
    78 {
    79         assert(instance);
    80         instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK;
    81 }
    82 
    83 inline static bool td_is_finished(td_t *instance)
    84 {
    85         assert(instance);
    86         int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;
    87         /* something went wrong, error code is set */
    88         if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2 && cc != CC_NOERROR) {
    89                 return true;
    90         }
    91         /* everything done */
    92         if (cc == CC_NOERROR && instance->cbp == 0) {
    93                 return true;
    94         }
    95         return false;
    96 }
    97 
    98 static inline int td_error(td_t *instance)
    99 {
    100         assert(instance);
    101         int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;
    102         return cc_to_rc(cc);
    103 }
    10466#endif
    10567/**
  • uspace/drv/ohci/iface.c

    ra43f1d18 rf35b294  
    11/*
    2  * Copyright (c) 2011 Vojtech Horky, Jan Vesely
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    3030 */
    3131/** @file
    32  * @brief OHCI driver hc interface implementation
     32 * USB-HC interface implementation.
    3333 */
    3434#include <ddf/driver.h>
     
    3636
    3737#include <usb/debug.h>
    38 #include <usb/host/endpoint.h>
    3938
    4039#include "iface.h"
    4140#include "hc.h"
    4241
    43 static inline int setup_batch(
    44     ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
    45     void *data, size_t size, void * setup_data, size_t setup_size,
    46     usbhc_iface_transfer_in_callback_t in,
    47     usbhc_iface_transfer_out_callback_t out, void *arg, const char* name,
    48     hc_t **hc, usb_transfer_batch_t **batch)
    49 {
    50         assert(hc);
    51         assert(batch);
    52         assert(fun);
    53         *hc = fun_to_hc(fun);
    54         assert(*hc);
    55 
    56         size_t res_bw;
    57         endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager,
    58             target.address, target.endpoint, direction, &res_bw);
    59         if (ep == NULL) {
    60                 usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
    61                     target.address, target.endpoint, name);
    62                 return ENOENT;
    63         }
    64 
    65         const size_t bw = bandwidth_count_usb11(
    66             ep->speed, ep->transfer_type, size, ep->max_packet_size);
    67         if (res_bw < bw) {
    68                 usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    69                     "but only %zu is reserved.\n",
    70                     name, target.address, target.endpoint, bw, res_bw);
    71                 return ENOSPC;
    72         }
    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)
    85                 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.
     42#define UNSUPPORTED(methodname) \
     43        usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \
     44            methodname, __FILE__, __LINE__)
     45
     46/** Reserve default address.
     47 *
     48 * This function may block the caller.
     49 *
     50 * @param[in] fun Device function the action was invoked on.
     51 * @param[in] speed Speed of the device for which the default address is
     52 *      reserved.
    9453 * @return Error code.
    9554 */
     
    10261        usb_device_keeper_reserve_default_address(&hc->manager, speed);
    10362        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.
     63}
     64/*----------------------------------------------------------------------------*/
     65/** Release default address.
     66 *
     67 * @param[in] fun Device function the action was invoked on.
    12868 * @return Error code.
    12969 */
     
    13474        assert(hc);
    13575        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);
    13876        usb_device_keeper_release_default_address(&hc->manager);
    13977        return EOK;
    14078}
    14179/*----------------------------------------------------------------------------*/
    142 /** Request address interface function
    143  *
    144  * @param[in] fun DDF function that was called.
    145  * @param[in] speed Speed to associate with the new default address.
    146  * @param[out] address Place to write a new address.
     80/** Found free USB address.
     81 *
     82 * @param[in] fun Device function the action was invoked on.
     83 * @param[in] speed Speed of the device that will get this address.
     84 * @param[out] address Non-null pointer where to store the free address.
    14785 * @return Error code.
    14886 */
     
    163101}
    164102/*----------------------------------------------------------------------------*/
    165 /** Bind address interface function
    166  *
    167  * @param[in] fun DDF function that was called.
    168  * @param[in] address Address of the device
    169  * @param[in] handle Devman handle of the device driver.
     103/** Bind USB address with device devman handle.
     104 *
     105 * @param[in] fun Device function the action was invoked on.
     106 * @param[in] address USB address of the device.
     107 * @param[in] handle Devman handle of the device.
    170108 * @return Error code.
    171109 */
    172110static int bind_address(
    173   ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     111    ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
    174112{
    175113        assert(fun);
     
    181119}
    182120/*----------------------------------------------------------------------------*/
    183 /** Release address interface function
    184  *
    185  * @param[in] fun DDF function that was called.
     121/** Release previously requested address.
     122 *
     123 * @param[in] fun Device function the action was invoked on.
    186124 * @param[in] address USB address to be released.
    187125 * @return Error code.
     
    201139 * @param[in] fun Device function the action was invoked on.
    202140 * @param[in] address USB address of the device.
    203  * @param[in] ep_speed Endpoint speed (invalid means to use device one).
    204141 * @param[in] endpoint Endpoint number.
    205142 * @param[in] transfer_type USB transfer type.
     
    209146 * @return Error code.
    210147 */
    211 static int register_endpoint(ddf_fun_t *fun,
    212     usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint,
     148static int register_endpoint(
     149    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
    213150    usb_transfer_type_t transfer_type, usb_direction_t direction,
    214151    size_t max_packet_size, unsigned int interval)
    215152{
     153        assert(fun);
    216154        hc_t *hc = fun_to_hc(fun);
    217155        assert(hc);
    218156        if (address == hc->rh.address)
    219157                return EOK;
    220         usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
    221         if (speed >= USB_SPEED_MAX) {
    222                 speed = ep_speed;
    223         }
    224         const size_t size =
    225             (transfer_type == USB_TRANSFER_INTERRUPT
    226             || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
    227             max_packet_size : 0;
    228         int ret;
    229 
    230         endpoint_t *ep = malloc(sizeof(endpoint_t));
    231         if (ep == NULL)
    232                 return ENOMEM;
    233         ret = endpoint_init(ep, address, endpoint, direction,
    234             transfer_type, speed, max_packet_size);
    235         if (ret != EOK) {
    236                 free(ep);
    237                 return ret;
    238         }
    239 
     158        const usb_speed_t speed =
     159                usb_device_keeper_get_speed(&hc->manager, address);
     160        const size_t size = max_packet_size;
    240161        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    241162            address, endpoint, usb_str_transfer_type(transfer_type),
    242163            usb_str_speed(speed), direction, size, max_packet_size, interval);
    243 
    244         ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
    245         if (ret != EOK) {
    246                 endpoint_destroy(ep);
    247         } else {
    248                 usb_device_keeper_add_ep(&hc->manager, address, ep);
    249         }
    250         return ret;
    251 }
    252 /*----------------------------------------------------------------------------*/
     164        // TODO use real endpoint here!
     165        return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0);
     166}
     167/*----------------------------------------------------------------------------*/
     168/** Unregister endpoint (free some bandwidth reservation).
     169 *
     170 * @param[in] fun Device function the action was invoked on.
     171 * @param[in] address USB address of the device.
     172 * @param[in] endpoint Endpoint number.
     173 * @param[in] direction Endpoint data direction.
     174 * @return Error code.
     175 */
    253176static int unregister_endpoint(
    254177    ddf_fun_t *fun, usb_address_t address,
    255178    usb_endpoint_t endpoint, usb_direction_t direction)
    256179{
     180        assert(fun);
    257181        hc_t *hc = fun_to_hc(fun);
    258182        assert(hc);
    259183        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    260184            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         }
    266185        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    267186            endpoint, direction);
     
    277196 * @param[in] fun Device function the action was invoked on.
    278197 * @param[in] target Target pipe (address and endpoint number) specification.
     198 * @param[in] max_packet_size Max packet size for the transfer.
    279199 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    280200 *      by the caller).
     
    285205 */
    286206static int interrupt_out(
    287     ddf_fun_t *fun, usb_target_t target, void *data,
     207    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    288208    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    289209{
    290         usb_transfer_batch_t *batch = NULL;
    291         hc_t *hc = NULL;
    292         int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
    293             NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch);
    294         if (ret != EOK)
    295                 return ret;
     210        assert(fun);
     211        hc_t *hc = fun_to_hc(fun);
     212        assert(hc);
     213        usb_speed_t speed =
     214            usb_device_keeper_get_speed(&hc->manager, target.address);
     215
     216        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
     217            target.address, target.endpoint, size, max_packet_size);
     218
     219        usb_transfer_batch_t *batch =
     220            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     221                speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     222        if (!batch)
     223                return ENOMEM;
    296224        batch_interrupt_out(batch);
    297         ret = hc_schedule(hc, batch);
     225        const int ret = hc_schedule(hc, batch);
    298226        if (ret != EOK) {
    299227                batch_dispose(batch);
     
    311239 * @param[in] fun Device function the action was invoked on.
    312240 * @param[in] target Target pipe (address and endpoint number) specification.
     241 * @param[in] max_packet_size Max packet size for the transfer.
    313242 * @param[in] data Buffer where to store the data (in USB endianess,
    314243 *      allocated and deallocated by the caller).
     
    319248 */
    320249static int interrupt_in(
    321     ddf_fun_t *fun, usb_target_t target, void *data,
     250    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    322251    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    323252{
    324         usb_transfer_batch_t *batch = NULL;
    325         hc_t *hc = NULL;
    326         int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
    327             NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch);
    328         if (ret != EOK)
    329                 return ret;
     253        assert(fun);
     254        hc_t *hc = fun_to_hc(fun);
     255        assert(hc);
     256        usb_speed_t speed =
     257            usb_device_keeper_get_speed(&hc->manager, target.address);
     258        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
     259            target.address, target.endpoint, size, max_packet_size);
     260
     261        usb_transfer_batch_t *batch =
     262            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     263                speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     264        if (!batch)
     265                return ENOMEM;
    330266        batch_interrupt_in(batch);
    331         ret = hc_schedule(hc, batch);
     267        const int ret = hc_schedule(hc, batch);
    332268        if (ret != EOK) {
    333269                batch_dispose(batch);
     
    345281 * @param[in] fun Device function the action was invoked on.
    346282 * @param[in] target Target pipe (address and endpoint number) specification.
     283 * @param[in] max_packet_size Max packet size for the transfer.
    347284 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    348285 *      by the caller).
     
    353290 */
    354291static int bulk_out(
    355     ddf_fun_t *fun, usb_target_t target, void *data,
     292    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    356293    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    357294{
    358         usb_transfer_batch_t *batch = NULL;
    359         hc_t *hc = NULL;
    360         int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
    361             NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch);
    362         if (ret != EOK)
    363                 return ret;
     295        assert(fun);
     296        hc_t *hc = fun_to_hc(fun);
     297        assert(hc);
     298        usb_speed_t speed =
     299            usb_device_keeper_get_speed(&hc->manager, target.address);
     300
     301        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
     302            target.address, target.endpoint, size, max_packet_size);
     303
     304        usb_transfer_batch_t *batch =
     305            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     306                data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     307        if (!batch)
     308                return ENOMEM;
    364309        batch_bulk_out(batch);
    365         ret = hc_schedule(hc, batch);
     310        const int ret = hc_schedule(hc, batch);
    366311        if (ret != EOK) {
    367312                batch_dispose(batch);
     
    379324 * @param[in] fun Device function the action was invoked on.
    380325 * @param[in] target Target pipe (address and endpoint number) specification.
     326 * @param[in] max_packet_size Max packet size for the transfer.
    381327 * @param[in] data Buffer where to store the data (in USB endianess,
    382328 *      allocated and deallocated by the caller).
     
    387333 */
    388334static int bulk_in(
    389     ddf_fun_t *fun, usb_target_t target, void *data,
     335    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    390336    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    391337{
    392         usb_transfer_batch_t *batch = NULL;
    393         hc_t *hc = NULL;
    394         int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
    395             NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch);
    396         if (ret != EOK)
    397                 return ret;
     338        assert(fun);
     339        hc_t *hc = fun_to_hc(fun);
     340        assert(hc);
     341        usb_speed_t speed =
     342            usb_device_keeper_get_speed(&hc->manager, target.address);
     343        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
     344            target.address, target.endpoint, size, max_packet_size);
     345
     346        usb_transfer_batch_t *batch =
     347            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     348                data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     349        if (!batch)
     350                return ENOMEM;
    398351        batch_bulk_in(batch);
    399         ret = hc_schedule(hc, batch);
     352        const int ret = hc_schedule(hc, batch);
    400353        if (ret != EOK) {
    401354                batch_dispose(batch);
     
    413366 * @param[in] fun Device function the action was invoked on.
    414367 * @param[in] target Target pipe (address and endpoint number) specification.
     368 * @param[in] max_packet_size Max packet size for the transfer.
    415369 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    416370 *      and deallocated by the caller).
     
    424378 */
    425379static int control_write(
    426     ddf_fun_t *fun, usb_target_t target,
     380    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    427381    void *setup_data, size_t setup_size, void *data, size_t size,
    428382    usbhc_iface_transfer_out_callback_t callback, void *arg)
    429383{
    430         usb_transfer_batch_t *batch = NULL;
    431         hc_t *hc = NULL;
    432         int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
    433             setup_data, setup_size, NULL, callback, arg, "Control WRITE",
    434             &hc, &batch);
    435         if (ret != EOK)
    436                 return ret;
     384        assert(fun);
     385        hc_t *hc = fun_to_hc(fun);
     386        assert(hc);
     387        usb_speed_t speed =
     388            usb_device_keeper_get_speed(&hc->manager, target.address);
     389        usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
     390            speed, target.address, target.endpoint, size, max_packet_size);
     391
     392        if (setup_size != 8)
     393                return EINVAL;
     394
     395        usb_transfer_batch_t *batch =
     396            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     397                speed, data, size, setup_data, setup_size, NULL, callback, arg,
     398                &hc->manager);
     399        if (!batch)
     400                return ENOMEM;
    437401        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    438402        batch_control_write(batch);
    439         ret = hc_schedule(hc, batch);
     403        const int ret = hc_schedule(hc, batch);
    440404        if (ret != EOK) {
    441405                batch_dispose(batch);
     
    453417 * @param[in] fun Device function the action was invoked on.
    454418 * @param[in] target Target pipe (address and endpoint number) specification.
     419 * @param[in] max_packet_size Max packet size for the transfer.
    455420 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    456421 *      and deallocated by the caller).
     
    464429 */
    465430static int control_read(
    466     ddf_fun_t *fun, usb_target_t target,
     431    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    467432    void *setup_data, size_t setup_size, void *data, size_t size,
    468433    usbhc_iface_transfer_in_callback_t callback, void *arg)
    469434{
    470         usb_transfer_batch_t *batch = NULL;
    471         hc_t *hc = NULL;
    472         int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
    473             setup_data, setup_size, callback, NULL, arg, "Control READ",
    474             &hc, &batch);
    475         if (ret != EOK)
    476                 return ret;
     435        assert(fun);
     436        hc_t *hc = fun_to_hc(fun);
     437        assert(hc);
     438        usb_speed_t speed =
     439            usb_device_keeper_get_speed(&hc->manager, target.address);
     440
     441        usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
     442            speed, target.address, target.endpoint, size, max_packet_size);
     443        usb_transfer_batch_t *batch =
     444            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     445                speed, data, size, setup_data, setup_size, callback, NULL, arg,
     446                &hc->manager);
     447        if (!batch)
     448                return ENOMEM;
    477449        batch_control_read(batch);
    478         ret = hc_schedule(hc, batch);
    479         if (ret != EOK) {
    480                 batch_dispose(batch);
    481         }
    482         return ret;
    483 }
    484 /*----------------------------------------------------------------------------*/
     450        const int ret = hc_schedule(hc, batch);
     451        if (ret != EOK) {
     452                batch_dispose(batch);
     453        }
     454        return ret;
     455}
     456/*----------------------------------------------------------------------------*/
     457/** Host controller interface implementation for OHCI. */
    485458usbhc_iface_t hc_iface = {
    486459        .reserve_default_address = reserve_default_address,
     
    502475        .control_read = control_read,
    503476};
     477
    504478/**
    505479 * @}
  • uspace/drv/ohci/ohci_regs.h

    ra43f1d18 rf35b294  
    4141        const volatile uint32_t revision;
    4242        volatile uint32_t control;
    43 #define C_CSBR_MASK (0x3) /* Control-bulk service ratio */
    44 #define C_CSBR_1_1  (0x0)
    45 #define C_CSBR_1_2  (0x1)
    46 #define C_CSBR_1_3  (0x2)
    47 #define C_CSBR_1_4  (0x3)
     43#define C_CSBR_MASK (0x3)
    4844#define C_CSBR_SHIFT (0)
     45#define C_PLE (1 << 2)
     46#define C_IE (1 << 3)
     47#define C_CLE (1 << 4)
     48#define C_BLE (1 << 5)
    4949
    50 #define C_PLE (1 << 2)   /* Periodic list enable */
    51 #define C_IE  (1 << 3)   /* Isochronous enable */
    52 #define C_CLE (1 << 4)   /* Control list enable */
    53 #define C_BLE (1 << 5)   /* Bulk list enable */
     50#define C_HCFS_MASK (0x3)
     51#define C_HCFS_SHIFT (6)
     52#define C_HCFS_RESET (0x0)
     53#define C_HCFS_OPERATIONAL (0x1)
     54#define C_HCFS_RESUME (0x2)
     55#define C_HCFS_SUSPEND (0x3)
    5456
    55 #define C_HCFS_MASK        (0x3) /* Host controller functional state */
    56 #define C_HCFS_RESET       (0x0)
    57 #define C_HCFS_OPERATIONAL (0x1)
    58 #define C_HCFS_RESUME      (0x2)
    59 #define C_HCFS_SUSPEND     (0x3)
    60 #define C_HCFS_SHIFT       (6)
    61 
    62 #define C_IR  (1 << 8)   /* Interrupt routing, make sure it's 0 */
    63 #define C_RWC (1 << 9)   /* Remote wakeup connected, host specific */
    64 #define C_RWE (1 << 10)  /* Remote wakeup enable */
     57#define C_IR (1 << 8)
     58#define C_RWC (1 << 9)
     59#define C_RWE (1 << 10)
    6560
    6661        volatile uint32_t command_status;
    67 #define CS_HCR (1 << 0)   /* Host controller reset */
    68 #define CS_CLF (1 << 1)   /* Control list filled */
    69 #define CS_BLF (1 << 2)   /* Bulk list filled */
    70 #define CS_OCR (1 << 3)   /* Ownership change request */
    71 #define CS_SOC_MASK (0x3) /* Scheduling overrun count */
     62#define CS_HCR (1 << 0)
     63#define CS_CLF (1 << 1)
     64#define CS_BLF (1 << 2)
     65#define CS_OCR (1 << 3)
     66#define CS_SOC_MASK (0x3)
    7267#define CS_SOC_SHIFT (16)
    7368
    7469        volatile uint32_t interrupt_status;
    75 #define IS_SO   (1 << 0)  /* Scheduling overrun */
    76 #define IS_WDH  (1 << 1)  /* Write-back done head */
    77 #define IS_SF   (1 << 2)  /* Start of frame */
    78 #define IS_RD   (1 << 3)  /* Resume detected */
    79 #define IS_UE   (1 << 4)  /* Unrecoverable error */
    80 #define IS_FNO  (1 << 5)  /* Frame number overflow */
    81 #define IS_RHSC (1 << 6)  /* Root hub status change */
    82 #define IS_OC   (1 << 30) /* Ownership change */
     70#define IS_SO (1 << 0)
     71#define IS_WDH (1 << 1)
     72#define IS_SF (1 << 2)
     73#define IS_RD (1 << 3)
     74#define IS_UE (1 << 4)
     75#define IS_FNO (1 << 5)
     76#define IS_RHSC (1 << 6)
     77#define IS_OC (1 << 30)
    8378
    84         /** Interupt enable/disable, reads give the same value, writing causes
    85          * enable/disable */
    8679        volatile uint32_t interupt_enable;
     80#define IE_SO   (1 << 0)
     81#define IE_WDH  (1 << 1)
     82#define IE_SF   (1 << 2)
     83#define IE_RD   (1 << 3)
     84#define IE_UE   (1 << 4)
     85#define IE_FNO  (1 << 5)
     86#define IE_RHSC (1 << 6)
     87#define IE_OC   (1 << 30)
     88#define IE_MIE  (1 << 31)
     89
    8790        volatile uint32_t interrupt_disable;
    88 #define I_SO   (1 << 0)   /* Scheduling overrun */
    89 #define I_WDH  (1 << 1)   /* Done head write-back */
    90 #define I_SF   (1 << 2)   /* Start of frame */
    91 #define I_RD   (1 << 3)   /* Resume detect */
    92 #define I_UE   (1 << 4)   /* Unrecoverable error */
    93 #define I_FNO  (1 << 5)   /* Frame number overflow */
    94 #define I_RHSC (1 << 6)   /* Root hub status change */
    95 #define I_OC   (1 << 30)  /* Ownership change */
    96 #define I_MI   (1 << 31)  /* Master interrupt (all/any interrupts) */
    97 
    98         /** HCCA pointer (see hw_struct hcca.h) */
    9991        volatile uint32_t hcca;
    100 #define HCCA_PTR_MASK 0xffffff00 /* HCCA is 256B aligned */
    101 
    102         /** Currently executed period endpoint */
    103         const volatile uint32_t period_current;
    104 
    105         /** The first control endpoint */
     92        volatile uint32_t period_corrent;
    10693        volatile uint32_t control_head;
    107 
    108         /** Currently executed control endpoint */
    10994        volatile uint32_t control_current;
    110 
    111         /** The first bulk endpoint */
    11295        volatile uint32_t bulk_head;
    113 
    114         /** Currently executed bulk endpoint */
    11596        volatile uint32_t bulk_current;
    116 
    117         /** Done TD list, this value is periodically written to HCCA */
    118         const volatile uint32_t done_head;
    119 
    120         /** Frame time and max packet size for all transfers */
     97        volatile uint32_t done_head;
    12198        volatile uint32_t fm_interval;
    122 #define FMI_FI_MASK (0x1fff) /* Frame interval in bit times (should be 11999)*/
    123 #define FMI_FI_SHIFT (0)
    124 #define FMI_FSMPS_MASK (0x7fff) /* Full speed max packet size */
    125 #define FMI_FSMPS_SHIFT (16)
    126 #define FMI_TOGGLE_FLAG (1 << 31)
    127 
    128         /** Bit times remaining in current frame */
    129         const volatile uint32_t fm_remaining;
    130 #define FMR_FR_MASK FMI_FI_MASK
    131 #define FMR_FR_SHIFT FMI_FI_SHIFT
    132 #define FMR_TOGGLE_FLAG FMI_TOGGLE_FLAG
    133 
    134         /** Frame number */
    135         const volatile uint32_t fm_number;
    136 #define FMN_NUMBER_MASK (0xffff)
    137 
    138         /** Remaining bit time in frame to start periodic transfers */
     99        volatile uint32_t fm_remaining;
     100        volatile uint32_t fm_number;
    139101        volatile uint32_t periodic_start;
    140 #define PS_PS_MASK (0x1fff) /* bit time when periodic get priority (0x3e67) */
    141 
    142         /** Threshold for starting LS transaction */
    143102        volatile uint32_t ls_threshold;
    144 #define LST_LST_MASK (0x7fff)
    145 
    146         /** The first root hub control register */
    147103        volatile uint32_t rh_desc_a;
    148 #define RHDA_NDS_MASK (0xff) /* Number of downstream ports, max 15 */
    149 #define RHDA_NDS_SHIFT (0)
    150 #define RHDA_PSM_FLAG  (1 << 8)  /* Power switching mode: 0-global, 1-per port*/
    151 #define RHDA_NPS_FLAG  (1 << 9)  /* No power switch: 1-power on, 0-use PSM*/
    152 #define RHDA_DT_FLAG   (1 << 10) /* 1-Compound device, must be 0 */
    153 #define RHDA_OCPM_FLAG (1 << 11) /* Over-current mode: 0-global, 1-per port */
    154 #define RHDA_NOCP      (1 << 12) /* OC control: 0-use OCPM, 1-OC off */
    155 #define RHDA_POTPGT_MASK (0xff)  /* Power on to power good time */
    156 #define RHDA_POTPGT_SHIFT (24)
    157 
    158         /** The other root hub control register */
    159104        volatile uint32_t rh_desc_b;
    160 #define RHDB_DR_MASK (0xffff) /* Device removable mask */
    161 #define RHDB_DR_SHIFT (0)
    162 #define RHDB_PCC_MASK (0xffff) /* Power control mask */
    163 #define RHDB_PCC_SHIFT (16)
    164 
    165 /* Port device removable status */
    166 #define RHDB_DR_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)
    167 /* Port power control status: 1-per port power control, 0-global power switch */
    168 #define RHDB_PPC_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)
    169 
    170         /** Root hub status register */
    171105        volatile uint32_t rh_status;
    172 #define RHS_LPS_FLAG  (1 <<  0)/* read: 0,
    173                                 * write: 0-no effect,
    174                                 *        1-turn off port power for ports
    175                                 *        specified in PPCM(RHDB), or all ports,
    176                                 *        if power is set globally */
    177 #define RHS_CLEAR_PORT_POWER RHS_LPS_FLAG /* synonym for the above */
    178 #define RHS_OCI_FLAG  (1 <<  1)/* Over-current indicator, if per-port: 0 */
    179 #define RHS_DRWE_FLAG (1 << 15)/* read: 0-connect status change does not wake HC
    180                                 *       1-connect status change wakes HC
    181                                 * write: 1-set DRWE, 0-no effect */
    182 #define RHS_SET_DRWE RHS_DRWE_FLAG
    183 #define RHS_LPSC_FLAG (1 << 16)/* read: 0,
    184                                 * write: 0-no effect
    185                                 *        1-turn on port power for ports
    186                                 *        specified in PPCM(RHDB), or all ports,
    187                                 *        if power is set globally */
    188 #define RHS_SET_PORT_POWER RHS_LPSC_FLAG /* synonym for the above */
    189 #define RHS_OCIC_FLAG (1 << 17)/* Over-current indicator change   */
    190 #define RHS_CLEAR_DRWE (1 << 31)
    191 
    192         /** Root hub per port status */
    193106        volatile uint32_t rh_port_status[];
    194 #define RHPS_CCS_FLAG (1 << 0) /* r: current connect status,
    195                                 * w: 1-clear port enable, 0-nothing */
    196 #define RHPS_CLEAR_PORT_ENABLE RHPS_CCS_FLAG
    197 #define RHPS_PES_FLAG (1 << 1) /* r: port enable status
    198                                 * w: 1-set port enable, 0-nothing */
    199 #define RHPS_SET_PORT_ENABLE RHPS_PES_FLAG
    200 #define RHPS_PSS_FLAG (1 << 2) /* r: port suspend status
    201                                 * w: 1-set port suspend, 0-nothing */
    202 #define RHPS_SET_PORT_SUSPEND RHPS_PSS_FLAG
    203 #define RHPS_POCI_FLAG (1 << 3) /* r: port over-current (if reports are per-port
    204                                  * w: 1-clear port suspend (start resume
    205                                  *      if suspened)
    206                                  *    0-nothing */
    207 #define RHPS_CLEAR_PORT_SUSPEND RHPS_POCI_FLAG
    208 #define RHPS_PRS_FLAG (1 << 4) /* r: port reset status
    209                                 * w: 1-set port reset, 0-nothing */
    210 #define RHPS_SET_PORT_RESET RHPS_PRS_FLAG
    211 #define RHPS_PPS_FLAG (1 << 8) /* r: port power status
    212                                 * w: 1-set port power, 0-nothing */
    213 #define RHPS_SET_PORT_POWER RHPS_PPS_FLAG
    214 #define RHPS_LSDA_FLAG (1 << 9) /* r: low speed device attached
    215                                  * w: 1-clear port power, 0-nothing */
    216 #define RHPS_CLEAR_PORT_POWER RHPS_LSDA_FLAG
    217 #define RHPS_CSC_FLAG  (1 << 16) /* connect status change Write-Clean */
    218 #define RHPS_PESC_FLAG (1 << 17) /* port enable status change WC */
    219 #define RHPS_PSSC_FLAG (1 << 18) /* port suspend status change WC */
    220 #define RHPS_OCIC_FLAG (1 << 19) /* port over-current change WC */
    221 #define RHPS_PRSC_FLAG (1 << 20) /* port reset status change WC */
    222 #define RHPS_CHANGE_WC_MASK 0x1f0000
    223107} __attribute__((packed)) ohci_regs_t;
    224108#endif
  • uspace/drv/ohci/utils/malloc32.h

    ra43f1d18 rf35b294  
    3737#include <assert.h>
    3838#include <malloc.h>
    39 #include <errno.h>
    4039#include <mem.h>
    4140#include <as.h>
  • uspace/drv/uhci-hcd/batch.c

    ra43f1d18 rf35b294  
    103103        usb_target_t target =
    104104            { .address = ep->address, .endpoint = ep->endpoint };
    105         usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
    106             ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
    107             func_in, func_out, arg, fun, ep, NULL);
     105        usb_transfer_batch_init(instance, target,
     106            ep->transfer_type, ep->speed, ep->max_packet_size,
     107            buffer, NULL, buffer_size, NULL, setup_size, func_in,
     108            func_out, arg, fun, ep, NULL);
    108109
    109110
    110111        uhci_batch_t *data = malloc(sizeof(uhci_batch_t));
    111         CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
     112        CHECK_NULL_DISPOSE_RETURN(instance,
     113            "Failed to allocate batch instance.\n");
    112114        bzero(data, sizeof(uhci_batch_t));
    113115        instance->private_data = data;
  • uspace/drv/uhci-hcd/hc.c

    ra43f1d18 rf35b294  
    240240        usb_log_debug("Initialized device manager.\n");
    241241
    242         ret = usb_endpoint_manager_init(&instance->ep_manager,
    243             BANDWIDTH_AVAILABLE_USB11);
     242        ret =
     243            usb_endpoint_manager_init(&instance->ep_manager,
     244                BANDWIDTH_AVAILABLE_USB11);
    244245        assert(ret == EOK);
    245246
  • uspace/drv/uhci-hcd/iface.c

    ra43f1d18 rf35b294  
    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));
     76        assert(ep->speed ==
     77            usb_device_keeper_get_speed(&(*hc)->manager, target.address));
    7878//      assert(ep->max_packet_size == max_packet_size);
    7979//      assert(ep->transfer_type == USB_TRANSFER_CONTROL);
     
    198198/*----------------------------------------------------------------------------*/
    199199static int register_endpoint(
    200     ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
    201     usb_endpoint_t endpoint,
     200    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
    202201    usb_transfer_type_t transfer_type, usb_direction_t direction,
    203202    size_t max_packet_size, unsigned int interval)
     
    205204        hc_t *hc = fun_to_hc(fun);
    206205        assert(hc);
    207         usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
    208         if (speed >= USB_SPEED_MAX) {
    209                 speed = ep_speed;
    210         }
     206        const usb_speed_t speed =
     207            usb_device_keeper_get_speed(&hc->manager, address);
    211208        const size_t size =
    212209            (transfer_type == USB_TRANSFER_INTERRUPT
     
    246243        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    247244            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         }
    253245        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    254246            endpoint, direction);
     
    259251 * @param[in] fun DDF function that was called.
    260252 * @param[in] target USB device to write to.
     253 * @param[in] max_packet_size maximum size of data packet the device accepts
    261254 * @param[in] data Source of data.
    262255 * @param[in] size Size of data source.
     
    266259 */
    267260static int interrupt_out(
    268     ddf_fun_t *fun, usb_target_t target, void *data,
     261    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    269262    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    270263{
     
    287280 * @param[in] fun DDF function that was called.
    288281 * @param[in] target USB device to write to.
     282 * @param[in] max_packet_size maximum size of data packet the device accepts
    289283 * @param[out] data Data destination.
    290284 * @param[in] size Size of data source.
     
    294288 */
    295289static int interrupt_in(
    296     ddf_fun_t *fun, usb_target_t target, void *data,
     290    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    297291    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    298292{
     
    315309 * @param[in] fun DDF function that was called.
    316310 * @param[in] target USB device to write to.
     311 * @param[in] max_packet_size maximum size of data packet the device accepts
    317312 * @param[in] data Source of data.
    318313 * @param[in] size Size of data source.
     
    322317 */
    323318static int bulk_out(
    324     ddf_fun_t *fun, usb_target_t target, void *data,
     319    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    325320    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    326321{
     
    343338 * @param[in] fun DDF function that was called.
    344339 * @param[in] target USB device to write to.
     340 * @param[in] max_packet_size maximum size of data packet the device accepts
    345341 * @param[out] data Data destination.
    346342 * @param[in] size Size of data source.
     
    350346 */
    351347static int bulk_in(
    352     ddf_fun_t *fun, usb_target_t target, void *data,
     348    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    353349    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    354350{
     
    371367 * @param[in] fun DDF function that was called.
    372368 * @param[in] target USB device to write to.
     369 * @param[in] max_packet_size maximum size of data packet the device accepts.
    373370 * @param[in] setup_data Data to send with SETUP transfer.
    374371 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
     
    380377 */
    381378static int control_write(
    382     ddf_fun_t *fun, usb_target_t target,
     379    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    383380    void *setup_data, size_t setup_size, void *data, size_t size,
    384381    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    404401 * @param[in] fun DDF function that was called.
    405402 * @param[in] target USB device to write to.
     403 * @param[in] max_packet_size maximum size of data packet the device accepts.
    406404 * @param[in] setup_data Data to send with SETUP packet.
    407405 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     
    413411 */
    414412static int control_read(
    415     ddf_fun_t *fun, usb_target_t target,
     413    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    416414    void *setup_data, size_t setup_size, void *data, size_t size,
    417415    usbhc_iface_transfer_in_callback_t callback, void *arg)
  • uspace/drv/usbmid/main.c

    ra43f1d18 rf35b294  
    5555        int rc;
    5656
    57         rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe);
     57        rc = usb_pipe_start_session(&dev->ctrl_pipe);
    5858        if (rc != EOK) {
    59                 usb_log_error("Failed to start transfer on control pipe: %s.\n",
     59                usb_log_error("Failed to start session on control pipe: %s.\n",
    6060                    str_error(rc));
    6161                return rc;
     
    6464        bool accept = usbmid_explore_device(dev);
    6565
    66         usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     66        rc = usb_pipe_end_session(&dev->ctrl_pipe);
     67        if (rc != EOK) {
     68                usb_log_warning("Failed to end session on control pipe: %s.\n",
     69                    str_error(rc));
     70        }
    6771
    6872        if (!accept) {
  • uspace/drv/vhc/connhost.c

    ra43f1d18 rf35b294  
    257257
    258258static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
     259    size_t max_packet_size,
    259260    void *data, size_t size,
    260261    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    266267
    267268static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
     269    size_t max_packet_size,
    268270    void *data, size_t size,
    269271    usbhc_iface_transfer_in_callback_t callback, void *arg)
     
    275277
    276278static int control_write(ddf_fun_t *fun, usb_target_t target,
     279    size_t max_packet_size,
    277280    void *setup_packet, size_t setup_packet_size,
    278281    void *data, size_t data_size,
     
    292295
    293296static int control_read(ddf_fun_t *fun, usb_target_t target,
     297    size_t max_packet_size,
    294298    void *setup_packet, size_t setup_packet_size,
    295299    void *data, size_t data_size,
  • uspace/lib/drv/generic/remote_usbhc.c

    ra43f1d18 rf35b294  
    270270        }
    271271
     272        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    272273        usb_target_t target = {
    273274                .address = DEV_IPC_GET_ARG1(*call),
     
    299300        trans->size = len;
    300301
    301         rc = transfer_func(fun, target,
     302        rc = transfer_func(fun, target, max_packet_size,
    302303            buffer, len,
    303304            callback_out, trans);
     
    325326        }
    326327
     328        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    327329        usb_target_t target = {
    328330                .address = DEV_IPC_GET_ARG1(*call),
     
    346348        trans->size = len;
    347349
    348         int rc = transfer_func(fun, target,
     350        int rc = transfer_func(fun, target, max_packet_size,
    349351            trans->buffer, len,
    350352            callback_in, trans);
     
    412414        };
    413415        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
     416        size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
    414417
    415418        int rc;
     
    447450        trans->size = data_buffer_len;
    448451
    449         rc = usb_iface->control_write(fun, target,
     452        rc = usb_iface->control_write(fun, target, max_packet_size,
    450453            setup_packet, setup_packet_len,
    451454            data_buffer, data_buffer_len,
     
    474477                .endpoint = DEV_IPC_GET_ARG2(*call)
    475478        };
     479        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    476480
    477481        int rc;
     
    511515        }
    512516
    513         rc = usb_iface->control_read(fun, target,
     517        rc = usb_iface->control_read(fun, target, max_packet_size,
    514518            setup_packet, setup_packet_len,
    515519            trans->buffer, trans->size,
     
    533537        }
    534538
    535 #define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
    536         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16)
    537 #define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
    538         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 16)
    539 #define _INIT_FROM_HIGH_DATA3(type, var, arg_no) \
    540         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16)
    541 #define _INIT_FROM_MIDDLE_DATA3(type, var, arg_no) \
    542         type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) / (1 << 8)) % (1 << 8)
    543 #define _INIT_FROM_LOW_DATA3(type, var, arg_no) \
    544         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 8)
    545 
    546         _INIT_FROM_HIGH_DATA2(usb_address_t, address, 1);
    547         _INIT_FROM_LOW_DATA2(usb_endpoint_t, endpoint, 1);
    548 
    549         _INIT_FROM_HIGH_DATA3(usb_speed_t, speed, 2);
    550         _INIT_FROM_MIDDLE_DATA3(usb_transfer_type_t, transfer_type, 2);
    551         _INIT_FROM_LOW_DATA3(usb_direction_t, direction, 2);
    552 
    553         _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
    554         _INIT_FROM_LOW_DATA2(unsigned int, interval, 3);
    555 
    556 #undef _INIT_FROM_HIGH_DATA2
    557 #undef _INIT_FROM_LOW_DATA2
    558 #undef _INIT_FROM_HIGH_DATA3
    559 #undef _INIT_FROM_MIDDLE_DATA3
    560 #undef _INIT_FROM_LOW_DATA3
    561 
    562         int rc = usb_iface->register_endpoint(fun, address, speed, endpoint,
     539#define INIT_FROM_HIGH_DATA(type, var, arg_no) \
     540        type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / 256
     541#define INIT_FROM_LOW_DATA(type, var, arg_no) \
     542        type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % 256
     543
     544        INIT_FROM_HIGH_DATA(usb_address_t, address, 1);
     545        INIT_FROM_LOW_DATA(usb_endpoint_t, endpoint, 1);
     546        INIT_FROM_HIGH_DATA(usb_transfer_type_t, transfer_type, 2);
     547        INIT_FROM_LOW_DATA(usb_direction_t, direction, 2);
     548
     549#undef INIT_FROM_HIGH_DATA
     550#undef INIT_FROM_LOW_DATA
     551
     552        size_t max_packet_size = (size_t) DEV_IPC_GET_ARG3(*call);
     553        unsigned int interval  = (unsigned int) DEV_IPC_GET_ARG4(*call);
     554
     555        int rc = usb_iface->register_endpoint(fun, address, endpoint,
    563556            transfer_type, direction, max_packet_size, interval);
    564557
  • uspace/lib/drv/include/usbhc_iface.h

    ra43f1d18 rf35b294  
    6666 *   - argument #1 is target address
    6767 *   - argument #2 is target endpoint
     68 *   - argument #3 is max packet size of the endpoint
    6869 * - this call is immediately followed by IPC data read (async version)
    6970 * - the call is not answered until the device returns some data (or until
     
    168169        /** Register endpoint attributes at host controller.
    169170         * This is used to reserve portion of USB bandwidth.
    170          * When speed is invalid, speed of the device is used.
    171171         * Parameters:
    172          * - USB address + endpoint number
    173          *   - packed as ADDR << 16 + EP
    174          * - speed + transfer type + direction
    175          *   - packed as ( SPEED << 8 + TYPE ) << 8 + DIR
    176          * - maximum packet size + interval (in milliseconds)
    177          *   - packed as MPS << 16 + INT
     172         * - USB address + endpoint number (ADDR * 256 + EP)
     173         * - transfer type + direction (TYPE * 256 + DIR)
     174         * - maximum packet size
     175         * - interval (in milliseconds)
    178176         * Answer:
    179177         * - EOK - reservation successful
     
    204202
    205203/** Out transfer processing function prototype. */
    206 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t,
     204typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, size_t,
    207205    void *, size_t,
    208206    usbhc_iface_transfer_out_callback_t, void *);
     
    212210
    213211/** In transfer processing function prototype. */
    214 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t,
     212typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, size_t,
    215213    void *, size_t,
    216214    usbhc_iface_transfer_in_callback_t, void *);
     
    224222        int (*release_address)(ddf_fun_t *, usb_address_t);
    225223
    226         int (*register_endpoint)(ddf_fun_t *,
    227             usb_address_t, usb_speed_t, usb_endpoint_t,
     224        int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
    228225            usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
    229226        int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
     
    237234
    238235        int (*control_write)(ddf_fun_t *, usb_target_t,
     236            size_t,
    239237            void *, size_t, void *, size_t,
    240238            usbhc_iface_transfer_out_callback_t, void *);
    241239
    242240        int (*control_read)(ddf_fun_t *, usb_target_t,
     241            size_t,
    243242            void *, size_t, void *, size_t,
    244243            usbhc_iface_transfer_in_callback_t, void *);
  • uspace/lib/usb/Makefile

    ra43f1d18 rf35b294  
    4343        src/hidparser.c \
    4444        src/hub.c \
    45         src/pipepriv.c \
    4645        src/pipes.c \
    4746        src/pipesinit.c \
  • uspace/lib/usb/include/usb/devdrv.h

    ra43f1d18 rf35b294  
    169169    usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
    170170
    171 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
    172 int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
    173     usb_endpoint_description_t **, uint8_t *, size_t, int, int,
    174     usb_endpoint_mapping_t **, size_t *);
    175 int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
    176 
    177 size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
    178 
    179171#endif
    180172/**
  • uspace/lib/usb/include/usb/host/device_keeper.h

    ra43f1d18 rf35b294  
    7373void usb_device_keeper_add_ep(
    7474    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);
    7775
    7876void usb_device_keeper_reserve_default_address(
  • uspace/lib/usb/include/usb/pipes.h

    ra43f1d18 rf35b294  
    4242#include <ipc/devman.h>
    4343#include <ddf/driver.h>
    44 #include <fibril_synch.h>
    4544
    4645/** Abstraction of a physical connection to the device.
     
    6059 * This endpoint must be bound with existing usb_device_connection_t
    6160 * (i.e. the wire to send data over).
    62  *
    63  * Locking order: if you want to lock both mutexes
    64  * (@c guard and @c hc_phone_mutex), lock @c guard first.
    65  * It is not necessary to lock @c guard if you want to lock @c hc_phone_mutex
    66  * only.
    6761 */
    6862typedef struct {
    69         /** Guard of the whole pipe. */
    70         fibril_mutex_t guard;
    71 
    7263        /** The connection used for sending the data. */
    7364        usb_device_connection_t *wire;
     
    8778        /** Phone to the host controller.
    8879         * Negative when no session is active.
    89          * It is an error to access this member without @c hc_phone_mutex
    90          * being locked.
    91          * If call over the phone is to be made, it must be preceeded by
    92          * call to pipe_add_ref() [internal libusb function].
    9380         */
    9481        int hc_phone;
    95 
    96         /** Guard for serialization of requests over the phone. */
    97         fibril_mutex_t hc_phone_mutex;
    98 
    99         /** Number of active transfers over the pipe. */
    100         int refcount;
    10182} usb_pipe_t;
    10283
     
    153134int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
    154135    size_t, uint8_t *, size_t, usb_device_connection_t *);
    155 int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t,
    156     unsigned int, usb_hc_connection_t *);
    157136int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *);
    158137int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *);
     
    161140int usb_pipe_end_session(usb_pipe_t *);
    162141bool usb_pipe_is_session_started(usb_pipe_t *);
    163 
    164 int usb_pipe_start_long_transfer(usb_pipe_t *);
    165 void usb_pipe_end_long_transfer(usb_pipe_t *);
    166142
    167143int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *);
  • uspace/lib/usb/include/usb/usb.h

    ra43f1d18 rf35b294  
    7777        USB_SPEED_FULL,
    7878        /** USB 2.0 high speed (480Mbits/s). */
    79         USB_SPEED_HIGH,
    80         /** Psuedo-speed serving as a boundary. */
    81         USB_SPEED_MAX
     79        USB_SPEED_HIGH
    8280} usb_speed_t;
    8381
  • uspace/lib/usb/src/devdrv.c

    ra43f1d18 rf35b294  
    7272}
    7373
     74/** Log out of memory error on given device.
     75 *
     76 * @param dev Device causing the trouble.
     77 */
     78static void usb_log_oom(ddf_dev_t *dev)
     79{
     80        usb_log_error("Out of memory when adding device `%s'.\n",
     81            dev->name);
     82}
     83
    7484/** Count number of pipes the driver expects.
    7585 *
     
    98108 */
    99109static int initialize_other_pipes(usb_endpoint_description_t **endpoints,
    100     usb_device_t *dev, int alternate_setting)
    101 {
    102         usb_endpoint_mapping_t *pipes;
    103         size_t pipes_count;
    104 
    105         int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints,
     110    usb_device_t *dev)
     111{
     112        int rc;
     113
     114        size_t pipe_count = count_other_pipes(endpoints);
     115        if (pipe_count == 0) {
     116                return EOK;
     117        }
     118
     119        dev->pipes = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
     120        if (dev->pipes == NULL) {
     121                usb_log_oom(dev->ddf_dev);
     122                return ENOMEM;
     123        }
     124
     125        size_t i;
     126
     127        /* Initialize to NULL first for rollback purposes. */
     128        for (i = 0; i < pipe_count; i++) {
     129                dev->pipes[i].pipe = NULL;
     130        }
     131
     132        for (i = 0; i < pipe_count; i++) {
     133                dev->pipes[i].pipe = malloc(sizeof(usb_pipe_t));
     134                if (dev->pipes[i].pipe == NULL) {
     135                        usb_log_oom(dev->ddf_dev);
     136                        rc = ENOMEM;
     137                        goto rollback;
     138                }
     139
     140                dev->pipes[i].description = endpoints[i];
     141                dev->pipes[i].interface_no = dev->interface_no;
     142                dev->pipes[i].interface_setting = 0;
     143        }
     144
     145        rc = usb_pipe_initialize_from_configuration(dev->pipes, pipe_count,
    106146            dev->descriptors.configuration, dev->descriptors.configuration_size,
    107             dev->interface_no, alternate_setting,
    108             &pipes, &pipes_count);
    109 
     147            &dev->wire);
     148        if (rc != EOK) {
     149                usb_log_error("Failed initializing USB endpoints: %s.\n",
     150                    str_error(rc));
     151                goto rollback;
     152        }
     153
     154        /* Register the endpoints. */
     155        usb_hc_connection_t hc_conn;
     156        rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev);
    110157        if (rc != EOK) {
    111158                usb_log_error(
    112                     "Failed to create endpoint pipes for `%s': %s.\n",
    113                     dev->ddf_dev->name, str_error(rc));
    114                 return rc;
    115         }
    116 
    117         dev->pipes = pipes;
    118         dev->pipes_count = pipes_count;
     159                    "Failed initializing connection to host controller: %s.\n",
     160                    str_error(rc));
     161                goto rollback;
     162        }
     163        rc = usb_hc_connection_open(&hc_conn);
     164        if (rc != EOK) {
     165                usb_log_error("Failed to connect to host controller: %s.\n",
     166                    str_error(rc));
     167                goto rollback;
     168        }
     169        for (i = 0; i < pipe_count; i++) {
     170                if (dev->pipes[i].present) {
     171                        rc = usb_pipe_register(dev->pipes[i].pipe,
     172                            dev->pipes[i].descriptor->poll_interval,
     173                            &hc_conn);
     174                        /* Ignore error when operation not supported by HC. */
     175                        if ((rc != EOK) && (rc != ENOTSUP)) {
     176                                /* FIXME: what shall we do? */
     177                                dev->pipes[i].present = false;
     178                                free(dev->pipes[i].pipe);
     179                                dev->pipes[i].pipe = NULL;
     180                        }
     181                }
     182        }
     183        /* Ignoring errors here. */
     184        usb_hc_connection_close(&hc_conn);
     185
     186        dev->pipes_count = pipe_count;
    119187
    120188        return EOK;
     189
     190rollback:
     191        for (i = 0; i < pipe_count; i++) {
     192                if (dev->pipes[i].pipe != NULL) {
     193                        free(dev->pipes[i].pipe);
     194                }
     195        }
     196        free(dev->pipes);
     197
     198        return rc;
    121199}
    122200
     
    161239
    162240        /*
    163          * We will do some querying of the device, it is worth to prepare
    164          * the long transfer.
     241         * For further actions, we need open session on default control pipe.
    165242         */
    166         rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe);
    167         if (rc != EOK) {
    168                 usb_log_error("Failed to start transfer: %s.\n",
     243        rc = usb_pipe_start_session(&dev->ctrl_pipe);
     244        if (rc != EOK) {
     245                usb_log_error("Failed to start an IPC session: %s.\n",
    169246                    str_error(rc));
    170247                return rc;
    171248        }
    172249
    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",
     250        /* Get the device descriptor. */
     251        rc = usb_request_get_device_descriptor(&dev->ctrl_pipe,
     252            &dev->descriptors.device);
     253        if (rc != EOK) {
     254                usb_log_error("Failed to retrieve device descriptor: %s.\n",
     255                    str_error(rc));
     256                return rc;
     257        }
     258
     259        /* Get the full configuration descriptor. */
     260        rc = usb_request_get_full_configuration_descriptor_alloc(
     261            &dev->ctrl_pipe, 0, (void **) &dev->descriptors.configuration,
     262            &dev->descriptors.configuration_size);
     263        if (rc != EOK) {
     264                usb_log_error("Failed retrieving configuration descriptor: %s. %s\n",
    179265                    dev->ddf_dev->name, str_error(rc));
    180266                return rc;
    181267        }
    182268
    183 
    184269        if (driver->endpoints != NULL) {
    185                 rc = initialize_other_pipes(driver->endpoints, dev, 0);
    186         }
    187 
    188         usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     270                rc = initialize_other_pipes(driver->endpoints, dev);
     271        }
     272
     273        /* No checking here. */
     274        usb_pipe_end_session(&dev->ctrl_pipe);
    189275
    190276        /* Rollback actions. */
     
    205291 * @return Number of alternate interfaces for @p interface_no interface.
    206292 */
    207 size_t usb_interface_count_alternates(uint8_t *config_descr,
    208     size_t config_descr_size, uint8_t interface_no)
     293static size_t count_alternate_interfaces(uint8_t *config_descr,
     294    size_t config_descr_size, int interface_no)
    209295{
    210296        assert(config_descr != NULL);
    211         assert(config_descr_size > 0);
    212 
    213297        usb_dp_parser_t dp_parser = {
    214298                .nesting = usb_dp_standard_descriptor_nesting
     
    259343
    260344        alternates->alternative_count
    261             = usb_interface_count_alternates(dev->descriptors.configuration,
     345            = count_alternate_interfaces(dev->descriptors.configuration,
    262346            dev->descriptors.configuration_size, dev->interface_no);
    263347
     
    373457static int destroy_current_pipes(usb_device_t *dev)
    374458{
    375         int rc = usb_device_destroy_pipes(dev->ddf_dev,
    376             dev->pipes, dev->pipes_count);
    377         if (rc != EOK) {
    378                 return rc;
    379         }
    380 
     459        size_t i;
     460        int rc;
     461
     462        /* TODO: this shall be done under some device mutex. */
     463
     464        /* First check that no session is opened. */
     465        for (i = 0; i < dev->pipes_count; i++) {
     466                if (usb_pipe_is_session_started(dev->pipes[i].pipe)) {
     467                        return EBUSY;
     468                }
     469        }
     470
     471        /* Prepare connection to HC. */
     472        usb_hc_connection_t hc_conn;
     473        rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev);
     474        if (rc != EOK) {
     475                return rc;
     476        }
     477        rc = usb_hc_connection_open(&hc_conn);
     478        if (rc != EOK) {
     479                return rc;
     480        }
     481
     482        /* Destroy the pipes. */
     483        for (i = 0; i < dev->pipes_count; i++) {
     484                usb_pipe_unregister(dev->pipes[i].pipe, &hc_conn);
     485                free(dev->pipes[i].pipe);
     486        }
     487
     488        usb_hc_connection_close(&hc_conn);
     489
     490        free(dev->pipes);
    381491        dev->pipes = NULL;
    382492        dev->pipes_count = 0;
     
    425535
    426536        /* Create new pipes. */
    427         rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting);
     537        rc = initialize_other_pipes(endpoints, dev);
    428538
    429539        return rc;
    430 }
    431 
    432 /** Retrieve basic descriptors from the device.
    433  *
    434  * @param[in] ctrl_pipe Control pipe with opened session.
    435  * @param[out] descriptors Where to store the descriptors.
    436  * @return Error code.
    437  */
    438 int usb_device_retrieve_descriptors(usb_pipe_t *ctrl_pipe,
    439     usb_device_descriptors_t *descriptors)
    440 {
    441         assert(descriptors != NULL);
    442         assert(usb_pipe_is_session_started(ctrl_pipe));
    443 
    444         descriptors->configuration = NULL;
    445 
    446         int rc;
    447 
    448         /* Get the device descriptor. */
    449         rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
    450         if (rc != EOK) {
    451                 return rc;
    452         }
    453 
    454         /* Get the full configuration descriptor. */
    455         rc = usb_request_get_full_configuration_descriptor_alloc(
    456             ctrl_pipe, 0, (void **) &descriptors->configuration,
    457             &descriptors->configuration_size);
    458         if (rc != EOK) {
    459                 return rc;
    460         }
    461 
    462         return EOK;
    463 }
    464 
    465 /** Create pipes for a device.
    466  *
    467  * This is more or less a wrapper that does following actions:
    468  * - allocate and initialize pipes
    469  * - map endpoints to the pipes based on the descriptions
    470  * - registers endpoints with the host controller
    471  *
    472  * @param[in] dev Generic DDF device backing the USB one.
    473  * @param[in] wire Initialized backing connection to the host controller.
    474  * @param[in] endpoints Endpoints description, NULL terminated.
    475  * @param[in] config_descr Configuration descriptor of active configuration.
    476  * @param[in] config_descr_size Size of @p config_descr in bytes.
    477  * @param[in] interface_no Interface to map from.
    478  * @param[in] interface_setting Interface setting (default is usually 0).
    479  * @param[out] pipes_ptr Where to store array of created pipes
    480  *      (not NULL terminated).
    481  * @param[out] pipes_count_ptr Where to store number of pipes
    482  *      (set to if you wish to ignore the count).
    483  * @return Error code.
    484  */
    485 int usb_device_create_pipes(ddf_dev_t *dev, usb_device_connection_t *wire,
    486     usb_endpoint_description_t **endpoints,
    487     uint8_t *config_descr, size_t config_descr_size,
    488     int interface_no, int interface_setting,
    489     usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
    490 {
    491         assert(dev != NULL);
    492         assert(wire != NULL);
    493         assert(endpoints != NULL);
    494         assert(config_descr != NULL);
    495         assert(config_descr_size > 0);
    496         assert(pipes_ptr != NULL);
    497 
    498         size_t i;
    499         int rc;
    500 
    501         size_t pipe_count = count_other_pipes(endpoints);
    502         if (pipe_count == 0) {
    503                 *pipes_ptr = NULL;
    504                 return EOK;
    505         }
    506 
    507         usb_endpoint_mapping_t *pipes
    508             = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
    509         if (pipes == NULL) {
    510                 return ENOMEM;
    511         }
    512 
    513         /* Initialize to NULL to allow smooth rollback. */
    514         for (i = 0; i < pipe_count; i++) {
    515                 pipes[i].pipe = NULL;
    516         }
    517 
    518         /* Now allocate and fully initialize. */
    519         for (i = 0; i < pipe_count; i++) {
    520                 pipes[i].pipe = malloc(sizeof(usb_pipe_t));
    521                 if (pipes[i].pipe == NULL) {
    522                         rc = ENOMEM;
    523                         goto rollback_free_only;
    524                 }
    525                 pipes[i].description = endpoints[i];
    526                 pipes[i].interface_no = interface_no;
    527                 pipes[i].interface_setting = interface_setting;
    528         }
    529 
    530         /* Find the mapping from configuration descriptor. */
    531         rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
    532             config_descr, config_descr_size, wire);
    533         if (rc != EOK) {
    534                 goto rollback_free_only;
    535         }
    536 
    537         /* Register the endpoints with HC. */
    538         usb_hc_connection_t hc_conn;
    539         rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
    540         if (rc != EOK) {
    541                 goto rollback_free_only;
    542         }
    543 
    544         rc = usb_hc_connection_open(&hc_conn);
    545         if (rc != EOK) {
    546                 goto rollback_free_only;
    547         }
    548 
    549         for (i = 0; i < pipe_count; i++) {
    550                 if (pipes[i].present) {
    551                         rc = usb_pipe_register(pipes[i].pipe,
    552                             pipes[i].descriptor->poll_interval, &hc_conn);
    553                         if (rc != EOK) {
    554                                 goto rollback_unregister_endpoints;
    555                         }
    556                 }
    557         }
    558 
    559         usb_hc_connection_close(&hc_conn);
    560 
    561         *pipes_ptr = pipes;
    562         if (pipes_count_ptr != NULL) {
    563                 *pipes_count_ptr = pipe_count;
    564         }
    565 
    566         return EOK;
    567 
    568         /*
    569          * Jump here if something went wrong after endpoints have
    570          * been registered.
    571          * This is also the target when the registration of
    572          * endpoints fails.
    573          */
    574 rollback_unregister_endpoints:
    575         for (i = 0; i < pipe_count; i++) {
    576                 if (pipes[i].present) {
    577                         usb_pipe_unregister(pipes[i].pipe, &hc_conn);
    578                 }
    579         }
    580 
    581         usb_hc_connection_close(&hc_conn);
    582 
    583         /*
    584          * Jump here if something went wrong before some actual communication
    585          * with HC. Then the only thing that needs to be done is to free
    586          * allocated memory.
    587          */
    588 rollback_free_only:
    589         for (i = 0; i < pipe_count; i++) {
    590                 if (pipes[i].pipe != NULL) {
    591                         free(pipes[i].pipe);
    592                 }
    593         }
    594         free(pipes);
    595 
    596         return rc;
    597 }
    598 
    599 /** Destroy pipes previously created by usb_device_create_pipes.
    600  *
    601  * @param[in] dev Generic DDF device backing the USB one.
    602  * @param[in] pipes Endpoint mapping to be destroyed.
    603  * @param[in] pipes_count Number of endpoints.
    604  */
    605 int usb_device_destroy_pipes(ddf_dev_t *dev,
    606     usb_endpoint_mapping_t *pipes, size_t pipes_count)
    607 {
    608         assert(dev != NULL);
    609         assert(((pipes != NULL) && (pipes_count > 0))
    610             || ((pipes == NULL) && (pipes_count == 0)));
    611 
    612         if (pipes_count == 0) {
    613                 return EOK;
    614         }
    615 
    616         int rc;
    617 
    618         /* Prepare connection to HC to allow endpoint unregistering. */
    619         usb_hc_connection_t hc_conn;
    620         rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
    621         if (rc != EOK) {
    622                 return rc;
    623         }
    624         rc = usb_hc_connection_open(&hc_conn);
    625         if (rc != EOK) {
    626                 return rc;
    627         }
    628 
    629         /* Destroy the pipes. */
    630         size_t i;
    631         for (i = 0; i < pipes_count; i++) {
    632                 usb_pipe_unregister(pipes[i].pipe, &hc_conn);
    633                 free(pipes[i].pipe);
    634         }
    635 
    636         usb_hc_connection_close(&hc_conn);
    637 
    638         free(pipes);
    639 
    640         return EOK;
    641540}
    642541
  • uspace/lib/usb/src/devpoll.c

    ra43f1d18 rf35b294  
    7777                int rc;
    7878
     79                rc = usb_pipe_start_session(pipe);
     80                if (rc != EOK) {
     81                        failed_attempts++;
     82                        continue;
     83                }
     84
    7985                size_t actual_size;
    8086                rc = usb_pipe_read(pipe, polling_data->buffer,
    8187                    polling_data->request_size, &actual_size);
    8288
     89                /* Quit the session regardless of errors. */
     90                usb_pipe_end_session(pipe);
    8391               
    8492//              if (rc == ESTALL) {
  • uspace/lib/usb/src/host/batch.c

    ra43f1d18 rf35b294  
    6363        instance->transfer_type = transfer_type;
    6464        instance->speed = speed;
    65         instance->direction = ep->direction;
     65        instance->direction = USB_DIRECTION_BOTH;
    6666        instance->callback_in = func_in;
    6767        instance->callback_out = func_out;
  • uspace/lib/usb/src/host/device_keeper.c

    ra43f1d18 rf35b294  
    5656                instance->devices[i].control_used = 0;
    5757                instance->devices[i].handle = 0;
    58                 instance->devices[i].speed = USB_SPEED_MAX;
    5958                list_initialize(&instance->devices[i].endpoints);
    6059        }
    61         // TODO: is this hack enough?
    62         // (it is needed to allow smooth registration at default address)
    63         instance->devices[0].occupied = true;
    6460}
    6561/*----------------------------------------------------------------------------*/
     
    7167        assert(instance->devices[address].occupied);
    7268        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);
    8469        fibril_mutex_unlock(&instance->guard);
    8570}
  • uspace/lib/usb/src/hub.c

    ra43f1d18 rf35b294  
    4040#include <errno.h>
    4141#include <assert.h>
    42 #include <usb/debug.h>
    4342
    4443/** Check that HC connection is alright.
     
    5655
    5756/** Tell host controller to reserve default address.
    58  * @deprecated
    5957 *
    6058 * @param connection Opened connection to host controller.
     
    6765        CHECK_CONNECTION(connection);
    6866
    69         usb_log_warning("usb_hc_reserve_default_address() considered obsolete");
    70 
    7167        return async_req_2_0(connection->hc_phone,
    7268            DEV_IFACE_ID(USBHC_DEV_IFACE),
     
    7571
    7672/** Tell host controller to release default address.
    77  * @deprecated
    7873 *
    7974 * @param connection Opened connection to host controller.
     
    8378{
    8479        CHECK_CONNECTION(connection);
    85 
    86         usb_log_warning("usb_hc_release_default_address() considered obsolete");
    8780
    8881        return async_req_1_0(connection->hc_phone,
     
    242235        }
    243236
    244         /*
    245          * We will not register control pipe on default address.
    246          * The registration might fail. That means that someone else already
    247          * registered that endpoint. We will simply wait and try again.
    248          * (Someone else already wants to add a new device.)
     237
     238        /*
     239         * Reserve the default address.
     240         */
     241        rc = usb_hc_reserve_default_address(&hc_conn, dev_speed);
     242        if (rc != EOK) {
     243                rc = EBUSY;
     244                goto leave_release_free_address;
     245        }
     246
     247        /*
     248         * Enable the port (i.e. allow signaling through this port).
     249         */
     250        rc = enable_port(port_no, arg);
     251        if (rc != EOK) {
     252                goto leave_release_default_address;
     253        }
     254
     255        /*
     256         * Change the address from default to the free one.
     257         * We need to create a new control pipe for that.
    249258         */
    250259        usb_device_connection_t dev_conn;
     
    253262        if (rc != EOK) {
    254263                rc = ENOTCONN;
    255                 goto leave_release_free_address;
     264                goto leave_release_default_address;
    256265        }
    257266
     
    261270        if (rc != EOK) {
    262271                rc = ENOTCONN;
    263                 goto leave_release_free_address;
    264         }
    265 
    266         do {
    267                 rc = usb_pipe_register_with_speed(&ctrl_pipe, dev_speed, 0,
    268                     &hc_conn);
    269                 if (rc != EOK) {
    270                         /* Do not overheat the CPU ;-). */
    271                         async_usleep(10);
    272                 }
    273         } while (rc != EOK);
    274 
    275         /*
    276          * Endpoint is registered. We can enable the port and change
    277          * device address.
    278          */
    279         rc = enable_port(port_no, arg);
    280         if (rc != EOK) {
    281                 goto leave_release_default_address;
    282         }
    283 
     272                goto leave_release_default_address;
     273        }
     274
     275        /* Before sending any traffic, we need to register this
     276         * endpoint.
     277         */
     278        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
     279        if (rc != EOK) {
     280                rc = EREFUSED;
     281                goto leave_release_default_address;
     282        }
    284283        rc = usb_pipe_probe_default_control(&ctrl_pipe);
    285284        if (rc != EOK) {
     285                rc = ENOTCONN;
     286                goto leave_release_default_address;
     287        }
     288
     289        rc = usb_pipe_start_session(&ctrl_pipe);
     290        if (rc != EOK) {
     291                rc = ENOTCONN;
     292                goto leave_unregister_endpoint;
     293        }
     294
     295        rc = usb_request_set_address(&ctrl_pipe, dev_addr);
     296        if (rc != EOK) {
    286297                rc = ESTALL;
    287                 goto leave_release_default_address;
    288         }
    289 
    290         rc = usb_request_set_address(&ctrl_pipe, dev_addr);
    291         if (rc != EOK) {
    292                 rc = ESTALL;
    293                 goto leave_release_default_address;
    294         }
    295 
    296         /*
    297          * Address changed. We can release the original endpoint, thus
    298          * allowing other to access the default address.
     298                goto leave_stop_session;
     299        }
     300
     301        usb_pipe_end_session(&ctrl_pipe);
     302
     303        /*
     304         * Register the control endpoint for the new device.
     305         */
     306        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
     307        if (rc != EOK) {
     308                rc = EREFUSED;
     309                goto leave_unregister_endpoint;
     310        }
     311
     312        /*
     313         * Release the original endpoint.
    299314         */
    300315        unregister_control_endpoint_on_default_address(&hc_conn);
    301316
    302317        /*
    303          * Time to register the new endpoint.
    304          */
    305         rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    306         if (rc != EOK) {
    307                 goto leave_release_free_address;
    308         }
     318         * Once the address is changed, we can return the default address.
     319         */
     320        usb_hc_release_default_address(&hc_conn);
     321
    309322
    310323        /*
     
    321334        }
    322335
     336
     337
    323338        /*
    324339         * And now inform the host controller about the handle.
     
    352367         * Completely ignoring errors here.
    353368         */
     369
     370leave_stop_session:
     371        usb_pipe_end_session(&ctrl_pipe);
     372
     373leave_unregister_endpoint:
     374        usb_pipe_unregister(&ctrl_pipe, &hc_conn);
     375
    354376leave_release_default_address:
    355         usb_pipe_unregister(&ctrl_pipe, &hc_conn);
     377        usb_hc_release_default_address(&hc_conn);
    356378
    357379leave_release_free_address:
  • uspace/lib/usb/src/pipes.c

    ra43f1d18 rf35b294  
    4141#include <errno.h>
    4242#include <assert.h>
    43 #include "pipepriv.h"
    4443
    4544#define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
     
    242241 * necessary.
    243242 *
    244  * @deprecated
    245  * Obsoleted with introduction of usb_pipe_start_long_transfer
    246  *
    247243 * @param pipe Endpoint pipe to start the session on.
    248244 * @return Error code.
     
    250246int usb_pipe_start_session(usb_pipe_t *pipe)
    251247{
    252         usb_log_warning("usb_pipe_start_session() was deprecated.\n");
     248        assert(pipe);
     249
     250        if (usb_pipe_is_session_started(pipe)) {
     251                return EBUSY;
     252        }
     253
     254        int phone = devman_device_connect(pipe->wire->hc_handle, 0);
     255        if (phone < 0) {
     256                return phone;
     257        }
     258
     259        pipe->hc_phone = phone;
     260
    253261        return EOK;
    254262}
     
    257265/** Ends a session on the endpoint pipe.
    258266 *
    259  * @deprecated
    260  * Obsoleted with introduction of usb_pipe_end_long_transfer
    261  *
    262267 * @see usb_pipe_start_session
    263268 *
     
    267272int usb_pipe_end_session(usb_pipe_t *pipe)
    268273{
    269         usb_log_warning("usb_pipe_end_session() was deprecated.\n");
     274        assert(pipe);
     275
     276        if (!usb_pipe_is_session_started(pipe)) {
     277                return ENOENT;
     278        }
     279
     280        int rc = async_hangup(pipe->hc_phone);
     281        if (rc != EOK) {
     282                return rc;
     283        }
     284
     285        pipe->hc_phone = -1;
     286
    270287        return EOK;
    271288}
     
    281298bool usb_pipe_is_session_started(usb_pipe_t *pipe)
    282299{
    283         pipe_acquire(pipe);
    284         bool started = pipe->refcount > 0;
    285         pipe_release(pipe);
    286         return started;
    287 }
    288 
    289 /** Prepare pipe for a long transfer.
    290  *
    291  * By a long transfer is mean transfer consisting of several
    292  * requests to the HC.
    293  * Calling such function is optional and it has positive effect of
    294  * improved performance because IPC session is initiated only once.
    295  *
    296  * @param pipe Pipe over which the transfer will happen.
    297  * @return Error code.
    298  */
    299 int usb_pipe_start_long_transfer(usb_pipe_t *pipe)
    300 {
    301         return pipe_add_ref(pipe);
    302 }
    303 
    304 /** Terminate a long transfer on a pipe.
    305  *
    306  * @see usb_pipe_start_long_transfer
    307  *
    308  * @param pipe Pipe where to end the long transfer.
    309  */
    310 void usb_pipe_end_long_transfer(usb_pipe_t *pipe)
    311 {
    312         pipe_drop_ref(pipe);
     300        return (pipe->hc_phone >= 0);
    313301}
    314302
  • uspace/lib/usb/src/pipesinit.c

    ra43f1d18 rf35b294  
    356356        assert(connection);
    357357
    358         fibril_mutex_initialize(&pipe->guard);
    359358        pipe->wire = connection;
    360359        pipe->hc_phone = -1;
    361         fibril_mutex_initialize(&pipe->hc_phone_mutex);
    362360        pipe->endpoint_no = endpoint_no;
    363361        pipe->transfer_type = transfer_type;
    364362        pipe->max_packet_size = max_packet_size;
    365363        pipe->direction = direction;
    366         pipe->refcount = 0;
    367364
    368365        return EOK;
     
    416413        int rc;
    417414
    418         rc = usb_pipe_start_long_transfer(pipe);
     415        TRY_LOOP(failed_attempts) {
     416                rc = usb_pipe_start_session(pipe);
     417                if (rc == EOK) {
     418                        break;
     419                }
     420        }
    419421        if (rc != EOK) {
    420422                return rc;
     
    437439                }
    438440        }
    439         usb_pipe_end_long_transfer(pipe);
     441        usb_pipe_end_session(pipe);
    440442        if (rc != EOK) {
    441443                return rc;
     
    459461    usb_hc_connection_t *hc_connection)
    460462{
    461         return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1,
    462             interval, hc_connection);
    463 }
    464 
    465 /** Register endpoint with a speed at the host controller.
    466  *
    467  * You will rarely need to use this function because it is needed only
    468  * if the registered endpoint is of address 0 and there is no other way
    469  * to tell speed of the device at address 0.
    470  *
    471  * @param pipe Pipe to be registered.
    472  * @param speed Speed of the device
    473  *      (invalid speed means use previously specified one).
    474  * @param interval Polling interval.
    475  * @param hc_connection Connection to the host controller (must be opened).
    476  * @return Error code.
    477  */
    478 int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed,
    479     unsigned int interval,
    480     usb_hc_connection_t *hc_connection)
    481 {
    482463        assert(pipe);
    483464        assert(hc_connection);
     
    487468        }
    488469
    489 #define _PACK2(high, low) (((high) << 16) + (low))
    490 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))
    491 
    492         return async_req_4_0(hc_connection->hc_phone,
     470#define _PACK(high, low) ((high) * 256 + (low))
     471
     472        return async_req_5_0(hc_connection->hc_phone,
    493473            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
    494             _PACK2(pipe->wire->address, pipe->endpoint_no),
    495             _PACK3(speed, pipe->transfer_type, pipe->direction),
    496             _PACK2(pipe->max_packet_size, interval));
    497 
    498 #undef _PACK2
    499 #undef _PACK3
     474            _PACK(pipe->wire->address, pipe->endpoint_no),
     475            _PACK(pipe->transfer_type, pipe->direction),
     476            pipe->max_packet_size, interval);
     477
     478#undef _PACK
    500479}
    501480
  • uspace/lib/usb/src/pipesio.c

    ra43f1d18 rf35b294  
    4949#include <assert.h>
    5050#include <usbhc_iface.h>
    51 #include "pipepriv.h"
    5251
    5352/** Request an in transfer, no checking of input parameters.
     
    7978        }
    8079
    81         /* Ensure serialization over the phone. */
    82         pipe_start_transaction(pipe);
    83 
    8480        /*
    8581         * Make call identifying target USB device and type of transfer.
    8682         */
    87         aid_t opening_request = async_send_3(pipe->hc_phone,
     83        aid_t opening_request = async_send_4(pipe->hc_phone,
    8884            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    8985            pipe->wire->address, pipe->endpoint_no,
     86            pipe->max_packet_size,
    9087            NULL);
    9188        if (opening_request == 0) {
    92                 pipe_end_transaction(pipe);
    9389                return ENOMEM;
    9490        }
     
    10096        aid_t data_request = async_data_read(pipe->hc_phone, buffer, size,
    10197            &data_request_call);
    102 
    103         /*
    104          * Since now on, someone else might access the backing phone
    105          * without breaking the transfer IPC protocol.
    106          */
    107         pipe_end_transaction(pipe);
    10898
    10999        if (data_request == 0) {
     
    156146
    157147        if (buffer == NULL) {
    158                 return EINVAL;
     148                        return EINVAL;
    159149        }
    160150
     
    163153        }
    164154
     155        if (!usb_pipe_is_session_started(pipe)) {
     156                return EBADF;
     157        }
     158
    165159        if (pipe->direction != USB_DIRECTION_IN) {
    166160                return EBADF;
     
    171165        }
    172166
     167        size_t act_size = 0;
    173168        int rc;
    174         rc = pipe_add_ref(pipe);
    175         if (rc != EOK) {
    176                 return rc;
    177         }
    178 
    179 
    180         size_t act_size = 0;
    181169
    182170        rc = usb_pipe_read_no_checks(pipe, buffer, size, &act_size);
    183 
    184         pipe_drop_ref(pipe);
    185 
    186171        if (rc != EOK) {
    187172                return rc;
     
    225210        }
    226211
    227         /* Ensure serialization over the phone. */
    228         pipe_start_transaction(pipe);
    229 
    230212        /*
    231213         * Make call identifying target USB device and type of transfer.
    232214         */
    233         aid_t opening_request = async_send_3(pipe->hc_phone,
     215        aid_t opening_request = async_send_4(pipe->hc_phone,
    234216            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    235217            pipe->wire->address, pipe->endpoint_no,
     218            pipe->max_packet_size,
    236219            NULL);
    237220        if (opening_request == 0) {
    238                 pipe_end_transaction(pipe);
    239221                return ENOMEM;
    240222        }
     
    244226         */
    245227        int rc = async_data_write_start(pipe->hc_phone, buffer, size);
    246 
    247         /*
    248          * Since now on, someone else might access the backing phone
    249          * without breaking the transfer IPC protocol.
    250          */
    251         pipe_end_transaction(pipe);
    252 
    253228        if (rc != EOK) {
    254229                async_wait_for(opening_request, NULL);
     
    285260        }
    286261
     262        if (!usb_pipe_is_session_started(pipe)) {
     263                return EBADF;
     264        }
     265
    287266        if (pipe->direction != USB_DIRECTION_OUT) {
    288267                return EBADF;
     
    293272        }
    294273
    295         int rc;
    296 
    297         rc = pipe_add_ref(pipe);
    298         if (rc != EOK) {
    299                 return rc;
    300         }
    301 
    302         rc = usb_pipe_write_no_check(pipe, buffer, size);
    303 
    304         pipe_drop_ref(pipe);
     274        int rc = usb_pipe_write_no_check(pipe, buffer, size);
    305275
    306276        return rc;
     
    323293    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
    324294{
    325         /* Ensure serialization over the phone. */
    326         pipe_start_transaction(pipe);
    327 
    328295        /*
    329296         * Make call identifying target USB device and control transfer type.
    330297         */
    331         aid_t opening_request = async_send_3(pipe->hc_phone,
     298        aid_t opening_request = async_send_4(pipe->hc_phone,
    332299            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
    333300            pipe->wire->address, pipe->endpoint_no,
     301            pipe->max_packet_size,
    334302            NULL);
    335303        if (opening_request == 0) {
     
    343311            setup_buffer, setup_buffer_size);
    344312        if (rc != EOK) {
    345                 pipe_end_transaction(pipe);
    346313                async_wait_for(opening_request, NULL);
    347314                return rc;
     
    355322            data_buffer, data_buffer_size,
    356323            &data_request_call);
    357 
    358         /*
    359          * Since now on, someone else might access the backing phone
    360          * without breaking the transfer IPC protocol.
    361          */
    362         pipe_end_transaction(pipe);
    363 
    364 
    365324        if (data_request == 0) {
    366325                async_wait_for(opening_request, NULL);
     
    420379        }
    421380
     381        if (!usb_pipe_is_session_started(pipe)) {
     382                return EBADF;
     383        }
     384
    422385        if ((pipe->direction != USB_DIRECTION_BOTH)
    423386            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     
    425388        }
    426389
    427         int rc;
    428 
    429         rc = pipe_add_ref(pipe);
    430         if (rc != EOK) {
    431                 return rc;
    432         }
    433 
    434390        size_t act_size = 0;
    435         rc = usb_pipe_control_read_no_check(pipe,
     391        int rc = usb_pipe_control_read_no_check(pipe,
    436392            setup_buffer, setup_buffer_size,
    437393            data_buffer, data_buffer_size, &act_size);
    438 
    439         pipe_drop_ref(pipe);
    440394
    441395        if (rc != EOK) {
     
    464418    void *data_buffer, size_t data_buffer_size)
    465419{
    466         /* Ensure serialization over the phone. */
    467         pipe_start_transaction(pipe);
    468 
    469420        /*
    470421         * Make call identifying target USB device and control transfer type.
    471422         */
    472         aid_t opening_request = async_send_4(pipe->hc_phone,
     423        aid_t opening_request = async_send_5(pipe->hc_phone,
    473424            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
    474425            pipe->wire->address, pipe->endpoint_no,
    475426            data_buffer_size,
     427            pipe->max_packet_size,
    476428            NULL);
    477429        if (opening_request == 0) {
    478                 pipe_end_transaction(pipe);
    479430                return ENOMEM;
    480431        }
     
    486437            setup_buffer, setup_buffer_size);
    487438        if (rc != EOK) {
    488                 pipe_end_transaction(pipe);
    489439                async_wait_for(opening_request, NULL);
    490440                return rc;
     
    497447                rc = async_data_write_start(pipe->hc_phone,
    498448                    data_buffer, data_buffer_size);
    499 
    500                 /* All data sent, pipe can be released. */
    501                 pipe_end_transaction(pipe);
    502 
    503449                if (rc != EOK) {
    504450                        async_wait_for(opening_request, NULL);
    505451                        return rc;
    506452                }
    507         } else {
    508                 /* No data to send, we can release the pipe for others. */
    509                 pipe_end_transaction(pipe);
    510453        }
    511454
     
    548491        }
    549492
     493        if (!usb_pipe_is_session_started(pipe)) {
     494                return EBADF;
     495        }
     496
    550497        if ((pipe->direction != USB_DIRECTION_BOTH)
    551498            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     
    553500        }
    554501
    555         int rc;
    556 
    557         rc = pipe_add_ref(pipe);
    558         if (rc != EOK) {
    559                 return rc;
    560         }
    561 
    562         rc = usb_pipe_control_write_no_check(pipe,
     502        int rc = usb_pipe_control_write_no_check(pipe,
    563503            setup_buffer, setup_buffer_size, data_buffer, data_buffer_size);
    564 
    565         pipe_drop_ref(pipe);
    566504
    567505        return rc;
  • uspace/lib/usb/src/recognise.c

    ra43f1d18 rf35b294  
    404404        child->driver_data = dev_data;
    405405
     406        rc = usb_pipe_start_session(&ctrl_pipe);
     407        if (rc != EOK) {
     408                goto failure;
     409        }
     410
    406411        rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
     412        if (rc != EOK) {
     413                goto failure;
     414        }
     415
     416        rc = usb_pipe_end_session(&ctrl_pipe);
    407417        if (rc != EOK) {
    408418                goto failure;
Note: See TracChangeset for help on using the changeset viewer.