Changes in / [4deca9b:1324ff3] in mainline


Ignore:
Location:
uspace
Files:
12 edited

Legend:

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

    r4deca9b r1324ff3  
    7373        CHECK_NULL_DISPOSE_RETURN(instance,
    7474            "Failed to allocate batch instance.\n");
    75         usb_transfer_batch_init(instance, ep, buffer, NULL, buffer_size,
    76             NULL, setup_size, func_in, func_out, arg, fun, NULL);
     75        usb_target_t target =
     76            { .address = ep->address, .endpoint = ep->endpoint };
     77        usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
     78            ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
     79            func_in, func_out, arg, fun, ep, NULL);
    7780
    7881        ohci_batch_t *data = malloc(sizeof(ohci_batch_t));
     
    98101
    99102        if (buffer_size > 0) {
    100                 instance->data_buffer = malloc32(buffer_size);
    101                 CHECK_NULL_DISPOSE_RETURN(instance->data_buffer,
     103                instance->transport_buffer = malloc32(buffer_size);
     104                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
    102105                    "Failed to allocate device accessible buffer.\n");
    103106        }
     
    121124        free32(data->tds);
    122125        free32(instance->setup_buffer);
    123         free32(instance->data_buffer);
     126        free32(instance->transport_buffer);
    124127        free(data);
    125128        free(instance);
     
    162165        assert(instance);
    163166        /* We are data out, we are supposed to provide data */
    164         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
     167        memcpy(instance->transport_buffer, instance->buffer,
     168            instance->buffer_size);
    165169        instance->next_step = batch_call_out_and_dispose;
    166170        batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN);
     
    179183{
    180184        assert(instance);
     185        assert(instance->direction == USB_DIRECTION_IN);
    181186        instance->next_step = batch_call_in_and_dispose;
    182187        batch_data(instance);
     
    187192{
    188193        assert(instance);
     194        assert(instance->direction == USB_DIRECTION_OUT);
    189195        /* We are data out, we are supposed to provide data */
    190         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
     196        memcpy(instance->transport_buffer, instance->buffer,
     197            instance->buffer_size);
    191198        instance->next_step = batch_call_out_and_dispose;
    192199        batch_data(instance);
     
    197204{
    198205        assert(instance);
     206        instance->direction = USB_DIRECTION_IN;
    199207        instance->next_step = batch_call_in_and_dispose;
    200208        batch_data(instance);
     
    205213{
    206214        assert(instance);
     215        instance->direction = USB_DIRECTION_IN;
    207216        instance->next_step = batch_call_in_and_dispose;
    208217        batch_data(instance);
     
    240249        size_t td_current = 1;
    241250        size_t remain_size = instance->buffer_size;
    242         char *buffer = instance->data_buffer;
     251        char *transfer_buffer = instance->transport_buffer;
    243252        while (remain_size > 0) {
    244253                size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
     
    246255                toggle = 1 - toggle;
    247256
    248                 td_init(&data->tds[td_current], data_dir, buffer,
     257                td_init(&data->tds[td_current], data_dir, transfer_buffer,
    249258                    transfer_size, toggle);
    250259                td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);
     
    253262                    data->tds[td_current].next, data->tds[td_current].be);
    254263
    255                 buffer += transfer_size;
     264                transfer_buffer += transfer_size;
    256265                remain_size -= transfer_size;
    257266                assert(td_current < data->td_count - 2);
     
    281290        size_t td_current = 0;
    282291        size_t remain_size = instance->buffer_size;
    283         char *buffer = instance->data_buffer;
     292        char *transfer_buffer = instance->transport_buffer;
    284293        while (remain_size > 0) {
    285294                size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
     
    287296
    288297                td_init(&data->tds[td_current], instance->ep->direction,
    289                     buffer, transfer_size, -1);
     298                    transfer_buffer, transfer_size, -1);
    290299                td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);
    291300                usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",
     
    293302                    data->tds[td_current].next, data->tds[td_current].be);
    294303
    295                 buffer += transfer_size;
     304                transfer_buffer += transfer_size;
    296305                remain_size -= transfer_size;
    297306                assert(td_current < data->td_count);
  • uspace/drv/ohci/hc.c

    r4deca9b r1324ff3  
    5555        assert(hub_fun);
    5656
    57         int ret;
    58 
    5957        usb_address_t hub_address =
    6058            device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);
    61         if (hub_address <= 0) {
    62                 usb_log_error("Failed to get OHCI root hub address.\n");
    63                 return hub_address;
    64         }
    6559        instance->rh.address = hub_address;
    6660        usb_device_keeper_bind(
    6761            &instance->manager, hub_address, hub_fun->handle);
    6862
    69         ret = usb_endpoint_manager_add_ep(&instance->ep_manager,
    70             hub_address, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    71             USB_SPEED_FULL, 64, 0);
    72         if (ret != EOK) {
    73                 usb_log_error("Failed to add OHCI rh endpoint 0.\n");
    74                 usb_device_keeper_release(&instance->manager, hub_address);
    75                 return ret;
    76         }
     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);
    7770
    7871        char *match_str = NULL;
    79         /* DDF needs heap allocated string */
    8072        ret = asprintf(&match_str, "usb&class=hub");
     73//      ret = (match_str == NULL) ? ret : EOK;
    8174        if (ret < 0) {
    8275                usb_log_error(
    8376                    "Failed(%d) to create root hub match-id string.\n", ret);
    84                 usb_device_keeper_release(&instance->manager, hub_address);
    8577                return ret;
    8678        }
     
    8880        ret = ddf_fun_add_match_id(hub_fun, match_str, 100);
    8981        if (ret != EOK) {
    90                 usb_log_error("Failed add root hub match-id.\n");
     82                usb_log_error("Failed add create root hub match-id.\n");
    9183        }
    9284        return ret;
     
    123115        fibril_mutex_initialize(&instance->guard);
    124116
    125         rh_init(&instance->rh, instance->registers);
     117        rh_init(&instance->rh, dev, instance->registers);
    126118
    127119        if (!interrupts) {
     
    138130        assert(instance);
    139131        assert(batch);
    140         assert(batch->ep);
    141132
    142133        /* check for root hub communication */
    143         if (batch->ep->address == instance->rh.address) {
     134        if (batch->target.address == instance->rh.address) {
    144135                return rh_request(&instance->rh, batch);
    145136        }
    146137
    147138        fibril_mutex_lock(&instance->guard);
    148         switch (batch->ep->transfer_type) {
     139        switch (batch->transfer_type) {
    149140        case USB_TRANSFER_CONTROL:
    150141                instance->registers->control &= ~C_CLE;
    151142                transfer_list_add_batch(
    152                     instance->transfers[batch->ep->transfer_type], batch);
     143                    instance->transfers[batch->transfer_type], batch);
    153144                instance->registers->command_status |= CS_CLF;
    154145                usb_log_debug2("Set CS control transfer filled: %x.\n",
     
    160151                instance->registers->control &= ~C_BLE;
    161152                transfer_list_add_batch(
    162                     instance->transfers[batch->ep->transfer_type], batch);
     153                    instance->transfers[batch->transfer_type], batch);
    163154                instance->registers->command_status |= CS_BLF;
    164155                usb_log_debug2("Set bulk transfer filled: %x.\n",
     
    170161                instance->registers->control &= (~C_PLE & ~C_IE);
    171162                transfer_list_add_batch(
    172                     instance->transfers[batch->ep->transfer_type], batch);
     163                    instance->transfers[batch->transfer_type], batch);
    173164                instance->registers->control |= C_PLE | C_IE;
    174165                usb_log_debug2("Added periodic transfer: %x.\n",
  • uspace/drv/ohci/root_hub.c

    r4deca9b r1324ff3  
    205205 * @return Error code.
    206206 */
    207 int rh_init(rh_t *instance, ohci_regs_t *regs) {
     207int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs) {
    208208        assert(instance);
     209        //instance->address = -1;
    209210        instance->registers = regs;
     211        instance->device = dev;
    210212        instance->port_count =
    211213            (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;
    212214        rh_init_descriptors(instance);
    213215        // set port power mode to no-power-switching
    214         instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
     216        instance->registers->rh_desc_a =
     217                instance->registers->rh_desc_a | (1<<9);
    215218
    216219        usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
     220
     221        //start generic usb hub driver
     222
     223        /* TODO: implement */
    217224        return EOK;
    218225}
     
    230237        assert(request);
    231238        int opResult;
    232         if (request->ep->transfer_type == USB_TRANSFER_CONTROL) {
     239        if (request->transfer_type == USB_TRANSFER_CONTROL) {
    233240                usb_log_info("Root hub got CONTROL packet\n");
    234241                opResult = process_ctrl_request(instance, request);
    235         } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) {
     242        } else if (request->transfer_type == USB_TRANSFER_INTERRUPT) {
    236243                usb_log_info("Root hub got INTERRUPT packet\n");
    237244                void * buffer;
    238245                create_interrupt_mask(instance, &buffer,
    239246                        &(request->transfered_size));
    240                 memcpy(request->data_buffer, buffer,
     247                memcpy(request->transport_buffer, buffer,
    241248                        request->transfered_size);
    242249                opResult = EOK;
     
    367374        if (port < 1 || port > instance->port_count)
    368375                return EINVAL;
    369         uint32_t * uint32_buffer = (uint32_t*) request->data_buffer;
     376        uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer;
    370377        request->transfered_size = 4;
    371378        uint32_buffer[0] = instance->registers->rh_port_status[port - 1];
     
    393400static int process_get_hub_status_request(rh_t *instance,
    394401        usb_transfer_batch_t * request) {
    395         uint32_t * uint32_buffer = (uint32_t*) request->data_buffer;
     402        uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer;
    396403        request->transfered_size = 4;
    397404        //bits, 0,1,16,17
     
    543550        }
    544551        request->transfered_size = size;
    545         memcpy(request->data_buffer, result_descriptor, size);
     552        memcpy(request->transport_buffer, result_descriptor, size);
    546553        if (del)
    547554                free(result_descriptor);
     
    564571        if (request->buffer_size != 1)
    565572                return EINVAL;
    566         request->data_buffer[0] = 1;
     573        request->transport_buffer[0] = 1;
    567574        request->transfered_size = 1;
    568575        return EOK;
  • uspace/drv/ohci/root_hub.h

    r4deca9b r1324ff3  
    5050        /** usb address of the root hub */
    5151        usb_address_t address;
     52        /** ddf device information */
     53        ddf_dev_t *device;
    5254        /** hub port count */
    5355        int port_count;
     
    5658} rh_t;
    5759
    58 int rh_init(rh_t *instance, ohci_regs_t *regs);
     60int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs);
    5961
    6062int rh_request(rh_t *instance, usb_transfer_batch_t *request);
  • uspace/drv/uhci-hcd/batch.c

    r4deca9b r1324ff3  
    3030 */
    3131/** @file
    32  * @brief UHCI driver USB transfer structure
     32 * @brief UHCI driver USB transaction structure
    3333 */
    3434#include <errno.h>
     
    4848        qh_t *qh;
    4949        td_t *tds;
    50         size_t td_count;
     50        size_t transfers;
    5151} uhci_batch_t;
    5252
     
    6161 *
    6262 * @param[in] fun DDF function to pass to callback.
    63  * @param[in] ep Communication target
     63 * @param[in] target Device and endpoint target of the transaction.
     64 * @param[in] transfer_type Interrupt, Control or Bulk.
     65 * @param[in] max_packet_size maximum allowed size of data transfers.
     66 * @param[in] speed Speed of the transaction.
    6467 * @param[in] buffer Data source/destination.
    6568 * @param[in] size Size of the buffer.
    6669 * @param[in] setup_buffer Setup data source (if not NULL)
    6770 * @param[in] setup_size Size of setup_buffer (should be always 8)
    68  * @param[in] func_in function to call on inbound transfer completion
    69  * @param[in] func_out function to call on outbound transfer completion
     71 * @param[in] func_in function to call on inbound transaction completion
     72 * @param[in] func_out function to call on outbound transaction completion
    7073 * @param[in] arg additional parameter to func_in or func_out
     74 * @param[in] ep Pointer to endpoint toggle management structure.
    7175 * @return Valid pointer if all substructures were successfully created,
    7276 * NULL otherwise.
    7377 *
    74  * Determines the number of needed transfer descriptors (TDs).
    75  * Prepares a transport buffer (that is accessible by the hardware).
    76  * Initializes parameters needed for the transfer and callback.
     78 * Determines the number of needed transfers (TDs). Prepares a transport buffer
     79 * (that is accessible by the hardware). Initializes parameters needed for the
     80 * transaction and callback.
    7781 */
    7882usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
     
    99103        usb_target_t target =
    100104            { .address = ep->address, .endpoint = ep->endpoint };
    101         usb_transfer_batch_init(instance, ep,
    102             buffer, NULL, buffer_size, NULL, setup_size,
    103             func_in, func_out, arg, fun, NULL);
     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);
    104108
    105109
     
    109113        instance->private_data = data;
    110114
    111         data->td_count =
     115        data->transfers =
    112116            (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size;
    113117        if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    114                 data->td_count += 2;
    115         }
    116 
    117         data->tds = malloc32(sizeof(td_t) * data->td_count);
     118                data->transfers += 2;
     119        }
     120
     121        data->tds = malloc32(sizeof(td_t) * data->transfers);
    118122        CHECK_NULL_DISPOSE_RETURN(
    119123            data->tds, "Failed to allocate transfer descriptors.\n");
    120         bzero(data->tds, sizeof(td_t) * data->td_count);
     124        bzero(data->tds, sizeof(td_t) * data->transfers);
    121125
    122126        data->qh = malloc32(sizeof(qh_t));
     
    127131
    128132        if (buffer_size > 0) {
    129                 instance->data_buffer = malloc32(buffer_size);
    130                 CHECK_NULL_DISPOSE_RETURN(instance->data_buffer,
     133                instance->transport_buffer = malloc32(buffer_size);
     134                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
    131135                    "Failed to allocate device accessible buffer.\n");
    132136        }
     
    150154 *
    151155 * Walk all TDs. Stop with false if there is an active one (it is to be
    152  * processed). Stop with true if an error is found. Return true if the last TD
     156 * processed). Stop with true if an error is found. Return true if the last TS
    153157 * is reached.
    154158 */
     
    160164
    161165        usb_log_debug2("Batch(%p) checking %d transfer(s) for completion.\n",
    162             instance, data->td_count);
     166            instance, data->transfers);
    163167        instance->transfered_size = 0;
    164168        size_t i = 0;
    165         for (;i < data->td_count; ++i) {
     169        for (;i < data->transfers; ++i) {
    166170                if (td_is_active(&data->tds[i])) {
    167171                        return false;
     
    173177                            instance, i, data->tds[i].status);
    174178                        td_print_status(&data->tds[i]);
    175 
    176179                        assert(instance->ep != NULL);
     180
    177181                        endpoint_toggle_set(instance->ep,
    178182                            td_toggle(&data->tds[i]));
     
    191195}
    192196/*----------------------------------------------------------------------------*/
    193 /** Prepares control write transfer.
    194  *
    195  * @param[in] instance Batch structure to use.
    196  *
    197  * Uses generic control function with pids OUT and IN.
     197/** Prepares control write transaction.
     198 *
     199 * @param[in] instance Batch structure to use.
     200 *
     201 * Uses genercir control function with pids OUT and IN.
    198202 */
    199203void batch_control_write(usb_transfer_batch_t *instance)
     
    201205        assert(instance);
    202206        /* We are data out, we are supposed to provide data */
    203         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
     207        memcpy(instance->transport_buffer, instance->buffer,
     208            instance->buffer_size);
    204209        batch_control(instance, USB_PID_OUT, USB_PID_IN);
    205210        instance->next_step = batch_call_out_and_dispose;
     
    207212}
    208213/*----------------------------------------------------------------------------*/
    209 /** Prepares control read transfer.
     214/** Prepares control read transaction.
    210215 *
    211216 * @param[in] instance Batch structure to use.
     
    221226}
    222227/*----------------------------------------------------------------------------*/
    223 /** Prepare interrupt in transfer.
    224  *
    225  * @param[in] instance Batch structure to use.
    226  *
    227  * Data transfer with PID_IN.
     228/** Prepare interrupt in transaction.
     229 *
     230 * @param[in] instance Batch structure to use.
     231 *
     232 * Data transaction with PID_IN.
    228233 */
    229234void batch_interrupt_in(usb_transfer_batch_t *instance)
    230235{
    231236        assert(instance);
     237        instance->direction = USB_DIRECTION_IN;
    232238        batch_data(instance, USB_PID_IN);
    233239        instance->next_step = batch_call_in_and_dispose;
     
    235241}
    236242/*----------------------------------------------------------------------------*/
    237 /** Prepare interrupt out transfer.
    238  *
    239  * @param[in] instance Batch structure to use.
    240  *
    241  * Data transfer with PID_OUT.
     243/** Prepare interrupt out transaction.
     244 *
     245 * @param[in] instance Batch structure to use.
     246 *
     247 * Data transaction with PID_OUT.
    242248 */
    243249void batch_interrupt_out(usb_transfer_batch_t *instance)
    244250{
    245251        assert(instance);
     252        instance->direction = USB_DIRECTION_OUT;
    246253        /* We are data out, we are supposed to provide data */
    247         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
     254        memcpy(instance->transport_buffer, instance->buffer,
     255            instance->buffer_size);
    248256        batch_data(instance, USB_PID_OUT);
    249257        instance->next_step = batch_call_out_and_dispose;
     
    251259}
    252260/*----------------------------------------------------------------------------*/
    253 /** Prepare bulk in transfer.
    254  *
    255  * @param[in] instance Batch structure to use.
    256  *
    257  * Data transfer with PID_IN.
     261/** Prepare bulk in transaction.
     262 *
     263 * @param[in] instance Batch structure to use.
     264 *
     265 * Data transaction with PID_IN.
    258266 */
    259267void batch_bulk_in(usb_transfer_batch_t *instance)
     
    261269        assert(instance);
    262270        batch_data(instance, USB_PID_IN);
     271        instance->direction = USB_DIRECTION_IN;
    263272        instance->next_step = batch_call_in_and_dispose;
    264273        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
    265274}
    266275/*----------------------------------------------------------------------------*/
    267 /** Prepare bulk out transfer.
    268  *
    269  * @param[in] instance Batch structure to use.
    270  *
    271  * Data transfer with PID_OUT.
     276/** Prepare bulk out transaction.
     277 *
     278 * @param[in] instance Batch structure to use.
     279 *
     280 * Data transaction with PID_OUT.
    272281 */
    273282void batch_bulk_out(usb_transfer_batch_t *instance)
    274283{
    275284        assert(instance);
     285        instance->direction = USB_DIRECTION_OUT;
    276286        /* We are data out, we are supposed to provide data */
    277         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
     287        memcpy(instance->transport_buffer, instance->buffer,
     288            instance->buffer_size);
    278289        batch_data(instance, USB_PID_OUT);
    279290        instance->next_step = batch_call_out_and_dispose;
     
    281292}
    282293/*----------------------------------------------------------------------------*/
    283 /** Prepare generic data transfer
    284  *
    285  * @param[in] instance Batch structure to use.
    286  * @param[in] pid Pid to use for data transactions.
    287  *
    288  * Transactions with alternating toggle bit and supplied pid value.
     294/** Prepare generic data transaction
     295 *
     296 * @param[in] instance Batch structure to use.
     297 * @param[in] pid Pid to use for data transfers.
     298 *
     299 * Packets with alternating toggle bit and supplied pid value.
    289300 * The last transfer is marked with IOC flag.
    290301 */
     
    295306        assert(data);
    296307
    297         const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
     308        const bool low_speed = instance->speed == USB_SPEED_LOW;
    298309        int toggle = endpoint_toggle_get(instance->ep);
    299310        assert(toggle == 0 || toggle == 1);
    300311
    301         size_t td = 0;
     312        size_t transfer = 0;
    302313        size_t remain_size = instance->buffer_size;
    303         char *buffer = instance->data_buffer;
    304314        while (remain_size > 0) {
     315                char *trans_data =
     316                    instance->transport_buffer + instance->buffer_size
     317                    - remain_size;
     318
    305319                const size_t packet_size =
    306                     (instance->ep->max_packet_size > remain_size) ?
    307                     remain_size : instance->ep->max_packet_size;
    308 
    309                 td_t *next_td = (td + 1 < data->td_count)
    310                     ? &data->tds[td + 1] : NULL;
    311 
    312 
    313                 usb_target_t target =
    314                     { instance->ep->address, instance->ep->endpoint };
    315 
    316                 assert(td < data->td_count);
     320                    (instance->max_packet_size > remain_size) ?
     321                    remain_size : instance->max_packet_size;
     322
     323                td_t *next_transfer = (transfer + 1 < data->transfers)
     324                    ? &data->tds[transfer + 1] : NULL;
     325
     326                assert(transfer < data->transfers);
     327                assert(packet_size <= remain_size);
     328
    317329                td_init(
    318                     &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
    319                     toggle, false, low_speed, target, pid, buffer, next_td);
    320 
    321                 ++td;
     330                    &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
     331                    toggle, false, low_speed, instance->target, pid, trans_data,
     332                    next_transfer);
     333
     334
    322335                toggle = 1 - toggle;
    323                 buffer += packet_size;
    324                 assert(packet_size <= remain_size);
    325336                remain_size -= packet_size;
    326         }
    327         td_set_ioc(&data->tds[td - 1]);
     337                ++transfer;
     338        }
     339        td_set_ioc(&data->tds[transfer - 1]);
    328340        endpoint_toggle_set(instance->ep, toggle);
    329341}
    330342/*----------------------------------------------------------------------------*/
    331 /** Prepare generic control transfer
    332  *
    333  * @param[in] instance Batch structure to use.
    334  * @param[in] data_stage Pid to use for data tds.
    335  * @param[in] status_stage Pid to use for data tds.
     343/** Prepare generic control transaction
     344 *
     345 * @param[in] instance Batch structure to use.
     346 * @param[in] data_stage Pid to use for data transfers.
     347 * @param[in] status_stage Pid to use for data transfers.
    336348 *
    337349 * Setup stage with toggle 0 and USB_PID_SETUP.
     
    346358        uhci_batch_t *data = instance->private_data;
    347359        assert(data);
    348         assert(data->td_count >= 2);
    349 
    350         const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
    351         const usb_target_t target =
    352             { instance->ep->address, instance->ep->endpoint };
    353 
     360        assert(data->transfers >= 2);
     361
     362        const bool low_speed = instance->speed == USB_SPEED_LOW;
     363        int toggle = 0;
    354364        /* setup stage */
    355365        td_init(
    356             data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, 0, false,
    357             low_speed, target, USB_PID_SETUP, instance->setup_buffer,
     366            data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, toggle, false,
     367            low_speed, instance->target, USB_PID_SETUP, instance->setup_buffer,
    358368            &data->tds[1]);
    359369
    360370        /* data stage */
    361         size_t td = 1;
    362         unsigned toggle = 1;
     371        size_t transfer = 1;
    363372        size_t remain_size = instance->buffer_size;
    364         char *buffer = instance->data_buffer;
    365373        while (remain_size > 0) {
     374                char *control_data =
     375                    instance->transport_buffer + instance->buffer_size
     376                    - remain_size;
     377
     378                toggle = 1 - toggle;
     379
    366380                const size_t packet_size =
    367                     (instance->ep->max_packet_size > remain_size) ?
    368                     remain_size : instance->ep->max_packet_size;
     381                    (instance->max_packet_size > remain_size) ?
     382                    remain_size : instance->max_packet_size;
    369383
    370384                td_init(
    371                     &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
    372                     toggle, false, low_speed, target, data_stage,
    373                     buffer, &data->tds[td + 1]);
    374 
    375                 ++td;
    376                 toggle = 1 - toggle;
    377                 buffer += packet_size;
    378                 assert(td < data->td_count);
     385                    &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
     386                    toggle, false, low_speed, instance->target, data_stage,
     387                    control_data, &data->tds[transfer + 1]);
     388
     389                ++transfer;
     390                assert(transfer < data->transfers);
    379391                assert(packet_size <= remain_size);
    380392                remain_size -= packet_size;
     
    382394
    383395        /* status stage */
    384         assert(td == data->td_count - 1);
     396        assert(transfer == data->transfers - 1);
    385397
    386398        td_init(
    387             &data->tds[td], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
    388             target, status_stage, NULL, NULL);
    389         td_set_ioc(&data->tds[td]);
     399            &data->tds[transfer], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
     400            instance->target, status_stage, NULL, NULL);
     401        td_set_ioc(&data->tds[transfer]);
    390402
    391403        usb_log_debug2("Control last TD status: %x.\n",
    392             data->tds[td].status);
     404            data->tds[transfer].status);
    393405}
    394406/*----------------------------------------------------------------------------*/
     
    401413}
    402414/*----------------------------------------------------------------------------*/
    403 /** Helper function, calls callback and correctly destroys batch structure.
     415/** Helper function calls callback and correctly disposes of batch structure.
    404416 *
    405417 * @param[in] instance Batch structure to use.
     
    412424}
    413425/*----------------------------------------------------------------------------*/
    414 /** Helper function calls callback and correctly destroys batch structure.
     426/** Helper function calls callback and correctly disposes of batch structure.
    415427 *
    416428 * @param[in] instance Batch structure to use.
     
    437449        free32(data->qh);
    438450        free32(instance->setup_buffer);
    439         free32(instance->data_buffer);
     451        free32(instance->transport_buffer);
    440452        free(data);
    441453        free(instance);
  • uspace/drv/uhci-hcd/hc.c

    r4deca9b r1324ff3  
    329329
    330330        transfer_list_t *list =
    331             instance->transfers[batch->ep->speed][batch->ep->transfer_type];
     331            instance->transfers[batch->speed][batch->transfer_type];
    332332        assert(list);
    333333        transfer_list_add_batch(list, batch);
  • uspace/drv/uhci-hcd/iface.c

    r4deca9b r1324ff3  
    148148        assert(hc);
    149149        const size_t size = max_packet_size;
     150        int ret;
    150151        usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
    151152        if (speed >= USB_SPEED_MAX) {
     
    156157            usb_str_speed(speed), direction, size, max_packet_size, interval);
    157158
    158         return usb_endpoint_manager_add_ep(&hc->ep_manager, address, endpoint,
    159             direction, transfer_type, speed, max_packet_size, size);
     159
     160        endpoint_t *ep = malloc(sizeof(endpoint_t));
     161        if (ep == NULL)
     162                return ENOMEM;
     163        ret = endpoint_init(ep, address, endpoint, direction,
     164            transfer_type, speed, max_packet_size);
     165        if (ret != EOK) {
     166                free(ep);
     167                return ret;
     168        }
     169
     170        ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
     171        if (ret != EOK) {
     172                endpoint_destroy(ep);
     173        }
     174        return ret;
    160175}
    161176/*----------------------------------------------------------------------------*/
  • uspace/lib/usb/include/usb/host/batch.h

    r4deca9b r1324ff3  
    4343typedef struct usb_transfer_batch usb_transfer_batch_t;
    4444struct usb_transfer_batch {
    45         endpoint_t *ep;
    4645        link_t link;
     46        usb_target_t target;
     47        usb_transfer_type_t transfer_type;
     48        usb_speed_t speed;
     49        usb_direction_t direction;
    4750        usbhc_iface_transfer_in_callback_t callback_in;
    4851        usbhc_iface_transfer_out_callback_t callback_out;
    49         void *arg;
    5052        char *buffer;
    51         char *data_buffer;
     53        char *transport_buffer;
    5254        size_t buffer_size;
    5355        char *setup_buffer;
    5456        size_t setup_size;
     57        size_t max_packet_size;
    5558        size_t transfered_size;
    5659        void (*next_step)(usb_transfer_batch_t *);
    5760        int error;
    5861        ddf_fun_t *fun;
     62        void *arg;
     63        endpoint_t *ep;
    5964        void *private_data;
    6065};
     
    6267void usb_transfer_batch_init(
    6368    usb_transfer_batch_t *instance,
    64                 endpoint_t *ep,
     69    usb_target_t target,
     70    usb_transfer_type_t transfer_type,
     71    usb_speed_t speed,
     72    size_t max_packet_size,
    6573    char *buffer,
    66     char *data_buffer,
     74    char *transport_buffer,
    6775    size_t buffer_size,
    6876    char *setup_buffer,
     
    7280    void *arg,
    7381    ddf_fun_t *fun,
     82                endpoint_t *ep,
    7483    void *private_data
    7584);
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r4deca9b r1324ff3  
    5454        usb_speed_t speed;
    5555        bool occupied;
     56        link_t endpoints;
     57        uint16_t control_used;
    5658        devman_handle_t handle;
    5759};
     
    6365        struct usb_device_info devices[USB_ADDRESS_COUNT];
    6466        fibril_mutex_t guard;
     67        fibril_condvar_t change;
    6568        usb_address_t last_address;
    6669} usb_device_keeper_t;
    6770
    6871void usb_device_keeper_init(usb_device_keeper_t *instance);
     72
     73void usb_device_keeper_reserve_default_address(
     74    usb_device_keeper_t *instance, usb_speed_t speed);
     75
     76void usb_device_keeper_release_default_address(usb_device_keeper_t *instance);
     77
     78void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance,
     79    usb_target_t target, const uint8_t *setup_data);
    6980
    7081usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance,
  • uspace/lib/usb/include/usb/host/usb_endpoint_manager.h

    r4deca9b r1324ff3  
    6666    endpoint_t *ep, size_t data_size);
    6767
     68int usb_endpoint_manager_register_ep_wait(usb_endpoint_manager_t *instance,
     69    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,
     70    void *data, void (*data_remove_callback)(void* data, void* arg), void *arg,
     71    size_t bw);
     72
    6873int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
    6974    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
     
    7580void usb_endpoint_manager_reset_if_need(
    7681    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
    77 
    78 static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
    79     usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    80     usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
    81     size_t data_size)
    82 {
    83         endpoint_t *ep = malloc(sizeof(endpoint_t));
    84         if (ep == NULL)
    85                 return ENOMEM;
    86 
    87         int ret = endpoint_init(ep, address, endpoint, direction, type, speed,
    88             max_packet_size);
    89         if (ret != EOK) {
    90                 free(ep);
    91                 return ret;
    92         }
    93 
    94         ret = usb_endpoint_manager_register_ep(instance, ep, data_size);
    95         if (ret != EOK) {
    96                 endpoint_destroy(ep);
    97                 return ret;
    98         }
    99         return EOK;
    100 }
    10182#endif
    10283/**
  • uspace/lib/usb/src/host/batch.c

    r4deca9b r1324ff3  
    4141void usb_transfer_batch_init(
    4242    usb_transfer_batch_t *instance,
    43                 endpoint_t *ep,
     43    usb_target_t target,
     44    usb_transfer_type_t transfer_type,
     45    usb_speed_t speed,
     46    size_t max_packet_size,
    4447    char *buffer,
    45     char *data_buffer,
     48    char *transport_buffer,
    4649    size_t buffer_size,
    4750    char *setup_buffer,
     
    5154    void *arg,
    5255    ddf_fun_t *fun,
     56                endpoint_t *ep,
    5357    void *private_data
    5458    )
     
    5660        assert(instance);
    5761        link_initialize(&instance->link);
    58         instance->ep = ep;
     62        instance->target = target;
     63        instance->transfer_type = transfer_type;
     64        instance->speed = speed;
     65        instance->direction = ep->direction;
    5966        instance->callback_in = func_in;
    6067        instance->callback_out = func_out;
    6168        instance->arg = arg;
    6269        instance->buffer = buffer;
    63         instance->data_buffer = data_buffer;
     70        instance->transport_buffer = transport_buffer;
    6471        instance->buffer_size = buffer_size;
    6572        instance->setup_buffer = setup_buffer;
    6673        instance->setup_size = setup_size;
     74        instance->max_packet_size = max_packet_size;
    6775        instance->fun = fun;
    6876        instance->private_data = private_data;
     
    7078        instance->next_step = NULL;
    7179        instance->error = EOK;
     80        instance->ep = ep;
    7281        endpoint_use(instance->ep);
    7382}
     
    96105        assert(instance);
    97106        assert(instance->callback_in);
    98         assert(instance->ep);
    99107
    100108        /* We are data in, we need data */
    101         memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
     109        memcpy(instance->buffer, instance->transport_buffer,
     110            instance->buffer_size);
    102111
    103112        usb_log_debug("Batch %p done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
    104             instance, instance->ep->address, instance->ep->endpoint,
    105             usb_str_speed(instance->ep->speed),
    106             usb_str_transfer_type_short(instance->ep->transfer_type),
    107             instance->transfered_size, str_error(instance->error), instance->error);
     113            instance,
     114            instance->target.address, instance->target.endpoint,
     115            usb_str_speed(instance->speed),
     116            usb_str_transfer_type_short(instance->transfer_type),
     117            instance->transfered_size,
     118            str_error(instance->error), instance->error);
    108119
    109120        instance->callback_in(instance->fun, instance->error,
     
    121132
    122133        usb_log_debug("Batch %p done (T%d.%d, %s %s out): %s (%d).\n",
    123             instance, instance->ep->address, instance->ep->endpoint,
    124             usb_str_speed(instance->ep->speed),
    125             usb_str_transfer_type_short(instance->ep->transfer_type),
     134            instance,
     135            instance->target.address, instance->target.endpoint,
     136            usb_str_speed(instance->speed),
     137            usb_str_transfer_type_short(instance->transfer_type),
    126138            str_error(instance->error), instance->error);
    127139
  • uspace/lib/usb/src/host/device_keeper.c

    r4deca9b r1324ff3  
    4848{
    4949        assert(instance);
     50        fibril_mutex_initialize(&instance->guard);
     51        fibril_condvar_initialize(&instance->change);
     52        instance->last_address = 0;
    5053        unsigned i = 0;
    5154        for (; i < USB_ADDRESS_COUNT; ++i) {
     
    5760        // (it is needed to allow smooth registration at default address)
    5861        instance->devices[0].occupied = true;
    59         instance->last_address = 0;
    60         fibril_mutex_initialize(&instance->guard);
    61 }
     62}
     63/*----------------------------------------------------------------------------*/
     64/** Attempt to obtain address 0, blocks.
     65 *
     66 * @param[in] instance Device keeper structure to use.
     67 * @param[in] speed Speed of the device requesting default address.
     68 */
     69void usb_device_keeper_reserve_default_address(
     70    usb_device_keeper_t *instance, usb_speed_t speed)
     71{
     72        assert(instance);
     73        fibril_mutex_lock(&instance->guard);
     74        while (instance->devices[USB_ADDRESS_DEFAULT].occupied) {
     75                fibril_condvar_wait(&instance->change, &instance->guard);
     76        }
     77        instance->devices[USB_ADDRESS_DEFAULT].occupied = true;
     78        instance->devices[USB_ADDRESS_DEFAULT].speed = speed;
     79        fibril_mutex_unlock(&instance->guard);
     80}
     81/*----------------------------------------------------------------------------*/
     82/** Attempt to obtain address 0, blocks.
     83 *
     84 * @param[in] instance Device keeper structure to use.
     85 * @param[in] speed Speed of the device requesting default address.
     86 */
     87void usb_device_keeper_release_default_address(usb_device_keeper_t *instance)
     88{
     89        assert(instance);
     90        fibril_mutex_lock(&instance->guard);
     91        instance->devices[USB_ADDRESS_DEFAULT].occupied = false;
     92        fibril_mutex_unlock(&instance->guard);
     93        fibril_condvar_signal(&instance->change);
     94}
     95/*----------------------------------------------------------------------------*/
    6296/*----------------------------------------------------------------------------*/
    6397/** Get a free USB address
     
    86120        assert(new_address != USB_ADDRESS_DEFAULT);
    87121        assert(instance->devices[new_address].occupied == false);
    88 
    89122        instance->devices[new_address].occupied = true;
    90123        instance->devices[new_address].speed = speed;
    91124        instance->last_address = new_address;
    92 
    93125        fibril_mutex_unlock(&instance->guard);
    94126        return new_address;
     
    106138        assert(instance);
    107139        fibril_mutex_lock(&instance->guard);
    108 
    109140        assert(address > 0);
    110141        assert(address <= USB11_ADDRESS_MAX);
    111142        assert(instance->devices[address].occupied);
    112 
    113143        instance->devices[address].handle = handle;
    114144        fibril_mutex_unlock(&instance->guard);
     
    129159        fibril_mutex_lock(&instance->guard);
    130160        assert(instance->devices[address].occupied);
    131 
    132161        instance->devices[address].occupied = false;
    133162        fibril_mutex_unlock(&instance->guard);
     
    148177        while (address <= USB11_ADDRESS_MAX) {
    149178                if (instance->devices[address].handle == handle) {
    150                         assert(instance->devices[address].occupied);
    151179                        fibril_mutex_unlock(&instance->guard);
    152180                        return address;
     
    170198        assert(address >= 0);
    171199        assert(address <= USB11_ADDRESS_MAX);
    172 
    173200        return instance->devices[address].speed;
    174201}
Note: See TracChangeset for help on using the changeset viewer.