Changeset 2cc6e97 in mainline for uspace/drv/uhci-hcd/batch.c


Ignore:
Timestamp:
2011-04-12T14:07:02Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3d932af6
Parents:
910ca3f
Message:

Move more functionality to libUSB usb_transfer_batch_t

UHCI uses one device accessible buffer for both structures and data

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/batch.c

    r910ca3f r2cc6e97  
    4545#define DEFAULT_ERROR_COUNT 3
    4646
    47 typedef struct uhci_batch {
     47typedef struct uhci_transfer_batch {
    4848        qh_t *qh;
    4949        td_t *tds;
     50        void *device_buffer;
    5051        size_t td_count;
    51 } uhci_batch_t;
     52} uhci_transfer_batch_t;
     53/*----------------------------------------------------------------------------*/
     54static void uhci_transfer_batch_dispose(void *uhci_batch)
     55{
     56        uhci_transfer_batch_t *instance = uhci_batch;
     57        assert(instance);
     58        free32(instance->device_buffer);
     59        free(instance);
     60}
     61/*----------------------------------------------------------------------------*/
    5262
    5363static void batch_control(usb_transfer_batch_t *instance,
    5464    usb_packet_id data_stage, usb_packet_id status_stage);
    5565static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid);
    56 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
    57 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
    58 
    5966
    6067/** Allocate memory and initialize internal data structure.
     
    8895        if (ptr == NULL) { \
    8996                usb_log_error(message); \
    90                 if (instance) { \
    91                         batch_dispose(instance); \
     97                if (uhci_data) { \
     98                        uhci_transfer_batch_dispose(uhci_data); \
    9299                } \
    93100                return NULL; \
    94101        } else (void)0
    95102
     103        uhci_transfer_batch_t *uhci_data =
     104            malloc(sizeof(uhci_transfer_batch_t));
     105        CHECK_NULL_DISPOSE_RETURN(uhci_data,
     106            "Failed to allocate UHCI batch.\n");
     107        bzero(uhci_data, sizeof(uhci_transfer_batch_t));
     108
     109        uhci_data->td_count =
     110            (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size;
     111        if (ep->transfer_type == USB_TRANSFER_CONTROL) {
     112                uhci_data->td_count += 2;
     113        }
     114
     115        assert((sizeof(td_t) % 16) == 0);
     116        const size_t total_size = (sizeof(td_t) * uhci_data->td_count)
     117            + sizeof(qh_t) + setup_size + buffer_size;
     118        uhci_data->device_buffer = malloc32(total_size);
     119        CHECK_NULL_DISPOSE_RETURN(uhci_data->device_buffer,
     120            "Failed to allocate UHCI buffer.\n");
     121        bzero(uhci_data->device_buffer, total_size);
     122
     123        uhci_data->tds = uhci_data->device_buffer;
     124        uhci_data->qh =
     125            (uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count));
     126
     127        qh_init(uhci_data->qh);
     128        qh_set_element_td(uhci_data->qh, addr_to_phys(uhci_data->tds));
     129
    96130        usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
    97131        CHECK_NULL_DISPOSE_RETURN(instance,
    98132            "Failed to allocate batch instance.\n");
     133        void *setup =
     134            uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count)
     135            + sizeof(qh_t);
     136        void *data_buffer = setup + setup_size;
    99137        usb_target_t target =
    100138            { .address = ep->address, .endpoint = ep->endpoint };
    101         usb_transfer_batch_init(instance, ep,
    102             buffer, NULL, buffer_size, NULL, setup_size,
    103             func_in, func_out, arg, fun, NULL);
    104 
    105 
    106         uhci_batch_t *data = malloc(sizeof(uhci_batch_t));
    107         CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
    108         bzero(data, sizeof(uhci_batch_t));
    109         instance->private_data = data;
    110 
    111         data->td_count =
    112             (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size;
    113         if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    114                 data->td_count += 2;
    115         }
    116 
    117         data->tds = malloc32(sizeof(td_t) * data->td_count);
    118         CHECK_NULL_DISPOSE_RETURN(
    119             data->tds, "Failed to allocate transfer descriptors.\n");
    120         bzero(data->tds, sizeof(td_t) * data->td_count);
    121 
    122         data->qh = malloc32(sizeof(qh_t));
    123         CHECK_NULL_DISPOSE_RETURN(data->qh,
    124             "Failed to allocate batch queue head.\n");
    125         qh_init(data->qh);
    126         qh_set_element_td(data->qh, addr_to_phys(data->tds));
    127 
    128         if (buffer_size > 0) {
    129                 instance->data_buffer = malloc32(buffer_size);
    130                 CHECK_NULL_DISPOSE_RETURN(instance->data_buffer,
    131                     "Failed to allocate device accessible buffer.\n");
    132         }
    133 
    134         if (setup_size > 0) {
    135                 instance->setup_buffer = malloc32(setup_size);
    136                 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
    137                     "Failed to allocate device accessible setup buffer.\n");
    138                 memcpy(instance->setup_buffer, setup_buffer, setup_size);
    139         }
    140 
     139        usb_transfer_batch_init(instance, ep, buffer, data_buffer, buffer_size,
     140            setup, setup_size, func_in, func_out, arg, fun,
     141            uhci_data, uhci_transfer_batch_dispose);
     142
     143        memcpy(instance->setup_buffer, setup_buffer, setup_size);
    141144        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    142145            instance, target.address, target.endpoint);
     
    156159{
    157160        assert(instance);
    158         uhci_batch_t *data = instance->private_data;
     161        uhci_transfer_batch_t *data = instance->private_data;
    159162        assert(data);
    160163
     
    203206        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    204207        batch_control(instance, USB_PID_OUT, USB_PID_IN);
    205         instance->next_step = batch_call_out_and_dispose;
     208        instance->next_step = usb_transfer_batch_call_out_and_dispose;
    206209        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
    207210}
     
    217220        assert(instance);
    218221        batch_control(instance, USB_PID_IN, USB_PID_OUT);
    219         instance->next_step = batch_call_in_and_dispose;
     222        instance->next_step = usb_transfer_batch_call_in_and_dispose;
    220223        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    221224}
     
    231234        assert(instance);
    232235        batch_data(instance, USB_PID_IN);
    233         instance->next_step = batch_call_in_and_dispose;
     236        instance->next_step = usb_transfer_batch_call_in_and_dispose;
    234237        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
    235238}
     
    247250        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    248251        batch_data(instance, USB_PID_OUT);
    249         instance->next_step = batch_call_out_and_dispose;
     252        instance->next_step = usb_transfer_batch_call_out_and_dispose;
    250253        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
    251254}
     
    261264        assert(instance);
    262265        batch_data(instance, USB_PID_IN);
    263         instance->next_step = batch_call_in_and_dispose;
     266        instance->next_step = usb_transfer_batch_call_in_and_dispose;
    264267        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
    265268}
     
    277280        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    278281        batch_data(instance, USB_PID_OUT);
    279         instance->next_step = batch_call_out_and_dispose;
     282        instance->next_step = usb_transfer_batch_call_out_and_dispose;
    280283        usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
    281284}
     
    292295{
    293296        assert(instance);
    294         uhci_batch_t *data = instance->private_data;
     297        uhci_transfer_batch_t *data = instance->private_data;
    295298        assert(data);
    296299
     
    344347{
    345348        assert(instance);
    346         uhci_batch_t *data = instance->private_data;
     349        uhci_transfer_batch_t *data = instance->private_data;
    347350        assert(data);
    348351        assert(data->td_count >= 2);
     
    396399{
    397400        assert(instance);
    398         uhci_batch_t *data = instance->private_data;
     401        uhci_transfer_batch_t *data = instance->private_data;
    399402        assert(data);
    400403        return data->qh;
    401404}
    402 /*----------------------------------------------------------------------------*/
    403 /** Helper function, calls callback and correctly destroys batch structure.
    404  *
    405  * @param[in] instance Batch structure to use.
    406  */
    407 void batch_call_in_and_dispose(usb_transfer_batch_t *instance)
    408 {
    409         assert(instance);
    410         usb_transfer_batch_call_in(instance);
    411         batch_dispose(instance);
    412 }
    413 /*----------------------------------------------------------------------------*/
    414 /** Helper function calls callback and correctly destroys batch structure.
    415  *
    416  * @param[in] instance Batch structure to use.
    417  */
    418 void batch_call_out_and_dispose(usb_transfer_batch_t *instance)
    419 {
    420         assert(instance);
    421         usb_transfer_batch_call_out(instance);
    422         batch_dispose(instance);
    423 }
    424 /*----------------------------------------------------------------------------*/
    425 /** Correctly dispose all used data structures.
    426  *
    427  * @param[in] instance Batch structure to use.
    428  */
    429 void batch_dispose(usb_transfer_batch_t *instance)
    430 {
    431         assert(instance);
    432         uhci_batch_t *data = instance->private_data;
    433         assert(data);
    434         usb_log_debug("Batch(%p) disposing.\n", instance);
    435         /* free32 is NULL safe */
    436         free32(data->tds);
    437         free32(data->qh);
    438         free32(instance->setup_buffer);
    439         free32(instance->data_buffer);
    440         free(data);
    441         free(instance);
    442 }
    443405/**
    444406 * @}
Note: See TracChangeset for help on using the changeset viewer.