Ignore:
File:
1 edited

Legend:

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

    r81dce9f r41b96b4  
    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 * @}
Note: See TracChangeset for help on using the changeset viewer.