Ignore:
File:
1 edited

Legend:

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

    r41b96b4 r1387692  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbohcihc
     28/** @addtogroup drvusbohci
    2929 * @{
    3030 */
     
    3939
    4040#include "batch.h"
     41#include "utils/malloc32.h"
    4142
    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);
     43static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
     44static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
    4645
    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,
     46#define DEFAULT_ERROR_COUNT 3
     47usb_transfer_batch_t * batch_get(
     48    ddf_fun_t *fun,
     49                usb_target_t target,
     50    usb_transfer_type_t transfer_type,
     51                size_t max_packet_size,
     52    usb_speed_t speed,
     53                char *buffer,
     54                size_t buffer_size,
     55                char *setup_buffer,
     56                size_t setup_size,
    7357    usbhc_iface_transfer_in_callback_t func_in,
    74     usbhc_iface_transfer_out_callback_t func_out, void *arg
    75     )
     58    usbhc_iface_transfer_out_callback_t func_out,
     59                void *arg,
     60                usb_device_keeper_t *manager
     61                )
    7662{
    77         assert(func_in == NULL || func_out == NULL);
    78         assert(func_in != NULL || func_out != NULL);
     63#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
     64        if (ptr == NULL) { \
     65                usb_log_error(message); \
     66                if (instance) { \
     67                        batch_dispose(instance); \
     68                } \
     69                return NULL; \
     70        } else (void)0
    7971
    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));
     72        usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
    9073        CHECK_NULL_DISPOSE_RETURN(instance,
    9174            "Failed to allocate batch instance.\n");
    92         bzero(instance, sizeof(batch_t));
     75        usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size,
     76            buffer, NULL, buffer_size, NULL, setup_size, func_in,
     77            func_out, arg, fun, NULL);
    9378
    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         }
     79        if (buffer_size > 0) {
     80                instance->transport_buffer = malloc32(buffer_size);
     81                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
     82                    "Failed to allocate device accessible buffer.\n");
     83        }
    10084
    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         }
     85        if (setup_size > 0) {
     86                instance->setup_buffer = malloc32(setup_size);
     87                CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
     88                    "Failed to allocate device accessible setup buffer.\n");
     89                memcpy(instance->setup_buffer, setup_buffer, setup_size);
     90        }
    10891
    109         link_initialize(&instance->link);
    11092
    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);
    12593        return instance;
    12694}
    12795/*----------------------------------------------------------------------------*/
    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)
     96void batch_dispose(usb_transfer_batch_t *instance)
    13497{
    13598        assert(instance);
    136         instance->error = error;
    137         instance->next_step(instance);
     99        free32(instance->transport_buffer);
     100        free32(instance->setup_buffer);
     101        free(instance);
    138102}
    139103/*----------------------------------------------------------------------------*/
    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)
     104void batch_control_write(usb_transfer_batch_t *instance)
    163105{
    164106        assert(instance);
     
    171113}
    172114/*----------------------------------------------------------------------------*/
    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)
     115void batch_control_read(usb_transfer_batch_t *instance)
    180116{
    181117        assert(instance);
    182118        instance->next_step = batch_call_in_and_dispose;
    183119        /* TODO: implement */
    184         usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
     120        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
    185121}
    186122/*----------------------------------------------------------------------------*/
    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)
     123void batch_interrupt_in(usb_transfer_batch_t *instance)
    194124{
    195125        assert(instance);
     126        instance->direction = USB_DIRECTION_IN;
     127        instance->next_step = batch_call_in_and_dispose;
    196128        /* TODO: implement */
    197         instance->next_step = batch_call_in_and_dispose;
    198129        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
    199130}
    200131/*----------------------------------------------------------------------------*/
    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)
     132void batch_interrupt_out(usb_transfer_batch_t *instance)
    208133{
    209134        assert(instance);
     135        instance->direction = USB_DIRECTION_OUT;
    210136        /* We are data out, we are supposed to provide data */
    211137        memcpy(instance->transport_buffer, instance->buffer,
     
    216142}
    217143/*----------------------------------------------------------------------------*/
    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)
     144void batch_bulk_in(usb_transfer_batch_t *instance)
    225145{
    226146        assert(instance);
     147        instance->direction = USB_DIRECTION_IN;
    227148        instance->next_step = batch_call_in_and_dispose;
    228149        /* TODO: implement */
     
    230151}
    231152/*----------------------------------------------------------------------------*/
    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)
     153void batch_bulk_out(usb_transfer_batch_t *instance)
    239154{
    240155        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;
     156        instance->direction = USB_DIRECTION_IN;
     157        instance->next_step = batch_call_in_and_dispose;
    245158        /* 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);
     159        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
    287160}
    288161/*----------------------------------------------------------------------------*/
     
    291164 * @param[in] instance Batch structure to use.
    292165 */
    293 void batch_call_in_and_dispose(batch_t *instance)
     166void batch_call_in_and_dispose(usb_transfer_batch_t *instance)
    294167{
    295168        assert(instance);
    296         batch_call_in(instance);
     169        usb_transfer_batch_call_in(instance);
    297170        batch_dispose(instance);
    298171}
     
    302175 * @param[in] instance Batch structure to use.
    303176 */
    304 void batch_call_out_and_dispose(batch_t *instance)
     177void batch_call_out_and_dispose(usb_transfer_batch_t *instance)
    305178{
    306179        assert(instance);
    307         batch_call_out(instance);
     180        usb_transfer_batch_call_out(instance);
    308181        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);
    324182}
    325183/**
Note: See TracChangeset for help on using the changeset viewer.