Changes in / [960ff451:f82cc1a8] in mainline


Ignore:
Location:
uspace/drv/uhci-hcd
Files:
2 added
3 deleted
8 edited

Legend:

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

    r960ff451 rf82cc1a8  
    3333
    3434SOURCES = \
    35         callback.c \
    3635        iface.c \
    3736        main.c \
     
    4039        uhci.c \
    4140        uhci_struct/transfer_descriptor.c \
    42         pci.c
     41        pci.c \
     42        tracker.c
    4343
    4444include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/uhci-hcd/iface.c

    r960ff451 rf82cc1a8  
    106106    usbhc_iface_transfer_out_callback_t callback, void *arg)
    107107{
    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);
     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_control_read_data_old(tracker);
     116        return EOK;
    113117}
    114118/*----------------------------------------------------------------------------*/
     
    117121    usbhc_iface_transfer_in_callback_t callback, void *arg)
    118122{
    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);
     123        size_t max_packet_size = 8;
     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_control_read_data_old(tracker);
     131        return EOK;
     132}
     133/*----------------------------------------------------------------------------*/
     134static 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 = size;
     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/*----------------------------------------------------------------------------*/
     149static 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 = size;
     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;
    124162}
    125163/*----------------------------------------------------------------------------*/
     
    128166    usbhc_iface_transfer_out_callback_t callback, void *arg)
    129167{
    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);
     168        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     169            8, FULL_SPEED, data, size, NULL, callback, arg);
     170        if (!tracker)
     171                return ENOMEM;
     172        tracker_control_setup_old(tracker);
     173        return EOK;
    135174}
    136175/*----------------------------------------------------------------------------*/
     
    139178    usbhc_iface_transfer_out_callback_t callback, void *arg)
    140179{
    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);
     180        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     181            size, FULL_SPEED, data, size, NULL, callback, arg);
     182        if (!tracker)
     183                return ENOMEM;
     184        tracker_control_write_data_old(tracker);
     185        return EOK;
    146186}
    147187/*----------------------------------------------------------------------------*/
     
    149189    usbhc_iface_transfer_in_callback_t callback, void *arg)
    150190{
    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);
     191        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     192            0, FULL_SPEED, NULL, 0, callback, NULL, arg);
     193        if (!tracker)
     194                return ENOMEM;
     195        tracker_control_write_status_old(tracker);
     196        return EOK;
    156197}
    157198/*----------------------------------------------------------------------------*/
     
    160201    usbhc_iface_transfer_out_callback_t callback, void *arg)
    161202{
    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);
     203        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     204            8, FULL_SPEED, data, size, NULL, callback, arg);
     205        if (!tracker)
     206                return ENOMEM;
     207        tracker_control_setup_old(tracker);
     208        return EOK;
    167209}
    168210/*----------------------------------------------------------------------------*/
     
    171213    usbhc_iface_transfer_in_callback_t callback, void *arg)
    172214{
    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);
     215        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     216            size, FULL_SPEED, data, size, callback, NULL, arg);
     217        if (!tracker)
     218                return ENOMEM;
     219        tracker_control_read_data_old(tracker);
     220        return EOK;
    178221}
    179222/*----------------------------------------------------------------------------*/
     
    181224    usbhc_iface_transfer_out_callback_t callback, void *arg)
    182225{
    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 
     226        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     227            0, FULL_SPEED, NULL, 0, NULL, callback, arg);
     228        if (!tracker)
     229                return ENOMEM;
     230        tracker_control_read_status_old(tracker);
     231        return EOK;
     232}
     233/*----------------------------------------------------------------------------*/
    191234usbhc_iface_t uhci_iface = {
    192235        .tell_address = get_address,
     
    200243        .interrupt_out = interrupt_out,
    201244        .interrupt_in = interrupt_in,
     245
     246        .control_read = control_read,
     247        .control_write = control_write,
    202248
    203249        .control_write_setup = control_write_setup,
  • uspace/drv/uhci-hcd/transfer_list.c

    r960ff451 rf82cc1a8  
    4141{
    4242        assert(instance);
    43         instance->first = NULL;
    44         instance->last = NULL;
    4543        instance->next = NULL;
    4644        instance->name = name;
     
    6664}
    6765/*----------------------------------------------------------------------------*/
    68 int transfer_list_append(
    69   transfer_list_t *instance, transfer_descriptor_t *transfer)
     66void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker)
    7067{
    7168        assert(instance);
    72         assert(transfer);
     69        assert(tracker);
    7370
    74         uint32_t pa = (uintptr_t)addr_to_phys(transfer);
     71        uint32_t pa = (uintptr_t)addr_to_phys(tracker->td);
    7572        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    7673
    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;
     74        if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
     75                /* there is nothing scheduled */
     76                instance->last_tracker = tracker;
     77                instance->queue_head->element = pa;
     78                return;
     79        }
     80        /* now we can be sure that last_tracker is a valid pointer */
     81        instance->last_tracker->td->next = pa;
     82        instance->last_tracker = tracker;
    8483
    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);
    91         if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
    92                 instance->queue_head->element = (pa & LINK_POINTER_ADDRESS_MASK);
    93         }
    94         usb_log_debug("Successfully added transfer to the hc queue %s.\n",
    95           instance->name);
    96         return EOK;
     84        /* check again, may be use atomic compare and swap */
     85//      if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
     86//              instance->queue_head->element = pa;
     87//      }
    9788}
    9889/**
  • uspace/drv/uhci-hcd/transfer_list.h

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

    r960ff451 rf82cc1a8  
    4242static int uhci_clean_finished(void *arg);
    4343static int uhci_debug_checker(void *arg);
     44static bool allowed_usb_packet(
     45        bool low_speed, usb_transfer_type_t, size_t size);
    4446
    4547int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     
    8486
    8587        const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
    86 
    8788        pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
     89
     90        list_initialize(&instance->tracker_list);
    8891
    8992        instance->cleaner = fibril_create(uhci_clean_finished, instance);
     
    9396        fibril_add_ready(instance->debug_checker);
    9497
    95         /* Start the hc with large(64b) packet FSBR */
     98        /* Start the hc with large(64B) packet FSBR */
    9699        pio_write_16(&instance->registers->usbcmd,
    97100            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
     
    147150}
    148151/*----------------------------------------------------------------------------*/
    149 int 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");
     152int uhci_schedule(uhci_t *instance, tracker_t *tracker)
     153{
     154        assert(instance);
     155        assert(tracker);
     156        const int low_speed = (tracker->speed == LOW_SPEED);
     157        if (!allowed_usb_packet(
     158            low_speed, tracker->transfer_type, tracker->packet_size)) {
     159                usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",
     160                          low_speed ? "LOW" : "FULL" , tracker->transfer_type,
     161                    tracker->packet_size);
    165162                return ENOTSUP;
    166163        }
    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");
    214 
    215         return EOK;
    216 }
    217 /*---------------------------------------------------------------------------*/
     164        /* TODO: check available bandwith here */
     165
     166        transfer_list_t *list =
     167            instance->transfers[low_speed][tracker->transfer_type];
     168        assert(list);
     169        transfer_list_add_tracker(list, tracker);
     170        list_append(&tracker->link, &instance->tracker_list);
     171
     172        return EOK;
     173}
     174/*----------------------------------------------------------------------------*/
    218175int uhci_clean_finished(void* arg)
    219176{
     
    223180
    224181        while(1) {
    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) );
     182                /* tracker iteration */
     183                link_t *current = instance->tracker_list.next;
     184                while (current != &instance->tracker_list)
     185                {
     186                        link_t *next = current->next;
     187                        tracker_t *tracker = list_get_instance(current, tracker_t, link);
     188
     189                        assert(current == &tracker->link);
     190                        assert(tracker);
     191                        assert(tracker->next_step);
     192                        assert(tracker->td);
     193
     194                        if (!transfer_descriptor_is_active(tracker->td)) {
     195                                usb_log_info("Found inactive tracker with status: %x.\n",
     196                                    tracker->td->status);
     197                                list_remove(current);
     198                                tracker->next_step(tracker);
    241199                        }
    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;
     200                        current = next;
    255201                }
    256202                async_usleep(UHCI_CLEANER_TIMEOUT);
     
    311257        return 0;
    312258}
     259/*----------------------------------------------------------------------------*/
     260bool allowed_usb_packet(
     261        bool low_speed, usb_transfer_type_t transfer, size_t size)
     262{
     263        /* see USB specification chapter 5.5-5.8 for magic numbers used here */
     264        switch(transfer) {
     265                case USB_TRANSFER_ISOCHRONOUS:
     266                        return (!low_speed && size < 1024);
     267                case USB_TRANSFER_INTERRUPT:
     268                        return size <= (low_speed ? 8 : 64);
     269                case USB_TRANSFER_CONTROL: /* device specifies its own max size */
     270                        return (size <= (low_speed ? 8 : 64));
     271                case USB_TRANSFER_BULK: /* device specifies its own max size */
     272                        return (!low_speed && size <= 64);
     273        }
     274        return false;
     275}
    313276/**
    314277 * @}
  • uspace/drv/uhci-hcd/uhci.h

    r960ff451 rf82cc1a8  
    3737
    3838#include <fibril.h>
     39#include <adt/list.h>
    3940
    4041#include <usb/addrkeep.h>
     
    4243
    4344#include "transfer_list.h"
     45#include "tracker.h"
    4446
    4547typedef struct uhci_regs {
     
    6870} regs_t;
    6971
    70 #define TRANSFER_QUEUES 4
    7172#define UHCI_FRAME_LIST_COUNT 1024
    7273#define UHCI_CLEANER_TIMEOUT 10000
    73 #define UHCI_DEBUGER_TIMEOUT 500000
     74#define UHCI_DEBUGER_TIMEOUT 5000000
    7475
    7576typedef struct uhci {
     
    7879
    7980        link_pointer_t *frame_list;
     81
     82        link_t tracker_list;
    8083
    8184        transfer_list_t transfers_bulk_full;
     
    108111  void *arg );
    109112
     113int uhci_schedule(uhci_t *instance, tracker_t *tracker);
     114
    110115static inline uhci_t * dev_to_uhci(device_t *dev)
    111116        { return (uhci_t*)dev->driver_data; }
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    r960ff451 rf82cc1a8  
    3232 * @brief UHCI driver
    3333 */
     34#include <errno.h>
    3435#include <usb/debug.h>
    3536
    3637#include "transfer_descriptor.h"
     38#include "utils/malloc32.h"
    3739
    3840void transfer_descriptor_init(transfer_descriptor_t *instance,
    39   int error_count, size_t size, bool isochronous, usb_target_t target,
    40         int pid, void *buffer)
     41    int error_count, size_t size, bool toggle, bool isochronous,
     42    usb_target_t target, int pid, void *buffer)
    4143{
    4244        assert(instance);
     
    4446        instance->next =
    4547          0 | LINK_POINTER_TERMINATE_FLAG;
    46 
    4748
    4849        assert(size < 1024);
     
    5859
    5960        instance->buffer_ptr = 0;
    60 
    61         instance->next_va = NULL;
    62         instance->callback = NULL;
    6361
    6462        if (size) {
     
    106104                return USB_OUTCOME_CRCERROR;
    107105
    108         assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
    109         | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
     106//      assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
     107//      | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
    110108        return USB_OUTCOME_OK;
    111109}
    112 
    113 void transfer_descriptor_fini(transfer_descriptor_t *instance)
     110/*----------------------------------------------------------------------------*/
     111int transfer_descriptor_status(transfer_descriptor_t *instance)
    114112{
    115113        assert(instance);
    116         callback_run(instance->callback,
    117                 convert_outcome(instance->status),
    118                 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK
    119         );
     114        if (convert_outcome(instance->status))
     115                return EINVAL; //TODO: use sane error value here
     116        return EOK;
    120117}
    121118/**
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    r960ff451 rf82cc1a8  
    3838#include <usb/usb.h>
    3939
    40 #include "utils/malloc32.h"
    41 #include "callback.h"
    4240#include "link_pointer.h"
    4341
     
    8684        volatile uint32_t buffer_ptr;
    8785
    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.
     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
    9289         */
    93         struct transfer_descriptor *next_va;
    94         callback_t *callback;
    9590} __attribute__((packed)) transfer_descriptor_t;
    9691
    9792
    9893void transfer_descriptor_init(transfer_descriptor_t *instance,
    99   int error_count, size_t size, bool isochronous, usb_target_t target,
    100         int pid, void *buffer);
     94    int error_count, size_t size, bool toggle, bool isochronous,
     95    usb_target_t target, int pid, void *buffer);
    10196
    102 static 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));
     97int transfer_descriptor_status(transfer_descriptor_t *instance);
    10898
    109         if (instance)
    110                 transfer_descriptor_init(
    111                   instance, error_count, size, isochronous, target, pid, buffer);
    112         return instance;
    113 }
    114 
    115 void transfer_descriptor_fini(transfer_descriptor_t *instance);
    116 
    117 static inline void transfer_descriptor_dispose(transfer_descriptor_t *instance)
     99static inline bool transfer_descriptor_is_active(
     100    transfer_descriptor_t *instance)
    118101{
    119102        assert(instance);
    120         transfer_descriptor_fini(instance);
    121         free32(instance);
    122 }
    123 
    124 static 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;
     103        return instance->status & TD_STATUS_ERROR_ACTIVE;
    130104}
    131105#endif
Note: See TracChangeset for help on using the changeset viewer.