Changeset 2cc6e97 in mainline


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

Location:
uspace
Files:
7 edited

Legend:

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

    r910ca3f r2cc6e97  
    4343#include "hw_struct/transfer_descriptor.h"
    4444
    45 typedef struct ohci_batch {
     45typedef struct ohci_transfer_batch {
    4646        ed_t *ed;
    4747        td_t *tds;
    4848        size_t td_count;
    49 } ohci_batch_t;
     49} ohci_transfer_batch_t;
     50
     51static void ohci_transfer_batch_dispose(void *ohci_batch)
     52{
     53        //TODO: add buffer disposal
     54        ohci_transfer_batch_t *instance = ohci_batch;
     55        assert(instance);
     56        free32(instance->ed);
     57        free32(instance->tds);
     58}
    5059
    5160static void batch_control(usb_transfer_batch_t *instance,
    5261    usb_direction_t data_dir, usb_direction_t status_dir);
    5362static void batch_data(usb_transfer_batch_t *instance);
    54 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
    55 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
    5663
    5764#define DEFAULT_ERROR_COUNT 3
     
    6572                usb_log_error(message); \
    6673                if (instance) { \
    67                         batch_dispose(instance); \
     74                        usb_transfer_batch_dispose(instance); \
    6875                } \
    6976                return NULL; \
     
    7481            "Failed to allocate batch instance.\n");
    7582        usb_transfer_batch_init(instance, ep, buffer, NULL, buffer_size,
    76             NULL, setup_size, func_in, func_out, arg, fun, NULL);
    77 
    78         ohci_batch_t *data = malloc(sizeof(ohci_batch_t));
     83            NULL, setup_size, func_in, func_out, arg, fun, NULL,
     84            ohci_transfer_batch_dispose);
     85
     86        ohci_transfer_batch_t *data = malloc(sizeof(ohci_transfer_batch_t));
    7987        CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
    80         bzero(data, sizeof(ohci_batch_t));
     88        bzero(data, sizeof(ohci_transfer_batch_t));
    8189        instance->private_data = data;
    8290
     
    113121}
    114122/*----------------------------------------------------------------------------*/
    115 void batch_dispose(usb_transfer_batch_t *instance)
    116 {
    117         assert(instance);
    118         ohci_batch_t *data = instance->private_data;
    119         assert(data);
    120         free32(data->ed);
    121         free32(data->tds);
    122         free32(instance->setup_buffer);
    123         free32(instance->data_buffer);
    124         free(data);
    125         free(instance);
    126 }
    127 /*----------------------------------------------------------------------------*/
    128123bool batch_is_complete(usb_transfer_batch_t *instance)
    129124{
    130125        assert(instance);
    131         ohci_batch_t *data = instance->private_data;
     126        ohci_transfer_batch_t *data = instance->private_data;
    132127        assert(data);
    133128        size_t tds = data->td_count - 1;
     
    163158        /* We are data out, we are supposed to provide data */
    164159        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    165         instance->next_step = batch_call_out_and_dispose;
     160        instance->next_step = usb_transfer_batch_call_out_and_dispose;
    166161        batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN);
    167162        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     
    171166{
    172167        assert(instance);
    173         instance->next_step = batch_call_in_and_dispose;
     168        instance->next_step = usb_transfer_batch_call_in_and_dispose;
    174169        batch_control(instance, USB_DIRECTION_IN, USB_DIRECTION_OUT);
    175170        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
     
    179174{
    180175        assert(instance);
    181         instance->next_step = batch_call_in_and_dispose;
     176        instance->next_step = usb_transfer_batch_call_in_and_dispose;
    182177        batch_data(instance);
    183178        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
     
    189184        /* We are data out, we are supposed to provide data */
    190185        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    191         instance->next_step = batch_call_out_and_dispose;
     186        instance->next_step = usb_transfer_batch_call_out_and_dispose;
    192187        batch_data(instance);
    193188        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
     
    197192{
    198193        assert(instance);
    199         instance->next_step = batch_call_in_and_dispose;
     194        instance->next_step = usb_transfer_batch_call_in_and_dispose;
    200195        batch_data(instance);
    201196        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     
    205200{
    206201        assert(instance);
    207         instance->next_step = batch_call_in_and_dispose;
     202        instance->next_step = usb_transfer_batch_call_in_and_dispose;
    208203        batch_data(instance);
    209204        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     
    213208{
    214209        assert(instance);
    215         ohci_batch_t *data = instance->private_data;
     210        ohci_transfer_batch_t *data = instance->private_data;
    216211        assert(data);
    217212        return data->ed;
     
    222217{
    223218        assert(instance);
    224         ohci_batch_t *data = instance->private_data;
     219        ohci_transfer_batch_t *data = instance->private_data;
    225220        assert(data);
    226221        ed_init(data->ed, instance->ep);
     
    270265{
    271266        assert(instance);
    272         ohci_batch_t *data = instance->private_data;
     267        ohci_transfer_batch_t *data = instance->private_data;
    273268        assert(data);
    274269        ed_init(data->ed, instance->ep);
     
    299294        }
    300295}
    301 /*----------------------------------------------------------------------------*/
    302 /** Helper function calls callback and correctly disposes of batch structure.
    303  *
    304  * @param[in] instance Batch structure to use.
    305  */
    306 void batch_call_in_and_dispose(usb_transfer_batch_t *instance)
    307 {
    308         assert(instance);
    309         usb_transfer_batch_call_in(instance);
    310         batch_dispose(instance);
    311 }
    312 /*----------------------------------------------------------------------------*/
    313 /** Helper function calls callback and correctly disposes of batch structure.
    314  *
    315  * @param[in] instance Batch structure to use.
    316  */
    317 void batch_call_out_and_dispose(usb_transfer_batch_t *instance)
    318 {
    319         assert(instance);
    320         usb_transfer_batch_call_out(instance);
    321         batch_dispose(instance);
    322 }
    323296/**
    324297 * @}
  • uspace/drv/ohci/batch.h

    r910ca3f r2cc6e97  
    5050    void *arg);
    5151
    52 void batch_dispose(usb_transfer_batch_t *instance);
    53 
    5452bool batch_is_complete(usb_transfer_batch_t *instance);
    5553
  • uspace/drv/ohci/iface.c

    r910ca3f r2cc6e97  
    228228        ret = hc_schedule(hc, batch);
    229229        if (ret != EOK) {
    230                 batch_dispose(batch);
     230                usb_transfer_batch_dispose(batch);
    231231        }
    232232        return ret;
     
    262262        ret = hc_schedule(hc, batch);
    263263        if (ret != EOK) {
    264                 batch_dispose(batch);
     264                usb_transfer_batch_dispose(batch);
    265265        }
    266266        return ret;
     
    296296        ret = hc_schedule(hc, batch);
    297297        if (ret != EOK) {
    298                 batch_dispose(batch);
     298                usb_transfer_batch_dispose(batch);
    299299        }
    300300        return ret;
     
    330330        ret = hc_schedule(hc, batch);
    331331        if (ret != EOK) {
    332                 batch_dispose(batch);
     332                usb_transfer_batch_dispose(batch);
    333333        }
    334334        return ret;
     
    370370        ret = hc_schedule(hc, batch);
    371371        if (ret != EOK) {
    372                 batch_dispose(batch);
     372                usb_transfer_batch_dispose(batch);
    373373        }
    374374        return ret;
     
    409409        ret = hc_schedule(hc, batch);
    410410        if (ret != EOK) {
    411                 batch_dispose(batch);
     411                usb_transfer_batch_dispose(batch);
    412412        }
    413413        return ret;
  • 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 * @}
  • uspace/drv/uhci-hcd/iface.c

    r910ca3f r2cc6e97  
    195195        ret = hc_schedule(hc, batch);
    196196        if (ret != EOK) {
    197                 batch_dispose(batch);
     197                usb_transfer_batch_dispose(batch);
    198198        }
    199199        return ret;
     
    223223        ret = hc_schedule(hc, batch);
    224224        if (ret != EOK) {
    225                 batch_dispose(batch);
     225                usb_transfer_batch_dispose(batch);
    226226        }
    227227        return ret;
     
    251251        ret = hc_schedule(hc, batch);
    252252        if (ret != EOK) {
    253                 batch_dispose(batch);
     253                usb_transfer_batch_dispose(batch);
    254254        }
    255255        return ret;
     
    279279        ret = hc_schedule(hc, batch);
    280280        if (ret != EOK) {
    281                 batch_dispose(batch);
     281                usb_transfer_batch_dispose(batch);
    282282        }
    283283        return ret;
     
    312312        ret = hc_schedule(hc, batch);
    313313        if (ret != EOK) {
    314                 batch_dispose(batch);
     314                usb_transfer_batch_dispose(batch);
    315315        }
    316316        return ret;
     
    344344        ret = hc_schedule(hc, batch);
    345345        if (ret != EOK) {
    346                 batch_dispose(batch);
     346                usb_transfer_batch_dispose(batch);
    347347        }
    348348        return ret;
  • uspace/lib/usb/include/usb/host/batch.h

    r910ca3f r2cc6e97  
    5858        ddf_fun_t *fun;
    5959        void *private_data;
     60        void (*private_data_dtor)(void *p_data);
    6061};
    6162
    6263void usb_transfer_batch_init(
    6364    usb_transfer_batch_t *instance,
    64                 endpoint_t *ep,
     65    endpoint_t *ep,
    6566    char *buffer,
    6667    char *data_buffer,
     
    7273    void *arg,
    7374    ddf_fun_t *fun,
    74     void *private_data
     75    void *private_data,
     76    void (*private_data_dtor)(void *p_data)
    7577);
    7678
    77 static inline usb_transfer_batch_t *usb_transfer_batch_from_link(link_t *l)
    78 {
    79         assert(l);
    80         return list_get_instance(l, usb_transfer_batch_t, link);
    81 }
    82 
    83 void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
    84 void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
     79void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance);
     80void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance);
    8581void usb_transfer_batch_finish(usb_transfer_batch_t *instance);
     82void usb_transfer_batch_dispose(usb_transfer_batch_t *instance);
    8683
    8784static inline void usb_transfer_batch_finish_error(
     
    9390}
    9491
     92static inline usb_transfer_batch_t *usb_transfer_batch_from_link(link_t *l)
     93{
     94        assert(l);
     95        return list_get_instance(l, usb_transfer_batch_t, link);
     96}
     97
    9598#endif
    9699/**
  • uspace/lib/usb/src/host/batch.c

    r910ca3f r2cc6e97  
    3939#include <usb/host/batch.h>
    4040
     41void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
     42void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
     43
    4144void usb_transfer_batch_init(
    4245    usb_transfer_batch_t *instance,
    43                 endpoint_t *ep,
     46    endpoint_t *ep,
    4447    char *buffer,
    4548    char *data_buffer,
     
    5154    void *arg,
    5255    ddf_fun_t *fun,
    53     void *private_data
     56    void *private_data,
     57    void (*private_data_dtor)(void *p_data)
    5458    )
    5559{
     
    6771        instance->fun = fun;
    6872        instance->private_data = private_data;
     73        instance->private_data_dtor = private_data_dtor;
    6974        instance->transfered_size = 0;
    7075        instance->next_step = NULL;
    7176        instance->error = EOK;
    7277        endpoint_use(instance->ep);
     78}
     79/*----------------------------------------------------------------------------*/
     80/** Helper function, calls callback and correctly destroys batch structure.
     81 *
     82 * @param[in] instance Batch structure to use.
     83 */
     84void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance)
     85{
     86        assert(instance);
     87        usb_transfer_batch_call_in(instance);
     88        usb_transfer_batch_dispose(instance);
     89}
     90/*----------------------------------------------------------------------------*/
     91/** Helper function calls callback and correctly destroys batch structure.
     92 *
     93 * @param[in] instance Batch structure to use.
     94 */
     95void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance)
     96{
     97        assert(instance);
     98        usb_transfer_batch_call_out(instance);
     99        usb_transfer_batch_dispose(instance);
    73100}
    74101/*----------------------------------------------------------------------------*/
     
    129156            instance->error, instance->arg);
    130157}
     158/*----------------------------------------------------------------------------*/
     159/** Correctly dispose all used data structures.
     160 *
     161 * @param[in] instance Batch structure to use.
     162 */
     163void usb_transfer_batch_dispose(usb_transfer_batch_t *instance)
     164{
     165        assert(instance);
     166        usb_log_debug("Batch(%p) disposing.\n", instance);
     167        if (instance->private_data) {
     168                assert(instance->private_data_dtor);
     169                instance->private_data_dtor(instance->private_data);
     170        }
     171        free(instance);
     172}
    131173/**
    132174 * @}
Note: See TracChangeset for help on using the changeset viewer.