Changeset 335382d in mainline for uspace/drv/uhci-hcd/transfer_list.c


Ignore:
Timestamp:
2011-03-13T18:17:30Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
deb4ba7
Parents:
0f3e68c (diff), a9f91cd (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

BIG refactoring, fixed a memory leak and few TODOs

File:
1 edited

Legend:

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

    r0f3e68c r335382d  
    4747 * @return Error code
    4848 *
    49  * Allocates memory for internat queue_head_t structure.
     49 * Allocates memory for internal qh_t structure.
    5050 */
    5151int transfer_list_init(transfer_list_t *instance, const char *name)
    5252{
    5353        assert(instance);
    54         instance->next = NULL;
    5554        instance->name = name;
    56         instance->queue_head = malloc32(sizeof(queue_head_t));
     55        instance->queue_head = malloc32(sizeof(qh_t));
    5756        if (!instance->queue_head) {
    5857                usb_log_error("Failed to allocate queue head.\n");
     
    6160        instance->queue_head_pa = addr_to_phys(instance->queue_head);
    6261
    63         queue_head_init(instance->queue_head);
     62        qh_init(instance->queue_head);
    6463        list_initialize(&instance->batch_list);
    6564        fibril_mutex_initialize(&instance->guard);
     
    7271 * @param[in] next List to append.
    7372 * @return Error code
     73 *
     74 * Does not check whether there was a next list already.
    7475 */
    7576void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
     
    7980        if (!instance->queue_head)
    8081                return;
    81         queue_head_append_qh(instance->queue_head, next->queue_head_pa);
    82         instance->queue_head->element = instance->queue_head->next_queue;
     82        /* set both next and element to point to the same QH */
     83        qh_set_next_qh(instance->queue_head, next->queue_head_pa);
     84        qh_set_element_qh(instance->queue_head, next->queue_head_pa);
    8385}
    8486/*----------------------------------------------------------------------------*/
     
    9395        assert(instance);
    9496        assert(batch);
    95         usb_log_debug2(
    96             "Adding batch(%p) to queue %s.\n", batch, instance->name);
     97        usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
    9798
    98         uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);
     99        const uint32_t pa = addr_to_phys(batch->qh);
    99100        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    100         pa |= LINK_POINTER_QUEUE_HEAD_FLAG;
    101101
    102         batch->qh->next_queue = instance->queue_head->next_queue;
     102        /* New batch will be added to the end of the current list
     103         * so set the link accordingly */
     104        qh_set_next_qh(batch->qh, instance->queue_head->next);
    103105
    104106        fibril_mutex_lock(&instance->guard);
    105107
    106         if (instance->queue_head->element == instance->queue_head->next_queue) {
    107                 /* there is nothing scheduled */
    108                 list_append(&batch->link, &instance->batch_list);
    109                 instance->queue_head->element = pa;
    110                 usb_log_debug("Batch(%p) added to queue %s first.\n",
    111                         batch, instance->name);
    112                 fibril_mutex_unlock(&instance->guard);
    113                 return;
     108        if (list_empty(&instance->batch_list)) {
     109                /* There is nothing scheduled */
     110                qh_t *qh = instance->queue_head;
     111                assert(qh->element == qh->next);
     112                qh_set_element_qh(qh, pa);
     113        } else {
     114                /* There is something scheduled */
     115                batch_t *last = list_get_instance(
     116                    instance->batch_list.prev, batch_t, link);
     117                qh_set_next_qh(last->qh, pa);
    114118        }
    115         /* now we can be sure that there is someting scheduled */
    116         assert(!list_empty(&instance->batch_list));
    117         batch_t *first = list_get_instance(
    118                   instance->batch_list.next, batch_t, link);
    119         batch_t *last = list_get_instance(
    120             instance->batch_list.prev, batch_t, link);
    121         queue_head_append_qh(last->qh, pa);
    122119        list_append(&batch->link, &instance->batch_list);
    123120
    124         usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n",
     121        batch_t *first = list_get_instance(
     122            instance->batch_list.next, batch_t, link);
     123        usb_log_debug("Batch(%p) added to queue %s, first is %p.\n",
    125124                batch, instance->name, first);
    126125        fibril_mutex_unlock(&instance->guard);
    127126}
    128127/*----------------------------------------------------------------------------*/
    129 /** Removes a transfer batch from list and queue.
     128/** Removes a transfer batch from the list and queue.
    130129 *
    131130 * @param[in] instance List to use.
    132131 * @param[in] batch Transfer batch to remove.
    133132 * @return Error code
     133 *
     134 * Does not lock the transfer list, caller is responsible for that.
    134135 */
    135136void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch)
     
    140141        assert(batch->qh);
    141142        usb_log_debug2(
    142             "Removing batch(%p) from queue %s.\n", batch, instance->name);
     143            "Queue %s: removing batch(%p).\n", instance->name, batch);
    143144
     145        const char * pos = NULL;
    144146        if (batch->link.prev == &instance->batch_list) {
    145147                /* I'm the first one here */
    146                 usb_log_debug(
    147                     "Batch(%p) removed (FIRST) from %s, next element %x.\n",
    148                     batch, instance->name, batch->qh->next_queue);
    149                 instance->queue_head->element = batch->qh->next_queue;
     148                qh_set_element_qh(instance->queue_head, batch->qh->next);
     149                pos = "FIRST";
    150150        } else {
    151                 usb_log_debug(
    152                     "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n",
    153                     batch, instance->name, batch->qh->next_queue);
    154151                batch_t *prev =
    155152                    list_get_instance(batch->link.prev, batch_t, link);
    156                 prev->qh->next_queue = batch->qh->next_queue;
     153                qh_set_next_qh(prev->qh, batch->qh->next);
     154                pos = "NOT FIRST";
    157155        }
    158156        list_remove(&batch->link);
     157        usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n",
     158            batch, pos, instance->name, batch->qh->next);
    159159}
    160160/*----------------------------------------------------------------------------*/
    161 /** Checks list for finished transfers.
     161/** Checks list for finished batches.
    162162 *
    163163 * @param[in] instance List to use.
Note: See TracChangeset for help on using the changeset viewer.