Changes in / [5d4193c:960ff451] in mainline


Ignore:
Location:
uspace/drv
Files:
2 added
2 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/Makefile

    r5d4193c r960ff451  
    3333
    3434SOURCES = \
     35        callback.c \
    3536        iface.c \
    3637        main.c \
     
    3940        uhci.c \
    4041        uhci_struct/transfer_descriptor.c \
    41         pci.c \
    42         tracker.c
     42        pci.c
    4343
    4444include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/uhci-hcd/iface.c

    r5d4193c r960ff451  
    106106    usbhc_iface_transfer_out_callback_t callback, void *arg)
    107107{
    108         size_t max_packet_size = 8;
    109         dev_speed_t speed = FULL_SPEED;
    110 
    111         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT,
    112             max_packet_size, speed, data, size, NULL, callback, arg);
    113         if (!tracker)
    114                 return ENOMEM;
    115         tracker_interrupt_out(tracker);
    116         return EOK;
     108        assert(dev);
     109        uhci_t *hc = dev_to_uhci(dev);
     110        assert(hc);
     111        return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_OUT,
     112                false, data, size, callback, NULL, arg);
    117113}
    118114/*----------------------------------------------------------------------------*/
     
    121117    usbhc_iface_transfer_in_callback_t callback, void *arg)
    122118{
    123         size_t max_packet_size = 4;
    124         dev_speed_t speed = FULL_SPEED;
    125 
    126         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT,
    127             max_packet_size, speed, data, size, callback, NULL, arg);
    128         if (!tracker)
    129                 return ENOMEM;
    130         tracker_interrupt_in(tracker);
    131         return EOK;
    132 }
    133 /*----------------------------------------------------------------------------*/
    134 static int control_write(device_t *dev, usb_target_t target,
    135     void *setup_data, size_t setup_size, void *data, size_t size,
    136     usbhc_iface_transfer_out_callback_t callback, void *arg)
    137 {
    138         size_t max_packet_size = 8;
    139         dev_speed_t speed = FULL_SPEED;
    140 
    141         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    142             max_packet_size, speed, data, size, NULL, callback, arg);
    143         if (!tracker)
    144                 return ENOMEM;
    145         tracker_control_write(tracker, setup_data, setup_size);
    146         return EOK;
    147 }
    148 /*----------------------------------------------------------------------------*/
    149 static int control_read(device_t *dev, usb_target_t target,
    150     void *setup_data, size_t setup_size, void *data, size_t size,
    151     usbhc_iface_transfer_in_callback_t callback, void *arg)
    152 {
    153         size_t max_packet_size = 8;
    154         dev_speed_t speed = FULL_SPEED;
    155 
    156         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    157             max_packet_size, speed, data, size, callback, NULL, arg);
    158         if (!tracker)
    159                 return ENOMEM;
    160         tracker_control_read(tracker, setup_data, setup_size);
    161         return EOK;
     119        assert(dev);
     120        uhci_t *hc = dev_to_uhci(dev);
     121        assert(hc);
     122        return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_IN,
     123                false, data, size, NULL, callback, arg);
    162124}
    163125/*----------------------------------------------------------------------------*/
     
    166128    usbhc_iface_transfer_out_callback_t callback, void *arg)
    167129{
    168         usb_log_warning("Using deprecated API control write setup.\n");
    169         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    170             8, FULL_SPEED, data, size, NULL, callback, arg);
    171         if (!tracker)
    172                 return ENOMEM;
    173         tracker_control_setup_old(tracker);
    174         return EOK;
     130        assert(dev);
     131        uhci_t *hc = dev_to_uhci(dev);
     132        assert(hc);
     133        return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP,
     134                false, data, size, callback, NULL, arg);
    175135}
    176136/*----------------------------------------------------------------------------*/
     
    179139    usbhc_iface_transfer_out_callback_t callback, void *arg)
    180140{
    181         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    182             size, FULL_SPEED, data, size, NULL, callback, arg);
    183         if (!tracker)
    184                 return ENOMEM;
    185         tracker_control_write_data_old(tracker);
    186         return EOK;
     141        assert(dev);
     142        uhci_t *hc = dev_to_uhci(dev);
     143        assert(hc);
     144        return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_OUT,
     145                false, data, size, callback, NULL, arg);
    187146}
    188147/*----------------------------------------------------------------------------*/
     
    190149    usbhc_iface_transfer_in_callback_t callback, void *arg)
    191150{
    192         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    193             0, FULL_SPEED, NULL, 0, callback, NULL, arg);
    194         if (!tracker)
    195                 return ENOMEM;
    196         tracker_control_write_status_old(tracker);
    197         return EOK;
     151        assert(dev);
     152        uhci_t *hc = dev_to_uhci(dev);
     153        assert(hc);
     154        return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_IN,
     155                false, NULL, 0, NULL, callback, arg);
    198156}
    199157/*----------------------------------------------------------------------------*/
     
    202160    usbhc_iface_transfer_out_callback_t callback, void *arg)
    203161{
    204         usb_log_warning("Using deprecated API control read setup.\n");
    205         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    206             8, FULL_SPEED, data, size, NULL, callback, arg);
    207         if (!tracker)
    208                 return ENOMEM;
    209         tracker_control_setup_old(tracker);
    210         return EOK;
     162        assert(dev);
     163        uhci_t *hc = dev_to_uhci(dev);
     164        assert(hc);
     165        return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP,
     166                false, data, size, callback, NULL, arg);
    211167}
    212168/*----------------------------------------------------------------------------*/
     
    215171    usbhc_iface_transfer_in_callback_t callback, void *arg)
    216172{
    217         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    218             size, FULL_SPEED, data, size, callback, NULL, arg);
    219         if (!tracker)
    220                 return ENOMEM;
    221         tracker_control_read_data_old(tracker);
    222         return EOK;
     173        assert(dev);
     174        uhci_t *hc = dev_to_uhci(dev);
     175        assert(hc);
     176        return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_IN,
     177                false, data, size, NULL, callback, arg);
    223178}
    224179/*----------------------------------------------------------------------------*/
     
    226181    usbhc_iface_transfer_out_callback_t callback, void *arg)
    227182{
    228         tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
    229             0, FULL_SPEED, NULL, 0, NULL, callback, arg);
    230         if (!tracker)
    231                 return ENOMEM;
    232         tracker_control_read_status_old(tracker);
    233         return EOK;
    234 }
    235 /*----------------------------------------------------------------------------*/
     183        assert(dev);
     184        uhci_t *hc = dev_to_uhci(dev);
     185        assert(hc);
     186        return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_OUT,
     187                false, NULL, 0, callback, NULL, arg);
     188}
     189
     190
    236191usbhc_iface_t uhci_iface = {
    237192        .tell_address = get_address,
     
    245200        .interrupt_out = interrupt_out,
    246201        .interrupt_in = interrupt_in,
    247 
    248         .control_read = control_read,
    249         .control_write = control_write,
    250202
    251203        .control_write_setup = control_write_setup,
  • uspace/drv/uhci-hcd/transfer_list.c

    r5d4193c r960ff451  
    4141{
    4242        assert(instance);
     43        instance->first = NULL;
     44        instance->last = NULL;
    4345        instance->next = NULL;
    4446        instance->name = name;
     
    6466}
    6567/*----------------------------------------------------------------------------*/
    66 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker)
     68int transfer_list_append(
     69  transfer_list_t *instance, transfer_descriptor_t *transfer)
    6770{
    6871        assert(instance);
    69         assert(tracker);
     72        assert(transfer);
    7073
    71         uint32_t pa = (uintptr_t)addr_to_phys(tracker->td);
     74        uint32_t pa = (uintptr_t)addr_to_phys(transfer);
    7275        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    7376
     77        /* empty list */
     78        if (instance->first == NULL) {
     79                assert(instance->last == NULL);
     80                instance->first = instance->last = transfer;
     81        } else {
     82                assert(instance->last);
     83                instance->last->next_va = transfer;
    7484
     85                assert(instance->last->next & LINK_POINTER_TERMINATE_FLAG);
     86                instance->last->next = (pa & LINK_POINTER_ADDRESS_MASK);
     87                instance->last = transfer;
     88        }
     89
     90        assert(instance->queue_head);
    7591        if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
    76                 usb_log_debug2("Adding td(%X:%X) to queue %s first.\n",
    77                         tracker->td->status, tracker->td->device, instance->name);
    78                 /* there is nothing scheduled */
    79                 instance->last_tracker = tracker;
    80                 instance->queue_head->element = pa;
    81                 usb_log_debug2("Added td(%X:%X) to queue %s first.\n",
    82                         tracker->td->status, tracker->td->device, instance->name);
    83                 return;
     92                instance->queue_head->element = (pa & LINK_POINTER_ADDRESS_MASK);
    8493        }
    85         usb_log_debug2("Adding td(%X:%X) to queue %s last.%p\n",
    86             tracker->td->status, tracker->td->device, instance->name,
    87             instance->last_tracker);
    88         /* now we can be sure that last_tracker is a valid pointer */
    89         instance->last_tracker->td->next = pa;
    90         instance->last_tracker = tracker;
    91 
    92         usb_log_debug2("Added td(%X:%X) to queue %s last.\n",
    93                 tracker->td->status, tracker->td->device, instance->name);
    94 
    95         /* check again, may be use atomic compare and swap */
    96         if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
    97                 instance->queue_head->element = pa;
    98                 usb_log_debug2("Added td(%X:%X) to queue first2 %s.\n",
    99                         tracker->td->status, tracker->td->device, instance->name);
    100         }
     94        usb_log_debug("Successfully added transfer to the hc queue %s.\n",
     95          instance->name);
     96        return EOK;
    10197}
    10298/**
  • uspace/drv/uhci-hcd/transfer_list.h

    r5d4193c r960ff451  
    3636
    3737#include "uhci_struct/queue_head.h"
    38 #include "tracker.h"
     38#include "uhci_struct/transfer_descriptor.h"
    3939
    4040typedef struct transfer_list
    4141{
    42         tracker_t *last_tracker;
    43 
     42        transfer_descriptor_t *first;
     43        transfer_descriptor_t *last;
    4444        queue_head_t *queue_head;
    4545        uint32_t queue_head_pa;
     
    5858}
    5959
    60 
    61 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker);
     60int transfer_list_append(
     61  transfer_list_t *instance, transfer_descriptor_t *transfer);
    6262
    6363#endif
  • uspace/drv/uhci-hcd/uhci.c

    r5d4193c r960ff451  
    3333 */
    3434#include <errno.h>
    35 #include <adt/list.h>
    3635
    3736#include <usb/debug.h>
     
    4342static int uhci_clean_finished(void *arg);
    4443static int uhci_debug_checker(void *arg);
    45 static bool allowed_usb_packet(
    46         bool low_speed, usb_transfer_type_t, size_t size);
    4744
    4845int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     
    8784
    8885        const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
     86
    8987        pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
    90 
    91         list_initialize(&instance->tracker_list);
    92         fibril_mutex_initialize(&instance->tracker_list_mutex);
    9388
    9489        instance->cleaner = fibril_create(uhci_clean_finished, instance);
     
    9893        fibril_add_ready(instance->debug_checker);
    9994
    100         /* Start the hc with large(64B) packet FSBR */
     95        /* Start the hc with large(64b) packet FSBR */
    10196        pio_write_16(&instance->registers->usbcmd,
    10297            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
     
    152147}
    153148/*----------------------------------------------------------------------------*/
    154 int uhci_schedule(uhci_t *instance, tracker_t *tracker)
    155 {
    156         assert(instance);
    157         assert(tracker);
    158         const int low_speed = (tracker->speed == LOW_SPEED);
    159         if (!allowed_usb_packet(
    160             low_speed, tracker->transfer_type, tracker->packet_size)) {
    161                 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",
    162                           low_speed ? "LOW" : "FULL" , tracker->transfer_type,
    163                     tracker->packet_size);
     149int uhci_transfer(
     150  uhci_t *instance,
     151  device_t *dev,
     152  usb_target_t target,
     153  usb_transfer_type_t transfer_type,
     154        bool toggle,
     155  usb_packet_id pid,
     156        bool low_speed,
     157  void *buffer, size_t size,
     158  usbhc_iface_transfer_out_callback_t callback_out,
     159  usbhc_iface_transfer_in_callback_t callback_in,
     160  void *arg)
     161{
     162        // TODO: Add support for isochronous transfers
     163        if (transfer_type == USB_TRANSFER_ISOCHRONOUS) {
     164                usb_log_warning("ISO transfer not supported.\n");
    164165                return ENOTSUP;
    165166        }
    166         /* TODO: check available bandwith here */
    167 
    168         usb_log_debug2("Scheduler(%d) acquiring tracker list mutex.\n",
    169             fibril_get_id());
    170         fibril_mutex_lock(&instance->tracker_list_mutex);
    171         usb_log_debug2("Scheduler(%d) acquired tracker list mutex.\n",
    172             fibril_get_id());
    173 
    174         transfer_list_t *list =
    175             instance->transfers[low_speed][tracker->transfer_type];
    176         assert(list);
    177         transfer_list_add_tracker(list, tracker);
    178         list_append(&tracker->link, &instance->tracker_list);
    179 
    180         usb_log_debug2("Scheduler(%d) releasing tracker list mutex.\n",
    181             fibril_get_id());
    182         fibril_mutex_unlock(&instance->tracker_list_mutex);
    183         usb_log_debug2("Scheduler(%d) released tracker list mutex.\n",
    184             fibril_get_id());
     167
     168        if (transfer_type == USB_TRANSFER_INTERRUPT
     169          && size >= 64) {
     170                usb_log_warning("Interrupt transfer too big %zu.\n", size);
     171                return ENOTSUP;
     172        }
     173
     174        if (size >= 1024) {
     175                usb_log_warning("Transfer too big.\n");
     176                return ENOTSUP;
     177        }
     178        transfer_list_t *list = instance->transfers[low_speed][transfer_type];
     179        if (!list) {
     180                usb_log_warning("UNSUPPORTED transfer %d-%d.\n", low_speed, transfer_type);
     181                return ENOTSUP;
     182        }
     183
     184        transfer_descriptor_t *td = NULL;
     185        callback_t *job = NULL;
     186        int ret = EOK;
     187        assert(dev);
     188
     189#define CHECK_RET_TRANS_FREE_JOB_TD(message) \
     190        if (ret != EOK) { \
     191                usb_log_error(message); \
     192                if (job) { \
     193                        callback_dispose(job); \
     194                } \
     195                if (td) { free32(td); } \
     196                return ret; \
     197        } else (void) 0
     198
     199        job = callback_get(dev, buffer, size, callback_in, callback_out, arg);
     200        ret = job ? EOK : ENOMEM;
     201        CHECK_RET_TRANS_FREE_JOB_TD("Failed to allocate callback structure.\n");
     202
     203        td = transfer_descriptor_get(3, size, false, target, pid, job->new_buffer);
     204        ret = td ? EOK : ENOMEM;
     205        CHECK_RET_TRANS_FREE_JOB_TD("Failed to setup transfer descriptor.\n");
     206
     207        td->callback = job;
     208
     209
     210        usb_log_debug("Appending a new transfer to queue %s.\n", list->name);
     211
     212        ret = transfer_list_append(list, td);
     213        CHECK_RET_TRANS_FREE_JOB_TD("Failed to append transfer descriptor.\n");
    185214
    186215        return EOK;
    187216}
    188 /*----------------------------------------------------------------------------*/
     217/*---------------------------------------------------------------------------*/
    189218int uhci_clean_finished(void* arg)
    190219{
     
    194223
    195224        while(1) {
    196                 LIST_INITIALIZE(done_trackers);
    197                 /* tracker iteration */
    198 
    199                 usb_log_debug2("Cleaner(%d) acquiring tracker list mutex.\n",
    200                     fibril_get_id());
    201                 fibril_mutex_lock(&instance->tracker_list_mutex);
    202                 usb_log_debug2("Cleaner(%d) acquired tracker list mutex.\n",
    203                     fibril_get_id());
    204 
    205                 link_t *current = instance->tracker_list.next;
    206                 while (current != &instance->tracker_list)
    207                 {
    208 
    209                         link_t *next = current->next;
    210                         tracker_t *tracker = list_get_instance(current, tracker_t, link);
    211 
    212                         assert(current == &tracker->link);
    213                         assert(tracker);
    214                         assert(tracker->next_step);
    215                         assert(tracker->td);
    216 
    217                         if (!transfer_descriptor_is_active(tracker->td)) {
    218                                 usb_log_info("Found inactive tracker with status: %x:%x.\n",
    219                                     tracker->td->status, tracker->td->device);
    220                                 list_remove(current);
    221                                 list_append(current, &done_trackers);
     225                usb_log_debug("Running cleaning fibril on: %p.\n", instance);
     226                /* iterate all transfer queues */
     227                transfer_list_t *current_list = &instance->transfers_interrupt;
     228                while (current_list) {
     229                        /* Remove inactive transfers from the top of the queue
     230                         * TODO: should I reach queue head or is this enough? */
     231                        volatile transfer_descriptor_t * it =
     232                                current_list->first;
     233                        usb_log_debug("Running cleaning fibril on queue: %s (%s).\n",
     234                                current_list->name, it ? "SOMETHING" : "EMPTY");
     235
     236                        if (it) {
     237                                usb_log_debug("First in queue: %p (%x) PA:%x.\n",
     238                                        it, it->status, addr_to_phys((void*)it) );
     239                                usb_log_debug("First to send: %x\n",
     240                                        (current_list->queue_head->element) );
    222241                        }
    223                         current = next;
    224                 }
    225 
    226                 usb_log_debug2("Cleaner(%d) releasing tracker list mutex.\n",
    227                     fibril_get_id());
    228                 fibril_mutex_unlock(&instance->tracker_list_mutex);
    229                 usb_log_debug2("Cleaner(%d) released tracker list mutex.\n",
    230                     fibril_get_id());
    231 
    232                 while (!list_empty(&done_trackers)) {
    233                         tracker_t *tracker = list_get_instance(
    234                           done_trackers.next, tracker_t, link);
    235                         list_remove(&tracker->link);
    236                         tracker->next_step(tracker);
     242
     243                        while (current_list->first &&
     244                         !(current_list->first->status & TD_STATUS_ERROR_ACTIVE)) {
     245                                transfer_descriptor_t *transfer = current_list->first;
     246                                usb_log_info("Inactive transfer calling callback with status %x.\n",
     247                                  transfer->status);
     248                                current_list->first = transfer->next_va;
     249                                transfer_descriptor_dispose(transfer);
     250                        }
     251                        if (!current_list->first)
     252                                current_list->last = current_list->first;
     253
     254                        current_list = current_list->next;
    237255                }
    238256                async_usleep(UHCI_CLEANER_TIMEOUT);
     
    293311        return 0;
    294312}
    295 /*----------------------------------------------------------------------------*/
    296 bool allowed_usb_packet(
    297         bool low_speed, usb_transfer_type_t transfer, size_t size)
    298 {
    299         /* see USB specification chapter 5.5-5.8 for magic numbers used here */
    300         switch(transfer) {
    301                 case USB_TRANSFER_ISOCHRONOUS:
    302                         return (!low_speed && size < 1024);
    303                 case USB_TRANSFER_INTERRUPT:
    304                         return size <= (low_speed ? 8 : 64);
    305                 case USB_TRANSFER_CONTROL: /* device specifies its own max size */
    306                         return (size <= (low_speed ? 8 : 64));
    307                 case USB_TRANSFER_BULK: /* device specifies its own max size */
    308                         return (!low_speed && size <= 64);
    309         }
    310         return false;
    311 }
    312313/**
    313314 * @}
  • uspace/drv/uhci-hcd/uhci.h

    r5d4193c r960ff451  
    3737
    3838#include <fibril.h>
    39 #include <fibril_synch.h>
    40 #include <adt/list.h>
    4139
    4240#include <usb/addrkeep.h>
     
    4442
    4543#include "transfer_list.h"
    46 #include "tracker.h"
    4744
    4845typedef struct uhci_regs {
     
    7168} regs_t;
    7269
     70#define TRANSFER_QUEUES 4
    7371#define UHCI_FRAME_LIST_COUNT 1024
    7472#define UHCI_CLEANER_TIMEOUT 10000
    75 #define UHCI_DEBUGER_TIMEOUT 5000000
     73#define UHCI_DEBUGER_TIMEOUT 500000
    7674
    7775typedef struct uhci {
     
    8078
    8179        link_pointer_t *frame_list;
    82 
    83         link_t tracker_list;
    84         fibril_mutex_t tracker_list_mutex;
    8580
    8681        transfer_list_t transfers_bulk_full;
     
    113108  void *arg );
    114109
    115 int uhci_schedule(uhci_t *instance, tracker_t *tracker);
    116 
    117110static inline uhci_t * dev_to_uhci(device_t *dev)
    118111        { return (uhci_t*)dev->driver_data; }
  • uspace/drv/uhci-hcd/uhci_struct/queue_head.h

    r5d4193c r960ff451  
    4343
    4444typedef struct queue_head {
    45         volatile link_pointer_t next_queue;
    46         volatile link_pointer_t element;
     45        link_pointer_t next_queue;
     46        link_pointer_t element;
    4747} __attribute__((packed)) queue_head_t;
    4848
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    r5d4193c r960ff451  
    3232 * @brief UHCI driver
    3333 */
    34 #include <errno.h>
    3534#include <usb/debug.h>
    3635
    3736#include "transfer_descriptor.h"
    38 #include "utils/malloc32.h"
    3937
    4038void transfer_descriptor_init(transfer_descriptor_t *instance,
    41     int error_count, size_t size, bool toggle, bool isochronous,
    42     usb_target_t target, int pid, void *buffer)
     39  int error_count, size_t size, bool isochronous, usb_target_t target,
     40        int pid, void *buffer)
    4341{
    4442        assert(instance);
    4543
    46         instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
     44        instance->next =
     45          0 | LINK_POINTER_TERMINATE_FLAG;
    4746
     47
     48        assert(size < 1024);
    4849        instance->status = 0
    4950          | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
    5051          | TD_STATUS_ERROR_ACTIVE;
    5152
    52         assert(size < 1024);
    5353        instance->device = 0
    5454                | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
    55                 | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
    5655                | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
    5756                | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
     
    5958
    6059        instance->buffer_ptr = 0;
     60
     61        instance->next_va = NULL;
     62        instance->callback = NULL;
    6163
    6264        if (size) {
     
    104106                return USB_OUTCOME_CRCERROR;
    105107
    106 //      assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
    107 //      | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
     108        assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
     109        | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
    108110        return USB_OUTCOME_OK;
    109111}
    110 /*----------------------------------------------------------------------------*/
    111 int transfer_descriptor_status(transfer_descriptor_t *instance)
     112
     113void transfer_descriptor_fini(transfer_descriptor_t *instance)
    112114{
    113115        assert(instance);
    114         if (convert_outcome(instance->status))
    115                 return EINVAL; //TODO: use sane error value here
    116         return EOK;
     116        callback_run(instance->callback,
     117                convert_outcome(instance->status),
     118                ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK
     119        );
    117120}
    118121/**
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    r5d4193c r960ff451  
    3838#include <usb/usb.h>
    3939
     40#include "utils/malloc32.h"
     41#include "callback.h"
    4042#include "link_pointer.h"
    4143
     
    8486        volatile uint32_t buffer_ptr;
    8587
    86         /* there is 16 bytes of data available here, according to UHCI
    87          * Design guide, according to linux kernel the hardware does not care
    88          * we don't use it anyway
     88        /* there is 16 bytes of data available here
     89         * those are used to store callback pointer
     90         * and next pointer. Thus, there is some free space
     91         * on 32bits systems.
    8992         */
     93        struct transfer_descriptor *next_va;
     94        callback_t *callback;
    9095} __attribute__((packed)) transfer_descriptor_t;
    9196
    9297
    9398void transfer_descriptor_init(transfer_descriptor_t *instance,
    94     int error_count, size_t size, bool toggle, bool isochronous,
    95     usb_target_t target, int pid, void *buffer);
     99  int error_count, size_t size, bool isochronous, usb_target_t target,
     100        int pid, void *buffer);
    96101
    97 int transfer_descriptor_status(transfer_descriptor_t *instance);
     102static inline transfer_descriptor_t * transfer_descriptor_get(
     103  int error_count, size_t size, bool isochronous, usb_target_t target,
     104  int pid, void *buffer)
     105{
     106        transfer_descriptor_t * instance =
     107          malloc32(sizeof(transfer_descriptor_t));
    98108
    99 static inline bool transfer_descriptor_is_active(
    100     transfer_descriptor_t *instance)
     109        if (instance)
     110                transfer_descriptor_init(
     111                  instance, error_count, size, isochronous, target, pid, buffer);
     112        return instance;
     113}
     114
     115void transfer_descriptor_fini(transfer_descriptor_t *instance);
     116
     117static inline void transfer_descriptor_dispose(transfer_descriptor_t *instance)
    101118{
    102119        assert(instance);
    103         return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0;
     120        transfer_descriptor_fini(instance);
     121        free32(instance);
     122}
     123
     124static inline void transfer_descriptor_append(
     125  transfer_descriptor_t *instance, transfer_descriptor_t *item)
     126{
     127        assert(instance);
     128        instance->next_va = item;
     129        instance->next = (uintptr_t)addr_to_phys( item ) & LINK_POINTER_ADDRESS_MASK;
    104130}
    105131#endif
  • uspace/drv/uhci-rhd/main.c

    r5d4193c r960ff451  
    102102int main(int argc, char *argv[])
    103103{
    104         usb_log_enable(USB_LOG_LEVEL_ERROR, NAME);
     104        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    105105        return driver_main(&uhci_rh_driver);
    106106}
Note: See TracChangeset for help on using the changeset viewer.