Changeset f8e1a2c in mainline


Ignore:
Timestamp:
2011-03-21T13:19:19Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0e45e7f, 8a951ca
Parents:
e387d0f (diff), 2e1d5d70 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development/ changes

Location:
uspace
Files:
2 added
12 edited
2 moved

Legend:

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

    re387d0f rf8e1a2c  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbohcihc
     28/** @addtogroup drvusbohci
    2929 * @{
    3030 */
     
    4040#include "batch.h"
    4141
    42 static void batch_call_in(batch_t *instance);
    43 static void batch_call_out(batch_t *instance);
    44 static void batch_call_in_and_dispose(batch_t *instance);
    45 static void batch_call_out_and_dispose(batch_t *instance);
     42#define DEFAULT_ERROR_COUNT 3
    4643
    47 /** Allocate memory and initialize internal data structure.
    48  *
    49  * @param[in] fun DDF function to pass to callback.
    50  * @param[in] target Device and endpoint target of the transaction.
    51  * @param[in] transfer_type Interrupt, Control or Bulk.
    52  * @param[in] max_packet_size maximum allowed size of data packets.
    53  * @param[in] speed Speed of the transaction.
    54  * @param[in] buffer Data source/destination.
    55  * @param[in] size Size of the buffer.
    56  * @param[in] setup_buffer Setup data source (if not NULL)
    57  * @param[in] setup_size Size of setup_buffer (should be always 8)
    58  * @param[in] func_in function to call on inbound transaction completion
    59  * @param[in] func_out function to call on outbound transaction completion
    60  * @param[in] arg additional parameter to func_in or func_out
    61  * @param[in] manager Pointer to toggle management structure.
    62  * @return Valid pointer if all substructures were successfully created,
    63  * NULL otherwise.
    64  *
    65  * Determines the number of needed packets (TDs). Prepares a transport buffer
    66  * (that is accessible by the hardware). Initializes parameters needed for the
    67  * transaction and callback.
    68  */
    69 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    70     usb_transfer_type_t transfer_type, size_t max_packet_size,
    71     usb_speed_t speed, char *buffer, size_t size,
    72     char* setup_buffer, size_t setup_size,
    73     usbhc_iface_transfer_in_callback_t func_in,
    74     usbhc_iface_transfer_out_callback_t func_out, void *arg
    75     )
    76 {
    77         assert(func_in == NULL || func_out == NULL);
    78         assert(func_in != NULL || func_out != NULL);
    79 
    80 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
    81         if (ptr == NULL) { \
    82                 usb_log_error(message); \
    83                 if (instance) { \
    84                         batch_dispose(instance); \
    85                 } \
    86                 return NULL; \
    87         } else (void)0
    88 
    89         batch_t *instance = malloc(sizeof(batch_t));
    90         CHECK_NULL_DISPOSE_RETURN(instance,
    91             "Failed to allocate batch instance.\n");
    92         bzero(instance, sizeof(batch_t));
    93 
    94         if (size > 0) {
    95                 /* TODO: use device accessible malloc here */
    96                 instance->transport_buffer = malloc(size);
    97                 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
    98                     "Failed to allocate device accessible buffer.\n");
    99         }
    100 
    101         if (setup_size > 0) {
    102                 /* TODO: use device accessible malloc here */
    103                 instance->setup_buffer = malloc(setup_size);
    104                 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
    105                     "Failed to allocate device accessible setup buffer.\n");
    106                 memcpy(instance->setup_buffer, setup_buffer, setup_size);
    107         }
    108 
    109         link_initialize(&instance->link);
    110 
    111         instance->max_packet_size = max_packet_size;
    112         instance->target = target;
    113         instance->transfer_type = transfer_type;
    114         instance->buffer = buffer;
    115         instance->buffer_size = size;
    116         instance->setup_size = setup_size;
    117         instance->fun = fun;
    118         instance->arg = arg;
    119         instance->speed = speed;
    120         instance->callback_out = func_out;
    121         instance->callback_in = func_in;
    122 
    123         usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    124             instance, target.address, target.endpoint);
    125         return instance;
    126 }
    127 /*----------------------------------------------------------------------------*/
    128 /** Mark batch as finished and continue with next step.
    129  *
    130  * @param[in] instance Batch structure to use.
    131  *
    132  */
    133 void batch_finish(batch_t *instance, int error)
    134 {
    135         assert(instance);
    136         instance->error = error;
    137         instance->next_step(instance);
    138 }
    139 /*----------------------------------------------------------------------------*/
    140 /** Check batch TDs for activity.
    141  *
    142  * @param[in] instance Batch structure to use.
    143  * @return False, if there is an active TD, true otherwise.
    144  *
    145  * Walk all TDs. Stop with false if there is an active one (it is to be
    146  * processed). Stop with true if an error is found. Return true if the last TS
    147  * is reached.
    148  */
    149 bool batch_is_complete(batch_t *instance)
    150 {
    151         assert(instance);
    152         /* TODO: implement */
    153         return true;
    154 }
    155 /*----------------------------------------------------------------------------*/
    156 /** Prepares control write transaction.
    157  *
    158  * @param[in] instance Batch structure to use.
    159  *
    160  * Uses genercir control function with pids OUT and IN.
    161  */
    162 void batch_control_write(batch_t *instance)
    163 {
    164         assert(instance);
    165         /* We are data out, we are supposed to provide data */
    166         memcpy(instance->transport_buffer, instance->buffer,
    167             instance->buffer_size);
    168         instance->next_step = batch_call_out_and_dispose;
    169         /* TODO: implement */
    170         usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
    171 }
    172 /*----------------------------------------------------------------------------*/
    173 /** Prepares control read transaction.
    174  *
    175  * @param[in] instance Batch structure to use.
    176  *
    177  * Uses generic control with pids IN and OUT.
    178  */
    179 void batch_control_read(batch_t *instance)
    180 {
    181         assert(instance);
    182         instance->next_step = batch_call_in_and_dispose;
    183         /* TODO: implement */
    184         usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    185 }
    186 /*----------------------------------------------------------------------------*/
    187 /** Prepare interrupt in transaction.
    188  *
    189  * @param[in] instance Batch structure to use.
    190  *
    191  * Data transaction with PID_IN.
    192  */
    193 void batch_interrupt_in(batch_t *instance)
    194 {
    195         assert(instance);
    196         /* TODO: implement */
    197         instance->next_step = batch_call_in_and_dispose;
    198         usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
    199 }
    200 /*----------------------------------------------------------------------------*/
    201 /** Prepare interrupt out transaction.
    202  *
    203  * @param[in] instance Batch structure to use.
    204  *
    205  * Data transaction with PID_OUT.
    206  */
    207 void batch_interrupt_out(batch_t *instance)
    208 {
    209         assert(instance);
    210         /* We are data out, we are supposed to provide data */
    211         memcpy(instance->transport_buffer, instance->buffer,
    212             instance->buffer_size);
    213         instance->next_step = batch_call_out_and_dispose;
    214         /* TODO: implement */
    215         usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
    216 }
    217 /*----------------------------------------------------------------------------*/
    218 /** Prepare bulk in transaction.
    219  *
    220  * @param[in] instance Batch structure to use.
    221  *
    222  * Data transaction with PID_IN.
    223  */
    224 void batch_bulk_in(batch_t *instance)
    225 {
    226         assert(instance);
    227         instance->next_step = batch_call_in_and_dispose;
    228         /* TODO: implement */
    229         usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
    230 }
    231 /*----------------------------------------------------------------------------*/
    232 /** Prepare bulk out transaction.
    233  *
    234  * @param[in] instance Batch structure to use.
    235  *
    236  * Data transaction with PID_OUT.
    237  */
    238 void batch_bulk_out(batch_t *instance)
    239 {
    240         assert(instance);
    241         /* We are data out, we are supposed to provide data */
    242         memcpy(instance->transport_buffer, instance->buffer,
    243             instance->buffer_size);
    244         instance->next_step = batch_call_out_and_dispose;
    245         /* TODO: implement */
    246         usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
    247 }
    248 /*----------------------------------------------------------------------------*/
    249 /** Prepare data, get error status and call callback in.
    250  *
    251  * @param[in] instance Batch structure to use.
    252  * Copies data from transport buffer, and calls callback with appropriate
    253  * parameters.
    254  */
    255 void batch_call_in(batch_t *instance)
    256 {
    257         assert(instance);
    258         assert(instance->callback_in);
    259 
    260         /* We are data in, we need data */
    261         memcpy(instance->buffer, instance->transport_buffer,
    262             instance->buffer_size);
    263 
    264         int err = instance->error;
    265         usb_log_debug("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n",
    266             instance, instance->transfer_type, str_error(err), err,
    267             instance->transfered_size);
    268 
    269         instance->callback_in(
    270             instance->fun, err, instance->transfered_size, instance->arg);
    271 }
    272 /*----------------------------------------------------------------------------*/
    273 /** Get error status and call callback out.
    274  *
    275  * @param[in] instance Batch structure to use.
    276  */
    277 void batch_call_out(batch_t *instance)
    278 {
    279         assert(instance);
    280         assert(instance->callback_out);
    281 
    282         int err = instance->error;
    283         usb_log_debug("Batch(%p) callback OUT(type:%d): %s(%d).\n",
    284             instance, instance->transfer_type, str_error(err), err);
    285         instance->callback_out(instance->fun,
    286             err, instance->arg);
    287 }
    288 /*----------------------------------------------------------------------------*/
    289 /** Helper function calls callback and correctly disposes of batch structure.
    290  *
    291  * @param[in] instance Batch structure to use.
    292  */
    293 void batch_call_in_and_dispose(batch_t *instance)
    294 {
    295         assert(instance);
    296         batch_call_in(instance);
    297         batch_dispose(instance);
    298 }
    299 /*----------------------------------------------------------------------------*/
    300 /** Helper function calls callback and correctly disposes of batch structure.
    301  *
    302  * @param[in] instance Batch structure to use.
    303  */
    304 void batch_call_out_and_dispose(batch_t *instance)
    305 {
    306         assert(instance);
    307         batch_call_out(instance);
    308         batch_dispose(instance);
    309 }
    310 /*----------------------------------------------------------------------------*/
    311 /** Correctly dispose all used data structures.
    312  *
    313  * @param[in] instance Batch structure to use.
    314  */
    315 void batch_dispose(batch_t *instance)
    316 {
    317         assert(instance);
    318         usb_log_debug("Batch(%p) disposing.\n", instance);
    319         if (instance->setup_buffer)
    320                 free(instance->setup_buffer);
    321         if (instance->transport_buffer)
    322                 free(instance->transport_buffer);
    323         free(instance);
    324 }
    32544/**
    32645 * @}
  • uspace/drv/ohci/batch.h

    re387d0f rf8e1a2c  
    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
    3636
    37 #include <adt/list.h>
    3837
    3938#include <usbhc_iface.h>
    4039#include <usb/usb.h>
    41 
    42 typedef struct batch
    43 {
    44         link_t link;
    45         usb_speed_t speed;
    46         usb_target_t target;
    47         usb_transfer_type_t transfer_type;
    48         usbhc_iface_transfer_in_callback_t callback_in;
    49         usbhc_iface_transfer_out_callback_t callback_out;
    50         void *arg;
    51         char *transport_buffer;
    52         char *setup_buffer;
    53         size_t setup_size;
    54         char *buffer;
    55         size_t buffer_size;
    56         size_t max_packet_size;
    57         size_t packets;
    58         size_t transfered_size;
    59         int error;
    60         ddf_fun_t *fun;
    61         void (*next_step)(struct batch*);
    62 } batch_t;
     40#include <usb/host/device_keeper.h>
     41#include <usb/host/batch.h>
    6342
    6443batch_t * batch_get(
     
    7453    usbhc_iface_transfer_in_callback_t func_in,
    7554    usbhc_iface_transfer_out_callback_t func_out,
    76                 void *arg
     55                void *arg,
     56                device_keeper_t *manager
    7757                );
    7858
    7959void batch_dispose(batch_t *instance);
    80 
    81 void batch_finish(batch_t *instance, int error);
    82 
    83 bool batch_is_complete(batch_t *instance);
    8460
    8561void batch_control_write(batch_t *instance);
  • uspace/drv/ohci/hc_iface.c

    re387d0f rf8e1a2c  
    322322}
    323323
    324 /** Host controller interface implementation for EHCI. */
     324/** Host controller interface implementation for OHCI. */
    325325usbhc_iface_t ohci_hc_iface = {
    326326        .reserve_default_address = reserve_default_address,
  • uspace/drv/ohci/ohci_rh.c

    re387d0f rf8e1a2c  
    3030 */
    3131/** @file
    32  * @brief UHCI driver
     32 * @brief OHCI driver
    3333 */
    3434#include <assert.h>
  • uspace/drv/uhci-hcd/Makefile

    re387d0f rf8e1a2c  
    4040        uhci_rh.c \
    4141        uhci_struct/transfer_descriptor.c \
    42         utils/device_keeper.c \
    4342        pci.c \
    4443        batch.c
  • uspace/drv/uhci-hcd/batch.c

    re387d0f rf8e1a2c  
    4242#include "uhci_hc.h"
    4343#include "utils/malloc32.h"
     44#include "uhci_struct/transfer_descriptor.h"
    4445
    4546#define DEFAULT_ERROR_COUNT 3
     47
     48typedef struct uhci_batch {
     49        qh_t *qh;
     50        td_t *tds;
     51        size_t packets;
     52        device_keeper_t *manager;
     53} uhci_batch_t;
    4654
    4755static void batch_control(batch_t *instance,
    4856    usb_packet_id data_stage, usb_packet_id status_stage);
    4957static void batch_data(batch_t *instance, usb_packet_id pid);
    50 static void batch_call_in(batch_t *instance);
    51 static void batch_call_out(batch_t *instance);
    5258static void batch_call_in_and_dispose(batch_t *instance);
    5359static void batch_call_out_and_dispose(batch_t *instance);
     
    7884batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    7985    usb_transfer_type_t transfer_type, size_t max_packet_size,
    80     usb_speed_t speed, char *buffer, size_t size,
     86    usb_speed_t speed, char *buffer, size_t buffer_size,
    8187    char* setup_buffer, size_t setup_size,
    8288    usbhc_iface_transfer_in_callback_t func_in,
     
    100106        CHECK_NULL_DISPOSE_RETURN(instance,
    101107            "Failed to allocate batch instance.\n");
    102         bzero(instance, sizeof(batch_t));
    103 
    104         instance->qh = malloc32(sizeof(qh_t));
    105         CHECK_NULL_DISPOSE_RETURN(instance->qh,
     108        batch_init(instance, target, transfer_type, speed, max_packet_size,
     109            buffer, NULL, buffer_size, NULL, setup_size, func_in,
     110            func_out, arg, fun, NULL);
     111
     112
     113        uhci_batch_t *data = malloc(sizeof(uhci_batch_t));
     114        CHECK_NULL_DISPOSE_RETURN(instance,
     115            "Failed to allocate batch instance.\n");
     116        bzero(data, sizeof(uhci_batch_t));
     117        data->manager = manager;
     118        instance->private_data = data;
     119
     120        data->packets = (buffer_size + max_packet_size - 1) / max_packet_size;
     121        if (transfer_type == USB_TRANSFER_CONTROL) {
     122                data->packets += 2;
     123        }
     124
     125        data->tds = malloc32(sizeof(td_t) * data->packets);
     126        CHECK_NULL_DISPOSE_RETURN(
     127            data->tds, "Failed to allocate transfer descriptors.\n");
     128        bzero(data->tds, sizeof(td_t) * data->packets);
     129
     130        data->qh = malloc32(sizeof(qh_t));
     131        CHECK_NULL_DISPOSE_RETURN(data->qh,
    106132            "Failed to allocate batch queue head.\n");
    107         qh_init(instance->qh);
    108 
    109         instance->packets = (size + max_packet_size - 1) / max_packet_size;
    110         if (transfer_type == USB_TRANSFER_CONTROL) {
    111                 instance->packets += 2;
    112         }
    113 
    114         instance->tds = malloc32(sizeof(td_t) * instance->packets);
    115         CHECK_NULL_DISPOSE_RETURN(
    116             instance->tds, "Failed to allocate transfer descriptors.\n");
    117         bzero(instance->tds, sizeof(td_t) * instance->packets);
    118 
    119         if (size > 0) {
    120                 instance->transport_buffer = malloc32(size);
     133        qh_init(data->qh);
     134        qh_set_element_td(data->qh, addr_to_phys(data->tds));
     135
     136        if (buffer_size > 0) {
     137                instance->transport_buffer = malloc32(buffer_size);
    121138                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
    122139                    "Failed to allocate device accessible buffer.\n");
     
    130147        }
    131148
    132 
    133         link_initialize(&instance->link);
    134 
    135         instance->max_packet_size = max_packet_size;
    136         instance->target = target;
    137         instance->transfer_type = transfer_type;
    138         instance->buffer = buffer;
    139         instance->buffer_size = size;
    140         instance->setup_size = setup_size;
    141         instance->fun = fun;
    142         instance->arg = arg;
    143         instance->speed = speed;
    144         instance->manager = manager;
    145         instance->callback_out = func_out;
    146         instance->callback_in = func_in;
    147 
    148         qh_set_element_td(instance->qh, addr_to_phys(instance->tds));
    149 
    150149        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    151150            instance, target.address, target.endpoint);
     
    153152}
    154153/*----------------------------------------------------------------------------*/
    155 /** Mark batch as failed and continue with next step.
    156  *
    157  * @param[in] instance Batch structure to use.
    158  *
    159  */
    160 void batch_abort(batch_t *instance)
    161 {
    162         assert(instance);
    163         instance->error = EIO;
    164         instance->next_step(instance);
    165 }
    166 /*----------------------------------------------------------------------------*/
    167154/** Check batch TDs for activity.
    168155 *
     
    177164{
    178165        assert(instance);
     166        uhci_batch_t *data = instance->private_data;
     167        assert(data);
     168
    179169        usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",
    180             instance, instance->packets);
     170            instance, data->packets);
    181171        instance->transfered_size = 0;
    182172        size_t i = 0;
    183         for (;i < instance->packets; ++i) {
    184                 if (td_is_active(&instance->tds[i])) {
     173        for (;i < data->packets; ++i) {
     174                if (td_is_active(&data->tds[i])) {
    185175                        return false;
    186176                }
    187177
    188                 instance->error = td_status(&instance->tds[i]);
     178                instance->error = td_status(&data->tds[i]);
    189179                if (instance->error != EOK) {
    190180                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    191                             instance, i, instance->tds[i].status);
    192                         td_print_status(&instance->tds[i]);
    193 
    194                         device_keeper_set_toggle(instance->manager,
    195                             instance->target, td_toggle(&instance->tds[i]));
     181                            instance, i, data->tds[i].status);
     182                        td_print_status(&data->tds[i]);
     183
     184                        device_keeper_set_toggle(data->manager,
     185                            instance->target, td_toggle(&data->tds[i]));
    196186                        if (i > 0)
    197187                                goto substract_ret;
     
    199189                }
    200190
    201                 instance->transfered_size += td_act_size(&instance->tds[i]);
    202                 if (td_is_short(&instance->tds[i]))
     191                instance->transfered_size += td_act_size(&data->tds[i]);
     192                if (td_is_short(&data->tds[i]))
    203193                        goto substract_ret;
    204194        }
     
    312302{
    313303        assert(instance);
     304        uhci_batch_t *data = instance->private_data;
     305        assert(data);
     306
    314307        const bool low_speed = instance->speed == USB_SPEED_LOW;
    315         int toggle =
    316             device_keeper_get_toggle(instance->manager, instance->target);
     308        int toggle = device_keeper_get_toggle(data->manager, instance->target);
    317309        assert(toggle == 0 || toggle == 1);
    318310
     
    320312        size_t remain_size = instance->buffer_size;
    321313        while (remain_size > 0) {
    322                 char *data =
     314                char *trans_data =
    323315                    instance->transport_buffer + instance->buffer_size
    324316                    - remain_size;
     
    328320                    remain_size : instance->max_packet_size;
    329321
    330                 td_t *next_packet = (packet + 1 < instance->packets)
    331                     ? &instance->tds[packet + 1] : NULL;
    332 
    333                 assert(packet < instance->packets);
     322                td_t *next_packet = (packet + 1 < data->packets)
     323                    ? &data->tds[packet + 1] : NULL;
     324
     325                assert(packet < data->packets);
    334326                assert(packet_size <= remain_size);
    335327
    336328                td_init(
    337                     &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    338                     toggle, false, low_speed, instance->target, pid, data,
     329                    &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     330                    toggle, false, low_speed, instance->target, pid, trans_data,
    339331                    next_packet);
    340332
     
    344336                ++packet;
    345337        }
    346         td_set_ioc(&instance->tds[packet - 1]);
    347         device_keeper_set_toggle(instance->manager, instance->target, toggle);
     338        td_set_ioc(&data->tds[packet - 1]);
     339        device_keeper_set_toggle(data->manager, instance->target, toggle);
    348340}
    349341/*----------------------------------------------------------------------------*/
     
    363355{
    364356        assert(instance);
     357        uhci_batch_t *data = instance->private_data;
     358        assert(data);
     359        assert(data->packets >= 2);
    365360
    366361        const bool low_speed = instance->speed == USB_SPEED_LOW;
    367362        int toggle = 0;
    368363        /* setup stage */
    369         td_init(instance->tds, DEFAULT_ERROR_COUNT,
    370             instance->setup_size, toggle, false, low_speed, instance->target,
    371             USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
     364        td_init(
     365            data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, toggle, false,
     366            low_speed, instance->target, USB_PID_SETUP, instance->setup_buffer,
     367            &data->tds[1]);
    372368
    373369        /* data stage */
     
    375371        size_t remain_size = instance->buffer_size;
    376372        while (remain_size > 0) {
    377                 char *data =
     373                char *control_data =
    378374                    instance->transport_buffer + instance->buffer_size
    379375                    - remain_size;
     
    386382
    387383                td_init(
    388                     &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     384                    &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    389385                    toggle, false, low_speed, instance->target, data_stage,
    390                     data, &instance->tds[packet + 1]);
     386                    control_data, &data->tds[packet + 1]);
    391387
    392388                ++packet;
    393                 assert(packet < instance->packets);
     389                assert(packet < data->packets);
    394390                assert(packet_size <= remain_size);
    395391                remain_size -= packet_size;
     
    397393
    398394        /* status stage */
    399         assert(packet == instance->packets - 1);
    400         td_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
    401             0, 1, false, low_speed, instance->target, status_stage, NULL, NULL);
    402 
    403         td_set_ioc(&instance->tds[packet]);
     395        assert(packet == data->packets - 1);
     396
     397        td_init(
     398            &data->tds[packet], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
     399            instance->target, status_stage, NULL, NULL);
     400        td_set_ioc(&data->tds[packet]);
     401
    404402        usb_log_debug2("Control last TD status: %x.\n",
    405             instance->tds[packet].status);
    406 }
    407 /*----------------------------------------------------------------------------*/
    408 /** Prepare data, get error status and call callback in.
    409  *
    410  * @param[in] instance Batch structure to use.
    411  * Copies data from transport buffer, and calls callback with appropriate
    412  * parameters.
    413  */
    414 void batch_call_in(batch_t *instance)
    415 {
    416         assert(instance);
    417         assert(instance->callback_in);
    418 
    419         /* We are data in, we need data */
    420         memcpy(instance->buffer, instance->transport_buffer,
    421             instance->buffer_size);
    422 
    423         int err = instance->error;
    424         usb_log_debug("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n",
    425             instance, instance->transfer_type, str_error(err), err,
    426             instance->transfered_size);
    427 
    428         instance->callback_in(
    429             instance->fun, err, instance->transfered_size, instance->arg);
    430 }
    431 /*----------------------------------------------------------------------------*/
    432 /** Get error status and call callback out.
    433  *
    434  * @param[in] instance Batch structure to use.
    435  */
    436 void batch_call_out(batch_t *instance)
    437 {
    438         assert(instance);
    439         assert(instance->callback_out);
    440 
    441         int err = instance->error;
    442         usb_log_debug("Batch(%p) callback OUT(type:%d): %s(%d).\n",
    443             instance, instance->transfer_type, str_error(err), err);
    444         instance->callback_out(instance->fun,
    445             err, instance->arg);
     403            data->tds[packet].status);
     404}
     405/*----------------------------------------------------------------------------*/
     406qh_t * batch_qh(batch_t *instance)
     407{
     408        assert(instance);
     409        uhci_batch_t *data = instance->private_data;
     410        assert(data);
     411        return data->qh;
    446412}
    447413/*----------------------------------------------------------------------------*/
     
    475441{
    476442        assert(instance);
     443        uhci_batch_t *data = instance->private_data;
     444        assert(data);
    477445        usb_log_debug("Batch(%p) disposing.\n", instance);
    478446        /* free32 is NULL safe */
    479         free32(instance->tds);
    480         free32(instance->qh);
     447        free32(data->tds);
     448        free32(data->qh);
    481449        free32(instance->setup_buffer);
    482450        free32(instance->transport_buffer);
     451        free(data);
    483452        free(instance);
    484453}
  • uspace/drv/uhci-hcd/batch.h

    re387d0f rf8e1a2c  
    3939#include <usbhc_iface.h>
    4040#include <usb/usb.h>
     41#include <usb/host/device_keeper.h>
     42#include <usb/host/batch.h>
    4143
    42 #include "uhci_struct/transfer_descriptor.h"
    4344#include "uhci_struct/queue_head.h"
    44 #include "utils/device_keeper.h"
    45 
    46 typedef struct batch
    47 {
    48         link_t link;
    49         usb_speed_t speed;
    50         usb_target_t target;
    51         usb_transfer_type_t transfer_type;
    52         usbhc_iface_transfer_in_callback_t callback_in;
    53         usbhc_iface_transfer_out_callback_t callback_out;
    54         void *arg;
    55         char *transport_buffer;
    56         char *setup_buffer;
    57         size_t setup_size;
    58         char *buffer;
    59         size_t buffer_size;
    60         size_t max_packet_size;
    61         size_t packets;
    62         size_t transfered_size;
    63         int error;
    64         ddf_fun_t *fun;
    65         qh_t *qh;
    66         td_t *tds;
    67         void (*next_step)(struct batch*);
    68         device_keeper_t *manager;
    69 } batch_t;
    7045
    7146batch_t * batch_get(
     
    8762void batch_dispose(batch_t *instance);
    8863
    89 void batch_abort(batch_t *instance);
    90 
    9164bool batch_is_complete(batch_t *instance);
    9265
     
    10275
    10376void batch_bulk_out(batch_t *instance);
     77
     78qh_t * batch_qh(batch_t *instance);
    10479#endif
    10580/**
  • uspace/drv/uhci-hcd/iface.c

    re387d0f rf8e1a2c  
    4141#include "iface.h"
    4242#include "uhci_hc.h"
    43 #include "utils/device_keeper.h"
    4443
    4544/** Reserve default address interface function
  • uspace/drv/uhci-hcd/transfer_list.c

    re387d0f rf8e1a2c  
    9898        usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
    9999
    100         const uint32_t pa = addr_to_phys(batch->qh);
     100        const uint32_t pa = addr_to_phys(batch_qh(batch));
    101101        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    102102
    103103        /* New batch will be added to the end of the current list
    104104         * so set the link accordingly */
    105         qh_set_next_qh(batch->qh, instance->queue_head->next);
     105        qh_set_next_qh(batch_qh(batch), instance->queue_head->next);
    106106
    107107        fibril_mutex_lock(&instance->guard);
     
    117117                batch_t *last = list_get_instance(
    118118                    instance->batch_list.prev, batch_t, link);
    119                 qh_set_next_qh(last->qh, pa);
     119                qh_set_next_qh(batch_qh(last), pa);
    120120        }
    121121        /* Add to the driver list */
     
    178178                batch_t *batch = list_get_instance(current, batch_t, link);
    179179                transfer_list_remove_batch(instance, batch);
    180                 batch_abort(batch);
     180                batch_finish(batch, EIO);
    181181        }
    182182        fibril_mutex_unlock(&instance->guard);
     
    194194{
    195195        assert(instance);
     196        assert(instance->queue_head);
    196197        assert(batch);
    197         assert(instance->queue_head);
    198         assert(batch->qh);
     198        assert(batch_qh(batch));
    199199        usb_log_debug2(
    200200            "Queue %s: removing batch(%p).\n", instance->name, batch);
     
    204204        if (batch->link.prev == &instance->batch_list) {
    205205                /* I'm the first one here */
    206                 qh_set_element_qh(instance->queue_head, batch->qh->next);
     206                qh_set_element_qh(instance->queue_head, batch_qh(batch)->next);
    207207                pos = "FIRST";
    208208        } else {
    209209                batch_t *prev =
    210210                    list_get_instance(batch->link.prev, batch_t, link);
    211                 qh_set_next_qh(prev->qh, batch->qh->next);
     211                qh_set_next_qh(batch_qh(prev), batch_qh(batch)->next);
    212212                pos = "NOT FIRST";
    213213        }
     
    215215        list_remove(&batch->link);
    216216        usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n",
    217             batch, pos, instance->name, batch->qh->next);
     217            batch, pos, instance->name, batch_qh(batch)->next);
    218218}
    219219/**
  • uspace/drv/uhci-hcd/uhci_hc.h

    re387d0f rf8e1a2c  
    4242
    4343#include <usbhc_iface.h>
     44#include <usb/host/device_keeper.h>
    4445
    4546#include "batch.h"
    4647#include "transfer_list.h"
    47 #include "utils/device_keeper.h"
    4848
    4949typedef struct uhci_regs {
  • uspace/lib/usb/Makefile

    re387d0f rf8e1a2c  
    4949        src/request.c \
    5050        src/usb.c \
    51         src/usbdevice.c
     51        src/usbdevice.c \
     52        src/host/device_keeper.c \
     53        src/host/batch.c
    5254
    5355include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usb/include/usb/host/device_keeper.h

    re387d0f rf8e1a2c  
    2727 */
    2828
    29 /** @addtogroup drvusbuhcihc
     29/** @addtogroup libusb
    3030 * @{
    3131 */
     
    3333 * @brief UHCI driver
    3434 */
    35 #ifndef UTILS_DEVICE_KEEPER_H
    36 #define UTILS_DEVICE_KEEPER_H
     35#ifndef LIBUSB_HOST_DEVICE_KEEPER_H
     36#define LIBUSB_HOST_DEVICE_KEEPER_H
    3737#include <devman.h>
    3838#include <fibril_synch.h>
  • uspace/lib/usb/src/host/device_keeper.c

    re387d0f rf8e1a2c  
    2727 */
    2828
    29 /** @addtogroup drvusbuhcihc
     29/** @addtogroup libusb
    3030 * @{
    3131 */
     
    3636#include <errno.h>
    3737#include <usb/debug.h>
    38 
    39 #include "device_keeper.h"
     38#include <usb/host/device_keeper.h>
    4039
    4140/*----------------------------------------------------------------------------*/
  • uspace/lib/usb/src/pipes.c

    re387d0f rf8e1a2c  
    4242#include <assert.h>
    4343
     44#define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
     45
    4446/** Tell USB address assigned to given device.
    4547 *
     
    150152        }
    151153
    152         my_address = get_my_address(parent_phone, dev);
    153         if (my_address < 0) {
    154                 rc = my_address;
    155                 goto leave;
    156         }
     154        /*
     155         * Asking for "my" address may require several attempts.
     156         * That is because following scenario may happen:
     157         *  - parent driver (i.e. driver of parent device) announces new device
     158         *    and devman launches current driver
     159         *  - parent driver is preempted and thus does not send address-handle
     160         *    binding to HC driver
     161         *  - this driver gets here and wants the binding
     162         *  - the HC does not know the binding yet and thus it answers ENOENT
     163         *  So, we need to wait for the HC to learn the binding.
     164         */
     165        do {
     166                my_address = get_my_address(parent_phone, dev);
     167
     168                if (my_address == ENOENT) {
     169                        /* Be nice, let other fibrils run and try again. */
     170                        async_usleep(IPC_AGAIN_DELAY);
     171                } else if (my_address < 0) {
     172                        /* Some other problem, no sense trying again. */
     173                        rc = my_address;
     174                        goto leave;
     175                }
     176
     177        } while (my_address < 0);
    157178
    158179        rc = usb_device_connection_initialize(connection,
Note: See TracChangeset for help on using the changeset viewer.