Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 9c10e51 in mainline


Ignore:
Timestamp:
2011-08-31T22:50:21Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
4e9ecf4
Parents:
f18d82f0
Message:

ohci: use driver specific structure instead of the generic one

ohci: do not create hw structures if communicating with root hub

Location:
uspace/drv/bus/usb/ohci
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/hc.c

    rf18d82f0 r9c10e51  
    289289{
    290290        assert(hcd);
    291         batch_init_ohci(batch);
    292291        hc_t *instance = hcd->private_data;
    293292        assert(instance);
     
    298297                return EOK;
    299298        }
     299        ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch);
     300        if (!ohci_batch)
     301                return ENOMEM;
    300302
    301303        fibril_mutex_lock(&instance->guard);
    302         list_append(&batch->link, &instance->pending_batches);
    303         batch_commit(batch);
     304        list_append(&ohci_batch->link, &instance->pending_batches);
     305        ohci_transfer_batch_commit(ohci_batch);
    304306
    305307        /* Control and bulk schedules need a kick to start working */
     
    341343                    instance->registers->periodic_current);
    342344
    343                 link_t *current = instance->pending_batches.head.next;
    344                 while (current != &instance->pending_batches.head) {
     345                link_t *current = list_first(&instance->pending_batches);
     346                while (current && current != &instance->pending_batches.head) {
    345347                        link_t *next = current->next;
    346                         usb_transfer_batch_t *batch =
    347                             usb_transfer_batch_from_link(current);
    348 
    349                         if (batch_is_complete(batch)) {
     348                        ohci_transfer_batch_t *batch =
     349                            ohci_transfer_batch_from_link(current);
     350
     351                        if (ohci_transfer_batch_is_complete(batch)) {
    350352                                list_remove(current);
    351                                 usb_transfer_batch_finish(batch);
     353                                ohci_transfer_batch_finish_dispose(batch);
    352354                        }
    353355
  • uspace/drv/bus/usb/ohci/ohci_batch.c

    rf18d82f0 r9c10e51  
    4141#include "ohci_endpoint.h"
    4242#include "utils/malloc32.h"
    43 #include "hw_struct/endpoint_descriptor.h"
    44 #include "hw_struct/transfer_descriptor.h"
    45 
    46 static void batch_control_write(usb_transfer_batch_t *instance);
    47 static void batch_control_read(usb_transfer_batch_t *instance);
    48 
    49 static void batch_interrupt_in(usb_transfer_batch_t *instance);
    50 static void batch_interrupt_out(usb_transfer_batch_t *instance);
    51 
    52 static void batch_bulk_in(usb_transfer_batch_t *instance);
    53 static void batch_bulk_out(usb_transfer_batch_t *instance);
    54 
    55 static void batch_setup_control(usb_transfer_batch_t *batch)
     43
     44static void control_write(ohci_transfer_batch_t *instance);
     45static void control_read(ohci_transfer_batch_t *instance);
     46
     47static void interrupt_in(ohci_transfer_batch_t *instance);
     48static void interrupt_out(ohci_transfer_batch_t *instance);
     49
     50static void bulk_in(ohci_transfer_batch_t *instance);
     51static void bulk_out(ohci_transfer_batch_t *instance);
     52
     53static void setup_control(ohci_transfer_batch_t *ohci_batch)
    5654{
    5755        // TODO Find a better way to do this
    58         if (batch->setup_buffer[0] & (1 << 7))
    59                 batch_control_read(batch);
     56        if (ohci_batch->device_buffer[0] & (1 << 7))
     57                control_read(ohci_batch);
    6058        else
    61                 batch_control_write(batch);
    62 }
    63 /*----------------------------------------------------------------------------*/
    64 void (*batch_setup[4][3])(usb_transfer_batch_t*) =
    65 {
    66         { NULL, NULL, batch_setup_control },
     59                control_write(ohci_batch);
     60}
     61/*----------------------------------------------------------------------------*/
     62static void batch_control(ohci_transfer_batch_t *instance,
     63    usb_direction_t data_dir, usb_direction_t status_dir);
     64static void batch_data(ohci_transfer_batch_t *instance);
     65/*----------------------------------------------------------------------------*/
     66void (*batch_setup[4][3])(ohci_transfer_batch_t*) =
     67{
     68        { NULL, NULL, setup_control },
    6769        { NULL, NULL, NULL },
    68         { batch_bulk_in, batch_bulk_out, NULL },
    69         { batch_interrupt_in, batch_interrupt_out, NULL },
     70        { bulk_in, bulk_out, NULL },
     71        { interrupt_in, interrupt_out, NULL },
    7072};
    71 
    72 
    73 /** OHCI specific data required for USB transfer */
    74 typedef struct ohci_transfer_batch {
    75         /** Endpoint descriptor of the target endpoint. */
    76         ed_t *ed;
    77         /** List of TDs needed for the transfer */
    78         td_t **tds;
    79         /** Number of TDs used by the transfer */
    80         size_t td_count;
    81         /** Dummy TD to be left at the ED and used by the next transfer */
    82         size_t leave_td;
    83         /** Data buffer, must be accessible byb the OHCI hw. */
    84         void *device_buffer;
    85 } ohci_transfer_batch_t;
    86 /*----------------------------------------------------------------------------*/
    87 static void batch_control(usb_transfer_batch_t *instance,
    88     usb_direction_t data_dir, usb_direction_t status_dir);
    89 static void batch_data(usb_transfer_batch_t *instance);
    9073/*----------------------------------------------------------------------------*/
    9174/** Safely destructs ohci_transfer_batch_t structure
     
    9376 * @param[in] ohci_batch Instance to destroy.
    9477 */
    95 static void ohci_batch_dispose(void *ohci_batch)
    96 {
    97         ohci_transfer_batch_t *instance = ohci_batch;
    98         if (!instance)
     78static void ohci_transfer_batch_dispose(ohci_transfer_batch_t *ohci_batch)
     79{
     80        if (!ohci_batch)
    9981                return;
    10082        unsigned i = 0;
    101         if (instance->tds) {
    102                 for (; i< instance->td_count; ++i) {
    103                         if (i != instance->leave_td)
    104                                 free32(instance->tds[i]);
     83        if (ohci_batch->tds) {
     84                for (; i< ohci_batch->td_count; ++i) {
     85                        if (i != ohci_batch->leave_td)
     86                                free32(ohci_batch->tds[i]);
    10587                }
    106                 free(instance->tds);
    107         }
    108         free32(instance->device_buffer);
    109         free(instance);
    110 }
    111 /*----------------------------------------------------------------------------*/
    112 int batch_init_ohci(usb_transfer_batch_t *batch)
    113 {
    114         assert(batch);
    115 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
    116         if (ptr == NULL) { \
    117                 usb_log_error(message); \
    118                 if (data) { \
    119                         ohci_batch_dispose(data); \
    120                 } \
    121                 return ENOMEM; \
    122         } else (void)0
    123 
    124         ohci_transfer_batch_t *data = calloc(sizeof(ohci_transfer_batch_t), 1);
    125         CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
    126 
    127         data->td_count = ((batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1)
    128             / OHCI_TD_MAX_TRANSFER);
     88                free(ohci_batch->tds);
     89        }
     90        usb_transfer_batch_dispose(ohci_batch->usb_batch);
     91        free32(ohci_batch->device_buffer);
     92        free(ohci_batch);
     93}
     94/*----------------------------------------------------------------------------*/
     95void ohci_transfer_batch_finish_dispose(ohci_transfer_batch_t *ohci_batch)
     96{
     97        assert(ohci_batch);
     98        assert(ohci_batch->usb_batch);
     99        usb_transfer_batch_finish(ohci_batch->usb_batch,
     100            ohci_batch->device_buffer + ohci_batch->usb_batch->setup_size,
     101            ohci_batch->usb_batch->buffer_size);
     102        ohci_transfer_batch_dispose(ohci_batch);
     103}
     104/*----------------------------------------------------------------------------*/
     105ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *usb_batch)
     106{
     107        assert(usb_batch);
     108#define CHECK_NULL_DISPOSE_RET(ptr, message...) \
     109if (ptr == NULL) { \
     110        usb_log_error(message); \
     111        ohci_transfer_batch_dispose(ohci_batch); \
     112        return NULL; \
     113} else (void)0
     114
     115        ohci_transfer_batch_t *ohci_batch =
     116            calloc(sizeof(ohci_transfer_batch_t), 1);
     117        CHECK_NULL_DISPOSE_RET(ohci_batch,
     118            "Failed to allocate OHCI batch data.\n");
     119
     120        ohci_batch->td_count =
     121            (usb_batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1)
     122            / OHCI_TD_MAX_TRANSFER;
    129123        /* Control transfer need Setup and Status stage */
    130         if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
    131                 data->td_count += 2;
     124        if (usb_batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
     125                ohci_batch->td_count += 2;
    132126        }
    133127
    134128        /* We need an extra place for TD that was left at ED */
    135         data->tds = calloc(sizeof(td_t*), data->td_count + 1);
    136         CHECK_NULL_DISPOSE_RETURN(data->tds,
    137             "Failed to allocate transfer descriptors.\n");
     129        ohci_batch->tds = calloc(ohci_batch->td_count + 1, sizeof(td_t*));
     130        CHECK_NULL_DISPOSE_RET(ohci_batch->tds,
     131            "Failed to allocate OHCI transfer descriptors.\n");
    138132
    139133        /* Add TD left over by the previous transfer */
    140         data->ed = ohci_endpoint_get(batch->ep)->ed;
    141         data->tds[0] = ohci_endpoint_get(batch->ep)->td;
    142         data->leave_td = 0;
     134        ohci_batch->ed = ohci_endpoint_get(usb_batch->ep)->ed;
     135        ohci_batch->tds[0] = ohci_endpoint_get(usb_batch->ep)->td;
     136        ohci_batch->leave_td = 0;
    143137        unsigned i = 1;
    144         for (; i <= data->td_count; ++i) {
    145                 data->tds[i] = malloc32(sizeof(td_t));
    146                 CHECK_NULL_DISPOSE_RETURN(data->tds[i],
     138        for (; i <= ohci_batch->td_count; ++i) {
     139                ohci_batch->tds[i] = malloc32(sizeof(td_t));
     140                CHECK_NULL_DISPOSE_RET(ohci_batch->tds[i],
    147141                    "Failed to allocate TD %d.\n", i );
    148142        }
     
    153147         * than two pages (the first page is computed using start pointer, the
    154148         * other using the end pointer) */
    155         if (batch->setup_size + batch->buffer_size > 0) {
    156                 data->device_buffer =
    157                     malloc32(batch->setup_size + batch->buffer_size);
    158                 CHECK_NULL_DISPOSE_RETURN(data->device_buffer,
     149        if (usb_batch->setup_size + usb_batch->buffer_size > 0) {
     150                /* Use one buffer for setup and data stage */
     151                ohci_batch->device_buffer =
     152                    malloc32(usb_batch->setup_size + usb_batch->buffer_size);
     153                CHECK_NULL_DISPOSE_RET(ohci_batch->device_buffer,
    159154                    "Failed to allocate device accessible buffer.\n");
    160155                /* Copy setup data */
    161                 memcpy(data->device_buffer, batch->setup_buffer,
    162                     batch->setup_size);
    163                 batch->data_buffer = data->device_buffer + batch->setup_size;
     156                memcpy(ohci_batch->device_buffer, usb_batch->setup_buffer,
     157                    usb_batch->setup_size);
     158                /* Copy generic data */
     159                if (usb_batch->ep->direction != USB_DIRECTION_IN)
     160                        memcpy(
     161                            ohci_batch->device_buffer + usb_batch->setup_size,
     162                            usb_batch->buffer, usb_batch->buffer_size);
    164163        }
    165 
    166         batch->private_data = data;
    167         batch->private_data_dtor = ohci_batch_dispose;
    168 
    169         assert(batch_setup[batch->ep->transfer_type][batch->ep->direction]);
    170         batch_setup[batch->ep->transfer_type][batch->ep->direction](batch);
    171 
    172         return EOK;
    173 #undef CHECK_NULL_DISPOSE_RETURN
     164        ohci_batch->usb_batch = usb_batch;
     165
     166        assert(
     167           batch_setup[usb_batch->ep->transfer_type][usb_batch->ep->direction]);
     168        batch_setup[usb_batch->ep->transfer_type][usb_batch->ep->direction](
     169            ohci_batch);
     170
     171        return ohci_batch;
     172#undef CHECK_NULL_DISPOSE_RET
    174173}
    175174/*----------------------------------------------------------------------------*/
     
    183182 * completes with the last TD.
    184183 */
    185 bool batch_is_complete(usb_transfer_batch_t *instance)
    186 {
    187         assert(instance);
    188         ohci_transfer_batch_t *data = instance->private_data;
    189         assert(data);
    190         usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n",
    191             instance, data->td_count);
    192         usb_log_debug("ED: %x:%x:%x:%x.\n",
    193             data->ed->status, data->ed->td_head, data->ed->td_tail,
    194             data->ed->next);
     184bool ohci_transfer_batch_is_complete(ohci_transfer_batch_t *ohci_batch)
     185{
     186        assert(ohci_batch);
     187        assert(ohci_batch->usb_batch);
     188
     189        usb_log_debug("Batch %p checking %zu td(s) for completion.\n",
     190            ohci_batch->usb_batch, ohci_batch->td_count);
     191        usb_log_debug2("ED: %x:%x:%x:%x.\n",
     192            ohci_batch->ed->status, ohci_batch->ed->td_head,
     193            ohci_batch->ed->td_tail, ohci_batch->ed->next);
     194
    195195        size_t i = 0;
    196         instance->transfered_size = instance->buffer_size;
    197         for (; i < data->td_count; ++i) {
    198                 assert(data->tds[i] != NULL);
     196        for (; i < ohci_batch->td_count; ++i) {
     197                assert(ohci_batch->tds[i] != NULL);
    199198                usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i,
    200                     data->tds[i]->status, data->tds[i]->cbp, data->tds[i]->next,
    201                     data->tds[i]->be);
    202                 if (!td_is_finished(data->tds[i])) {
     199                    ohci_batch->tds[i]->status, ohci_batch->tds[i]->cbp,
     200                    ohci_batch->tds[i]->next, ohci_batch->tds[i]->be);
     201                if (!td_is_finished(ohci_batch->tds[i])) {
    203202                        return false;
    204203                }
    205                 instance->error = td_error(data->tds[i]);
    206                 if (instance->error != EOK) {
    207                         usb_log_debug("Batch(%p) found error TD(%zu):%x.\n",
    208                             instance, i, data->tds[i]->status);
     204                ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]);
     205                if (ohci_batch->usb_batch->error != EOK) {
     206                        usb_log_debug("Batch %p found error TD(%zu):%x.\n",
     207                            ohci_batch->usb_batch, i,
     208                            ohci_batch->tds[i]->status);
    209209                        /* Make sure TD queue is empty (one TD),
    210210                         * ED should be marked as halted */
    211                         data->ed->td_tail =
    212                             (data->ed->td_head & ED_TDTAIL_PTR_MASK);
     211                        ohci_batch->ed->td_tail =
     212                            (ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK);
    213213                        ++i;
    214214                        break;
    215215                }
    216216        }
    217         data->leave_td = i;
    218         assert(data->leave_td <= data->td_count);
    219 
    220         ohci_endpoint_t *ohci_ep = ohci_endpoint_get(instance->ep);
     217
     218        assert(i <= ohci_batch->td_count);
     219        ohci_batch->leave_td = i;
     220
     221        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->usb_batch->ep);
    221222        assert(ohci_ep);
    222         ohci_ep->td = data->tds[data->leave_td];
     223        ohci_ep->td = ohci_batch->tds[ohci_batch->leave_td];
    223224        assert(i > 0);
    224         for (--i;i < data->td_count; ++i)
    225                 instance->transfered_size -= td_remain_size(data->tds[i]);
     225        ohci_batch->usb_batch->transfered_size =
     226            ohci_batch->usb_batch->buffer_size;
     227        for (--i;i < ohci_batch->td_count; ++i)
     228                ohci_batch->usb_batch->transfered_size
     229                    -= td_remain_size(ohci_batch->tds[i]);
    226230
    227231        /* Clear possible ED HALT */
    228         data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
     232        ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
     233        /* just make sure that we are leaving the right TD behind */
    229234        const uint32_t pa = addr_to_phys(ohci_ep->td);
    230         assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK));
    231         assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK));
     235        assert(pa == (ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK));
     236        assert(pa == (ohci_batch->ed->td_tail & ED_TDTAIL_PTR_MASK));
    232237
    233238        return true;
     
    238243 * @param[in] instance Batch structure to use
    239244 */
    240 void batch_commit(usb_transfer_batch_t *instance)
    241 {
    242         assert(instance);
    243         ohci_transfer_batch_t *data = instance->private_data;
    244         assert(data);
    245         ed_set_end_td(data->ed, data->tds[data->td_count]);
     245void ohci_transfer_batch_commit(ohci_transfer_batch_t *ohci_batch)
     246{
     247        assert(ohci_batch);
     248        ed_set_end_td(ohci_batch->ed, ohci_batch->tds[ohci_batch->td_count]);
    246249}
    247250/*----------------------------------------------------------------------------*/
     
    253256 * IN(status stage).
    254257 */
    255 void batch_control_write(usb_transfer_batch_t *instance)
    256 {
    257         assert(instance);
    258         /* We are data out, we are supposed to provide data */
    259         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    260         instance->next_step = usb_transfer_batch_call_out_and_dispose;
    261         batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN);
    262         usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     258void control_write(ohci_transfer_batch_t *ohci_batch)
     259{
     260        assert(ohci_batch);
     261        batch_control(ohci_batch, USB_DIRECTION_OUT, USB_DIRECTION_IN);
     262        usb_log_debug("Batch %p CONTROL WRITE initialized.\n", ohci_batch);
    263263}
    264264/*----------------------------------------------------------------------------*/
     
    270270 * OUT(status stage).
    271271 */
    272 void batch_control_read(usb_transfer_batch_t *instance)
    273 {
    274         assert(instance);
    275         instance->next_step = usb_transfer_batch_call_in_and_dispose;
    276         batch_control(instance, USB_DIRECTION_IN, USB_DIRECTION_OUT);
    277         usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
     272void control_read(ohci_transfer_batch_t *ohci_batch)
     273{
     274        assert(ohci_batch);
     275        batch_control(ohci_batch, USB_DIRECTION_IN, USB_DIRECTION_OUT);
     276        usb_log_debug("Batch %p CONTROL READ initialized.\n", ohci_batch);
    278277}
    279278/*----------------------------------------------------------------------------*/
     
    284283 * Data transfer.
    285284 */
    286 void batch_interrupt_in(usb_transfer_batch_t *instance)
    287 {
    288         assert(instance);
    289         instance->next_step = usb_transfer_batch_call_in_and_dispose;
    290         batch_data(instance);
    291         usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
     285void interrupt_in(ohci_transfer_batch_t *ohci_batch)
     286{
     287        assert(ohci_batch);
     288        batch_data(ohci_batch);
     289        usb_log_debug("Batch %p INTERRUPT IN initialized.\n", ohci_batch);
    292290}
    293291/*----------------------------------------------------------------------------*/
     
    298296 * Data transfer.
    299297 */
    300 void batch_interrupt_out(usb_transfer_batch_t *instance)
    301 {
    302         assert(instance);
    303         /* We are data out, we are supposed to provide data */
    304         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    305         instance->next_step = usb_transfer_batch_call_out_and_dispose;
    306         batch_data(instance);
    307         usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
     298void interrupt_out(ohci_transfer_batch_t *ohci_batch)
     299{
     300        assert(ohci_batch);
     301        batch_data(ohci_batch);
     302        usb_log_debug("Batch %p INTERRUPT OUT initialized.\n", ohci_batch);
    308303}
    309304/*----------------------------------------------------------------------------*/
     
    314309 * Data transfer.
    315310 */
    316 void batch_bulk_in(usb_transfer_batch_t *instance)
    317 {
    318         assert(instance);
    319         instance->next_step = usb_transfer_batch_call_in_and_dispose;
    320         batch_data(instance);
    321         usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     311void bulk_in(ohci_transfer_batch_t *ohci_batch)
     312{
     313        assert(ohci_batch);
     314        batch_data(ohci_batch);
     315        usb_log_debug("Batch %p BULK IN initialized.\n", ohci_batch);
    322316}
    323317/*----------------------------------------------------------------------------*/
     
    328322 * Data transfer.
    329323 */
    330 void batch_bulk_out(usb_transfer_batch_t *instance)
    331 {
    332         assert(instance);
    333         /* We are data out, we are supposed to provide data */
    334         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    335         instance->next_step = usb_transfer_batch_call_out_and_dispose;
    336         batch_data(instance);
    337         usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
     324void bulk_out(ohci_transfer_batch_t *ohci_batch)
     325{
     326        assert(ohci_batch);
     327        batch_data(ohci_batch);
     328        usb_log_debug("Batch %p BULK OUT initialized.\n", ohci_batch);
    338329}
    339330/*----------------------------------------------------------------------------*/
     
    348339 * Status stage with toggle 1 and direction supplied by parameter.
    349340 */
    350 void batch_control(usb_transfer_batch_t *instance,
     341void batch_control(ohci_transfer_batch_t *ohci_batch,
    351342    usb_direction_t data_dir, usb_direction_t status_dir)
    352343{
    353         assert(instance);
    354         ohci_transfer_batch_t *data = instance->private_data;
    355         assert(data);
    356         usb_log_debug("Using ED(%p): %x:%x:%x:%x.\n", data->ed,
    357             data->ed->status, data->ed->td_tail, data->ed->td_head,
    358             data->ed->next);
     344        assert(ohci_batch);
     345        assert(ohci_batch->usb_batch);
     346        usb_log_debug("Using ED(%p): %x:%x:%x:%x.\n", ohci_batch->ed,
     347            ohci_batch->ed->status, ohci_batch->ed->td_tail,
     348            ohci_batch->ed->td_head, ohci_batch->ed->next);
     349
    359350        int toggle = 0;
     351        char* buffer = ohci_batch->device_buffer;
     352
    360353        /* setup stage */
    361         td_init(data->tds[0], USB_DIRECTION_BOTH, instance->setup_buffer,
    362                 instance->setup_size, toggle);
    363         td_set_next(data->tds[0], data->tds[1]);
     354        td_init(ohci_batch->tds[0], USB_DIRECTION_BOTH, buffer,
     355                ohci_batch->usb_batch->setup_size, toggle);
     356        td_set_next(ohci_batch->tds[0], ohci_batch->tds[1]);
    364357        usb_log_debug("Created CONTROL SETUP TD: %x:%x:%x:%x.\n",
    365             data->tds[0]->status, data->tds[0]->cbp, data->tds[0]->next,
    366             data->tds[0]->be);
     358            ohci_batch->tds[0]->status, ohci_batch->tds[0]->cbp,
     359            ohci_batch->tds[0]->next, ohci_batch->tds[0]->be);
     360        buffer += ohci_batch->usb_batch->setup_size;
    367361
    368362        /* data stage */
    369363        size_t td_current = 1;
    370         size_t remain_size = instance->buffer_size;
    371         char *buffer = instance->data_buffer;
     364        size_t remain_size = ohci_batch->usb_batch->buffer_size;
    372365        while (remain_size > 0) {
    373                 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
     366                const size_t transfer_size =
     367                    remain_size > OHCI_TD_MAX_TRANSFER ?
    374368                    OHCI_TD_MAX_TRANSFER : remain_size;
    375369                toggle = 1 - toggle;
    376370
    377                 td_init(data->tds[td_current], data_dir, buffer,
     371                td_init(ohci_batch->tds[td_current], data_dir, buffer,
    378372                    transfer_size, toggle);
    379                 td_set_next(data->tds[td_current], data->tds[td_current + 1]);
     373                td_set_next(ohci_batch->tds[td_current],
     374                    ohci_batch->tds[td_current + 1]);
    380375                usb_log_debug("Created CONTROL DATA TD: %x:%x:%x:%x.\n",
    381                     data->tds[td_current]->status, data->tds[td_current]->cbp,
    382                     data->tds[td_current]->next, data->tds[td_current]->be);
     376                    ohci_batch->tds[td_current]->status,
     377                    ohci_batch->tds[td_current]->cbp,
     378                    ohci_batch->tds[td_current]->next,
     379                    ohci_batch->tds[td_current]->be);
    383380
    384381                buffer += transfer_size;
    385382                remain_size -= transfer_size;
    386                 assert(td_current < data->td_count - 1);
     383                assert(td_current < ohci_batch->td_count - 1);
    387384                ++td_current;
    388385        }
    389386
    390387        /* status stage */
    391         assert(td_current == data->td_count - 1);
    392         td_init(data->tds[td_current], status_dir, NULL, 0, 1);
    393         td_set_next(data->tds[td_current], data->tds[td_current + 1]);
     388        assert(td_current == ohci_batch->td_count - 1);
     389        td_init(ohci_batch->tds[td_current], status_dir, NULL, 0, 1);
     390        td_set_next(ohci_batch->tds[td_current],
     391            ohci_batch->tds[td_current + 1]);
    394392        usb_log_debug("Created CONTROL STATUS TD: %x:%x:%x:%x.\n",
    395             data->tds[td_current]->status, data->tds[td_current]->cbp,
    396             data->tds[td_current]->next, data->tds[td_current]->be);
     393            ohci_batch->tds[td_current]->status,
     394            ohci_batch->tds[td_current]->cbp,
     395            ohci_batch->tds[td_current]->next,
     396            ohci_batch->tds[td_current]->be);
    397397}
    398398/*----------------------------------------------------------------------------*/
     
    404404 * OHCI hw in ED.
    405405 */
    406 void batch_data(usb_transfer_batch_t *instance)
    407 {
    408         assert(instance);
    409         ohci_transfer_batch_t *data = instance->private_data;
    410         assert(data);
    411         usb_log_debug("Using ED(%p): %x:%x:%x:%x.\n", data->ed,
    412             data->ed->status, data->ed->td_tail, data->ed->td_head,
    413             data->ed->next);
    414 
     406void batch_data(ohci_transfer_batch_t *ohci_batch)
     407{
     408        assert(ohci_batch);
     409        usb_log_debug("Using ED(%p): %x:%x:%x:%x.\n", ohci_batch->ed,
     410            ohci_batch->ed->status, ohci_batch->ed->td_tail,
     411            ohci_batch->ed->td_head, ohci_batch->ed->next);
     412
     413        const usb_direction_t direction = ohci_batch->usb_batch->ep->direction;
    415414        size_t td_current = 0;
    416         size_t remain_size = instance->buffer_size;
    417         char *buffer = instance->data_buffer;
     415        size_t remain_size = ohci_batch->usb_batch->buffer_size;
     416        char *buffer = ohci_batch->device_buffer;
    418417        while (remain_size > 0) {
    419418                const size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER
    420419                    ? OHCI_TD_MAX_TRANSFER : remain_size;
    421420
    422                 td_init(data->tds[td_current], instance->ep->direction,
     421                td_init(ohci_batch->tds[td_current], direction,
    423422                    buffer, transfer_size, -1);
    424                 td_set_next(data->tds[td_current], data->tds[td_current + 1]);
     423                td_set_next(ohci_batch->tds[td_current],
     424                    ohci_batch->tds[td_current + 1]);
    425425                usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",
    426                     data->tds[td_current]->status, data->tds[td_current]->cbp,
    427                     data->tds[td_current]->next, data->tds[td_current]->be);
     426                    ohci_batch->tds[td_current]->status,
     427                    ohci_batch->tds[td_current]->cbp,
     428                    ohci_batch->tds[td_current]->next,
     429                    ohci_batch->tds[td_current]->be);
    428430
    429431                buffer += transfer_size;
    430432                remain_size -= transfer_size;
    431                 assert(td_current < data->td_count);
     433                assert(td_current < ohci_batch->td_count);
    432434                ++td_current;
    433435        }
  • uspace/drv/bus/usb/ohci/ohci_batch.h

    rf18d82f0 r9c10e51  
    3535#define DRV_OHCI_BATCH_H
    3636
     37#include <adt/list.h>
    3738#include <usbhc_iface.h>
    3839#include <usb/usb.h>
    39 #include <usb/host/device_keeper.h>
    40 #include <usb/host/endpoint.h>
    4140#include <usb/host/batch.h>
    4241
    43 int batch_init_ohci(usb_transfer_batch_t *batch);
    44 bool batch_is_complete(usb_transfer_batch_t *batch);
    45 void batch_commit(usb_transfer_batch_t *batch);
     42#include "hw_struct/transfer_descriptor.h"
     43#include "hw_struct/endpoint_descriptor.h"
     44
     45/** OHCI specific data required for USB transfer */
     46typedef struct ohci_transfer_batch {
     47        /** Link */
     48        link_t link;
     49        /** Endpoint descriptor of the target endpoint. */
     50        ed_t *ed;
     51        /** List of TDs needed for the transfer */
     52        td_t **tds;
     53        /** Number of TDs used by the transfer */
     54        size_t td_count;
     55        /** Dummy TD to be left at the ED and used by the next transfer */
     56        size_t leave_td;
     57        /** Data buffer, must be accessible by the OHCI hw. */
     58        char *device_buffer;
     59        /** Generic USB transfer structure */
     60        usb_transfer_batch_t *usb_batch;
     61} ohci_transfer_batch_t;
     62
     63ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *batch);
     64bool ohci_transfer_batch_is_complete(ohci_transfer_batch_t *batch);
     65void ohci_transfer_batch_commit(ohci_transfer_batch_t *batch);
     66void ohci_transfer_batch_finish_dispose(ohci_transfer_batch_t *batch);
     67/*----------------------------------------------------------------------------*/
     68static inline ohci_transfer_batch_t *ohci_transfer_batch_from_link(link_t *l)
     69{
     70        assert(l);
     71        return list_get_instance(l, ohci_transfer_batch_t, link);
     72}
    4673#endif
    4774/**
  • uspace/drv/bus/usb/ohci/root_hub.c

    rf18d82f0 r9c10e51  
    121121        assert(request);
    122122
    123         memcpy(request->data_buffer, &mask, size);
    124123        request->transfered_size = size;
    125         usb_transfer_batch_finish_error(request, EOK);
     124        usb_transfer_batch_finish_error(request, &mask, size, EOK);
    126125}
    127126
     
    206205                usb_log_debug("Root hub got CONTROL packet\n");
    207206                const int ret = control_request(instance, request);
    208                 usb_transfer_batch_finish_error(request, ret);
     207                usb_transfer_batch_finish_error(request, NULL, 0, ret);
    209208                break;
    210209        case USB_TRANSFER_INTERRUPT:
     
    215214                        assert(instance->unfinished_interrupt_transfer == NULL);
    216215                        instance->unfinished_interrupt_transfer = request;
    217                         break;
     216                        return;
    218217                }
    219218                usb_log_debug("Processing changes...\n");
     
    223222        default:
    224223                usb_log_error("Root hub got unsupported request.\n");
    225                 usb_transfer_batch_finish_error(request, EINVAL);
    226         }
     224                usb_transfer_batch_finish_error(request, NULL, 0, EINVAL);
     225        }
     226        usb_transfer_batch_dispose(request);
    227227}
    228228/*----------------------------------------------------------------------------*/
     
    244244        interrupt_request(instance->unfinished_interrupt_transfer,
    245245            mask, instance->interrupt_mask_size);
     246        usb_transfer_batch_dispose(instance->unfinished_interrupt_transfer);
    246247
    247248        instance->unfinished_interrupt_transfer = NULL;
     
    389390                const uint32_t data = instance->registers->rh_status &
    390391                    (RHS_LPS_FLAG | RHS_LPSC_FLAG | RHS_OCI_FLAG | RHS_OCIC_FLAG);
    391                 memcpy(request->data_buffer, &data, 4);
    392                 TRANSFER_OK(4);
     392                memcpy(request->buffer, &data, sizeof(data));
     393                TRANSFER_OK(sizeof(data));
    393394        }
    394395
     
    402403                const uint32_t data =
    403404                    instance->registers->rh_port_status[port - 1];
    404                 memcpy(request->data_buffer, &data, 4);
    405                 TRANSFER_OK(4);
     405                memcpy(request->buffer, &data, sizeof(data));
     406                TRANSFER_OK(sizeof(data));
    406407        }
    407408
     
    483484        }
    484485
    485         memcpy(request->data_buffer, descriptor, size);
     486        memcpy(request->buffer, descriptor, size);
    486487        TRANSFER_OK(size);
    487488}
     
    713714                if (request->buffer_size != 1)
    714715                        return EINVAL;
    715                 request->data_buffer[0] = 1;
     716                request->buffer[0] = 1;
    716717                TRANSFER_OK(1);
    717718
Note: See TracChangeset for help on using the changeset viewer.