Changes in / [2e1d5d70:f0fdc7d] in mainline


Ignore:
Location:
uspace
Files:
2 added
4 deleted
11 edited

Legend:

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

    r2e1d5d70 rf0fdc7d  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbohci
     28/** @addtogroup drvusbohcihc
    2929 * @{
    3030 */
     
    4040#include "batch.h"
    4141
    42 #define DEFAULT_ERROR_COUNT 3
    43 
     42static void batch_call_in(batch_t *instance);
     43static void batch_call_out(batch_t *instance);
     44static void batch_call_in_and_dispose(batch_t *instance);
     45static void batch_call_out_and_dispose(batch_t *instance);
     46
     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 */
     69batch_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 */
     133void 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 */
     149bool 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 */
     162void 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 */
     179void 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 */
     193void 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 */
     207void 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 */
     224void 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 */
     238void 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 */
     255void 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 */
     277void 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 */
     293void 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 */
     304void 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 */
     315void 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}
    44325/**
    45326 * @}
  • uspace/drv/ohci/batch.h

    r2e1d5d70 rf0fdc7d  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbohci
     28/** @addtogroup drvusbuhcihc
    2929 * @{
    3030 */
    3131/** @file
    32  * @brief OHCI driver USB transaction structure
     32 * @brief UHCI driver USB transaction structure
    3333 */
    34 #ifndef DRV_OHCI_BATCH_H
    35 #define DRV_OHCI_BATCH_H
     34#ifndef DRV_UHCI_BATCH_H
     35#define DRV_UHCI_BATCH_H
    3636
     37#include <adt/list.h>
    3738
    3839#include <usbhc_iface.h>
    3940#include <usb/usb.h>
    40 #include <usb/host/device_keeper.h>
    41 #include <usb/host/batch.h>
     41
     42typedef 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;
    4263
    4364batch_t * batch_get(
     
    5374    usbhc_iface_transfer_in_callback_t func_in,
    5475    usbhc_iface_transfer_out_callback_t func_out,
    55                 void *arg,
    56                 device_keeper_t *manager
     76                void *arg
    5777                );
    5878
    5979void batch_dispose(batch_t *instance);
     80
     81void batch_finish(batch_t *instance, int error);
     82
     83bool batch_is_complete(batch_t *instance);
    6084
    6185void batch_control_write(batch_t *instance);
  • uspace/drv/ohci/hc_iface.c

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

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

    r2e1d5d70 rf0fdc7d  
    4040        uhci_rh.c \
    4141        uhci_struct/transfer_descriptor.c \
     42        utils/device_keeper.c \
    4243        pci.c \
    4344        batch.c
  • uspace/drv/uhci-hcd/batch.c

    r2e1d5d70 rf0fdc7d  
    4242#include "uhci_hc.h"
    4343#include "utils/malloc32.h"
    44 #include "uhci_struct/transfer_descriptor.h"
    4544
    4645#define DEFAULT_ERROR_COUNT 3
    47 
    48 typedef struct uhci_batch {
    49         qh_t *qh;
    50         td_t *tds;
    51         size_t packets;
    52         device_keeper_t *manager;
    53 } uhci_batch_t;
    5446
    5547static void batch_control(batch_t *instance,
    5648    usb_packet_id data_stage, usb_packet_id status_stage);
    5749static void batch_data(batch_t *instance, usb_packet_id pid);
     50static void batch_call_in(batch_t *instance);
     51static void batch_call_out(batch_t *instance);
    5852static void batch_call_in_and_dispose(batch_t *instance);
    5953static void batch_call_out_and_dispose(batch_t *instance);
     
    8478batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    8579    usb_transfer_type_t transfer_type, size_t max_packet_size,
    86     usb_speed_t speed, char *buffer, size_t buffer_size,
     80    usb_speed_t speed, char *buffer, size_t size,
    8781    char* setup_buffer, size_t setup_size,
    8882    usbhc_iface_transfer_in_callback_t func_in,
     
    106100        CHECK_NULL_DISPOSE_RETURN(instance,
    107101            "Failed to allocate batch instance.\n");
    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;
     102        bzero(instance, sizeof(batch_t));
     103
     104        instance->qh = malloc32(sizeof(qh_t));
     105        CHECK_NULL_DISPOSE_RETURN(instance->qh,
     106            "Failed to allocate batch queue head.\n");
     107        qh_init(instance->qh);
     108
     109        instance->packets = (size + max_packet_size - 1) / max_packet_size;
    121110        if (transfer_type == USB_TRANSFER_CONTROL) {
    122                 data->packets += 2;
    123         }
    124 
    125         data->tds = malloc32(sizeof(td_t) * data->packets);
     111                instance->packets += 2;
     112        }
     113
     114        instance->tds = malloc32(sizeof(td_t) * instance->packets);
    126115        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,
    132             "Failed to allocate batch queue head.\n");
    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);
     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);
    138121                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
    139122                    "Failed to allocate device accessible buffer.\n");
     
    147130        }
    148131
     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
    149150        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    150151            instance, target.address, target.endpoint);
     
    152153}
    153154/*----------------------------------------------------------------------------*/
     155/** Mark batch as failed and continue with next step.
     156 *
     157 * @param[in] instance Batch structure to use.
     158 *
     159 */
     160void batch_abort(batch_t *instance)
     161{
     162        assert(instance);
     163        instance->error = EIO;
     164        instance->next_step(instance);
     165}
     166/*----------------------------------------------------------------------------*/
    154167/** Check batch TDs for activity.
    155168 *
     
    164177{
    165178        assert(instance);
    166         uhci_batch_t *data = instance->private_data;
    167         assert(data);
    168 
    169179        usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",
    170             instance, data->packets);
     180            instance, instance->packets);
    171181        instance->transfered_size = 0;
    172182        size_t i = 0;
    173         for (;i < data->packets; ++i) {
    174                 if (td_is_active(&data->tds[i])) {
     183        for (;i < instance->packets; ++i) {
     184                if (td_is_active(&instance->tds[i])) {
    175185                        return false;
    176186                }
    177187
    178                 instance->error = td_status(&data->tds[i]);
     188                instance->error = td_status(&instance->tds[i]);
    179189                if (instance->error != EOK) {
    180190                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    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]));
     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]));
    186196                        if (i > 0)
    187197                                goto substract_ret;
     
    189199                }
    190200
    191                 instance->transfered_size += td_act_size(&data->tds[i]);
    192                 if (td_is_short(&data->tds[i]))
     201                instance->transfered_size += td_act_size(&instance->tds[i]);
     202                if (td_is_short(&instance->tds[i]))
    193203                        goto substract_ret;
    194204        }
     
    302312{
    303313        assert(instance);
    304         uhci_batch_t *data = instance->private_data;
    305         assert(data);
    306 
    307314        const bool low_speed = instance->speed == USB_SPEED_LOW;
    308         int toggle = device_keeper_get_toggle(data->manager, instance->target);
     315        int toggle =
     316            device_keeper_get_toggle(instance->manager, instance->target);
    309317        assert(toggle == 0 || toggle == 1);
    310318
     
    312320        size_t remain_size = instance->buffer_size;
    313321        while (remain_size > 0) {
    314                 char *trans_data =
     322                char *data =
    315323                    instance->transport_buffer + instance->buffer_size
    316324                    - remain_size;
     
    320328                    remain_size : instance->max_packet_size;
    321329
    322                 td_t *next_packet = (packet + 1 < data->packets)
    323                     ? &data->tds[packet + 1] : NULL;
    324 
    325                 assert(packet < data->packets);
     330                td_t *next_packet = (packet + 1 < instance->packets)
     331                    ? &instance->tds[packet + 1] : NULL;
     332
     333                assert(packet < instance->packets);
    326334                assert(packet_size <= remain_size);
    327335
    328336                td_init(
    329                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    330                     toggle, false, low_speed, instance->target, pid, trans_data,
     337                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     338                    toggle, false, low_speed, instance->target, pid, data,
    331339                    next_packet);
    332340
     
    336344                ++packet;
    337345        }
    338         td_set_ioc(&data->tds[packet - 1]);
    339         device_keeper_set_toggle(data->manager, instance->target, toggle);
     346        td_set_ioc(&instance->tds[packet - 1]);
     347        device_keeper_set_toggle(instance->manager, instance->target, toggle);
    340348}
    341349/*----------------------------------------------------------------------------*/
     
    355363{
    356364        assert(instance);
    357         uhci_batch_t *data = instance->private_data;
    358         assert(data);
    359         assert(data->packets >= 2);
    360365
    361366        const bool low_speed = instance->speed == USB_SPEED_LOW;
    362367        int toggle = 0;
    363368        /* setup stage */
    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]);
     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]);
    368372
    369373        /* data stage */
     
    371375        size_t remain_size = instance->buffer_size;
    372376        while (remain_size > 0) {
    373                 char *control_data =
     377                char *data =
    374378                    instance->transport_buffer + instance->buffer_size
    375379                    - remain_size;
     
    382386
    383387                td_init(
    384                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     388                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    385389                    toggle, false, low_speed, instance->target, data_stage,
    386                     control_data, &data->tds[packet + 1]);
     390                    data, &instance->tds[packet + 1]);
    387391
    388392                ++packet;
    389                 assert(packet < data->packets);
     393                assert(packet < instance->packets);
    390394                assert(packet_size <= remain_size);
    391395                remain_size -= packet_size;
     
    393397
    394398        /* status stage */
    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 
     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]);
    402404        usb_log_debug2("Control last TD status: %x.\n",
    403             data->tds[packet].status);
    404 }
    405 /*----------------------------------------------------------------------------*/
    406 qh_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;
     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 */
     414void 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 */
     436void 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);
    412446}
    413447/*----------------------------------------------------------------------------*/
     
    441475{
    442476        assert(instance);
    443         uhci_batch_t *data = instance->private_data;
    444         assert(data);
    445477        usb_log_debug("Batch(%p) disposing.\n", instance);
    446478        /* free32 is NULL safe */
    447         free32(data->tds);
    448         free32(data->qh);
     479        free32(instance->tds);
     480        free32(instance->qh);
    449481        free32(instance->setup_buffer);
    450482        free32(instance->transport_buffer);
    451         free(data);
    452483        free(instance);
    453484}
  • uspace/drv/uhci-hcd/batch.h

    r2e1d5d70 rf0fdc7d  
    3939#include <usbhc_iface.h>
    4040#include <usb/usb.h>
    41 #include <usb/host/device_keeper.h>
    42 #include <usb/host/batch.h>
    4341
     42#include "uhci_struct/transfer_descriptor.h"
    4443#include "uhci_struct/queue_head.h"
     44#include "utils/device_keeper.h"
     45
     46typedef 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;
    4570
    4671batch_t * batch_get(
     
    6287void batch_dispose(batch_t *instance);
    6388
     89void batch_abort(batch_t *instance);
     90
    6491bool batch_is_complete(batch_t *instance);
    6592
     
    75102
    76103void batch_bulk_out(batch_t *instance);
    77 
    78 qh_t * batch_qh(batch_t *instance);
    79104#endif
    80105/**
  • uspace/drv/uhci-hcd/iface.c

    r2e1d5d70 rf0fdc7d  
    4141#include "iface.h"
    4242#include "uhci_hc.h"
     43#include "utils/device_keeper.h"
    4344
    4445/** Reserve default address interface function
  • uspace/drv/uhci-hcd/transfer_list.c

    r2e1d5d70 rf0fdc7d  
    9898        usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
    9999
    100         const uint32_t pa = addr_to_phys(batch_qh(batch));
     100        const uint32_t pa = addr_to_phys(batch->qh);
    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(batch), instance->queue_head->next);
     105        qh_set_next_qh(batch->qh, 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(batch_qh(last), pa);
     119                qh_set_next_qh(last->qh, 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_finish(batch, EIO);
     180                batch_abort(batch);
    181181        }
    182182        fibril_mutex_unlock(&instance->guard);
     
    194194{
    195195        assert(instance);
     196        assert(batch);
    196197        assert(instance->queue_head);
    197         assert(batch);
    198         assert(batch_qh(batch));
     198        assert(batch->qh);
    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(batch)->next);
     206                qh_set_element_qh(instance->queue_head, batch->qh->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(batch_qh(prev), batch_qh(batch)->next);
     211                qh_set_next_qh(prev->qh, batch->qh->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(batch)->next);
     217            batch, pos, instance->name, batch->qh->next);
    218218}
    219219/**
  • uspace/drv/uhci-hcd/uhci_hc.h

    r2e1d5d70 rf0fdc7d  
    4242
    4343#include <usbhc_iface.h>
    44 #include <usb/host/device_keeper.h>
    4544
    4645#include "batch.h"
    4746#include "transfer_list.h"
     47#include "utils/device_keeper.h"
    4848
    4949typedef struct uhci_regs {
  • uspace/lib/usb/Makefile

    r2e1d5d70 rf0fdc7d  
    4949        src/request.c \
    5050        src/usb.c \
    51         src/usbdevice.c \
    52         src/host/device_keeper.c \
    53         src/host/batch.c
     51        src/usbdevice.c
    5452
    5553include $(USPACE_PREFIX)/Makefile.common
Note: See TracChangeset for help on using the changeset viewer.