Changeset 3afb758 in mainline


Ignore:
Timestamp:
2011-08-24T15:23:46Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1a02517
Parents:
5fe0a69
Message:

UHCI: Remove old code

Add support for hcd_t destruction.

Location:
uspace
Files:
2 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/uhci/Makefile

    r5fe0a69 r3afb758  
    4242
    4343SOURCES = \
    44         iface.c \
    4544        main.c \
    4645        transfer_list.c \
  • uspace/drv/bus/usb/uhci/batch.c

    r5fe0a69 r3afb758  
    4444
    4545#define DEFAULT_ERROR_COUNT 3
     46static void batch_control_write(usb_transfer_batch_t *instance);
     47static void batch_control_read(usb_transfer_batch_t *instance);
     48
     49static void batch_interrupt_in(usb_transfer_batch_t *instance);
     50static void batch_interrupt_out(usb_transfer_batch_t *instance);
     51
     52static void batch_bulk_in(usb_transfer_batch_t *instance);
     53static void batch_bulk_out(usb_transfer_batch_t *instance);
    4654
    4755static void batch_setup_control(usb_transfer_batch_t *batch)
     
    93101}
    94102/*----------------------------------------------------------------------------*/
     103/** Allocate memory and initialize internal data structure.
     104 *
     105 * @param[in] fun DDF function to pass to callback.
     106 * @param[in] ep Communication target
     107 * @param[in] buffer Data source/destination.
     108 * @param[in] buffer_size Size of the buffer.
     109 * @param[in] setup_buffer Setup data source (if not NULL)
     110 * @param[in] setup_size Size of setup_buffer (should be always 8)
     111 * @param[in] func_in function to call on inbound transfer completion
     112 * @param[in] func_out function to call on outbound transfer completion
     113 * @param[in] arg additional parameter to func_in or func_out
     114 * @return Valid pointer if all structures were successfully created,
     115 * NULL otherwise.
     116 *
     117 * Determines the number of needed transfer descriptors (TDs).
     118 * Prepares a transport buffer (that is accessible by the hardware).
     119 * Initializes parameters needed for the transfer and callback.
     120 */
    95121void * uhci_transfer_batch_create(usb_transfer_batch_t *batch)
    96122{
     
    148174}
    149175/*----------------------------------------------------------------------------*/
    150 /** Allocate memory and initialize internal data structure.
    151  *
    152  * @param[in] fun DDF function to pass to callback.
    153  * @param[in] ep Communication target
    154  * @param[in] buffer Data source/destination.
    155  * @param[in] buffer_size Size of the buffer.
    156  * @param[in] setup_buffer Setup data source (if not NULL)
    157  * @param[in] setup_size Size of setup_buffer (should be always 8)
    158  * @param[in] func_in function to call on inbound transfer completion
    159  * @param[in] func_out function to call on outbound transfer completion
    160  * @param[in] arg additional parameter to func_in or func_out
    161  * @return Valid pointer if all structures were successfully created,
    162  * NULL otherwise.
    163  *
    164  * Determines the number of needed transfer descriptors (TDs).
    165  * Prepares a transport buffer (that is accessible by the hardware).
    166  * Initializes parameters needed for the transfer and callback.
    167  */
    168 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
    169     char *buffer, size_t buffer_size,
    170     const char* setup_buffer, size_t setup_size,
    171     usbhc_iface_transfer_in_callback_t func_in,
    172     usbhc_iface_transfer_out_callback_t func_out, void *arg)
    173 {
    174         assert(ep);
    175         assert(func_in == NULL || func_out == NULL);
    176         assert(func_in != NULL || func_out != NULL);
    177 
    178 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
    179         if (ptr == NULL) { \
    180                 usb_log_error(message); \
    181                 if (uhci_data) { \
    182                         uhci_transfer_batch_dispose(uhci_data); \
    183                 } \
    184                 return NULL; \
    185         } else (void)0
    186 
    187         uhci_transfer_batch_t *uhci_data =
    188             malloc(sizeof(uhci_transfer_batch_t));
    189         CHECK_NULL_DISPOSE_RETURN(uhci_data,
    190             "Failed to allocate UHCI batch.\n");
    191         bzero(uhci_data, sizeof(uhci_transfer_batch_t));
    192 
    193         uhci_data->td_count =
    194             (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size;
    195         if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    196                 uhci_data->td_count += 2;
    197         }
    198 
    199         assert((sizeof(td_t) % 16) == 0);
    200         const size_t total_size = (sizeof(td_t) * uhci_data->td_count)
    201             + sizeof(qh_t) + setup_size + buffer_size;
    202         uhci_data->device_buffer = malloc32(total_size);
    203         CHECK_NULL_DISPOSE_RETURN(uhci_data->device_buffer,
    204             "Failed to allocate UHCI buffer.\n");
    205         bzero(uhci_data->device_buffer, total_size);
    206 
    207         uhci_data->tds = uhci_data->device_buffer;
    208         uhci_data->qh =
    209             (uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count));
    210 
    211         qh_init(uhci_data->qh);
    212         qh_set_element_td(uhci_data->qh, uhci_data->tds);
    213 
    214         usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
    215         CHECK_NULL_DISPOSE_RETURN(instance,
    216             "Failed to allocate batch instance.\n");
    217         void *setup =
    218             uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count)
    219             + sizeof(qh_t);
    220         void *data_buffer = setup + setup_size;
    221         usb_transfer_batch_init(instance, ep, buffer, data_buffer, buffer_size,
    222             setup, setup_size, func_in, func_out, arg, fun,
    223             uhci_data, uhci_transfer_batch_dispose);
    224 
    225         memcpy(instance->setup_buffer, setup_buffer, setup_size);
    226         usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT
    227             " memory structures ready.\n", instance,
    228             USB_TRANSFER_BATCH_ARGS(*instance));
    229         return instance;
    230 }
    231176/*----------------------------------------------------------------------------*/
    232177/** Check batch TDs for activity.
     
    288233 * Uses generic control function with pids OUT and IN.
    289234 */
    290 void batch_control_write(usb_transfer_batch_t *instance)
     235static void batch_control_write(usb_transfer_batch_t *instance)
    291236{
    292237        assert(instance);
     
    304249 * Uses generic control with pids IN and OUT.
    305250 */
    306 void batch_control_read(usb_transfer_batch_t *instance)
     251static void batch_control_read(usb_transfer_batch_t *instance)
    307252{
    308253        assert(instance);
     
    318263 * Data transfer with PID_IN.
    319264 */
    320 void batch_interrupt_in(usb_transfer_batch_t *instance)
     265static void batch_interrupt_in(usb_transfer_batch_t *instance)
    321266{
    322267        assert(instance);
     
    332277 * Data transfer with PID_OUT.
    333278 */
    334 void batch_interrupt_out(usb_transfer_batch_t *instance)
     279static void batch_interrupt_out(usb_transfer_batch_t *instance)
    335280{
    336281        assert(instance);
     
    348293 * Data transfer with PID_IN.
    349294 */
    350 void batch_bulk_in(usb_transfer_batch_t *instance)
     295static void batch_bulk_in(usb_transfer_batch_t *instance)
    351296{
    352297        assert(instance);
     
    362307 * Data transfer with PID_OUT.
    363308 */
    364 void batch_bulk_out(usb_transfer_batch_t *instance)
     309static void batch_bulk_out(usb_transfer_batch_t *instance)
    365310{
    366311        assert(instance);
     
    380325 * The last transfer is marked with IOC flag.
    381326 */
    382 void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
     327static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
    383328{
    384329        assert(instance);
     
    431376 * The last transfer is marked with IOC.
    432377 */
    433 void batch_control(usb_transfer_batch_t *instance,
     378static void batch_control(usb_transfer_batch_t *instance,
    434379   usb_packet_id data_stage, usb_packet_id status_stage)
    435380{
  • uspace/drv/bus/usb/uhci/batch.h

    r5fe0a69 r3afb758  
    3939#include "hw_struct/queue_head.h"
    4040
    41 usb_transfer_batch_t * batch_get(
    42     ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
    43     const char *setup_buffer, size_t setup_size,
    44     usbhc_iface_transfer_in_callback_t func_in,
    45     usbhc_iface_transfer_out_callback_t func_out,
    46     void *arg);
    47 
    4841void * uhci_transfer_batch_create(usb_transfer_batch_t *batch);
    4942void uhci_transfer_batch_dispose(void *uhci_batch);
    5043
    51 void batch_dispose(usb_transfer_batch_t *instance);
    52 
    5344bool batch_is_complete(usb_transfer_batch_t *instance);
    54 
    55 void batch_control_write(usb_transfer_batch_t *instance);
    56 void batch_control_read(usb_transfer_batch_t *instance);
    57 
    58 void batch_interrupt_in(usb_transfer_batch_t *instance);
    59 void batch_interrupt_out(usb_transfer_batch_t *instance);
    60 
    61 void batch_bulk_in(usb_transfer_batch_t *instance);
    62 void batch_bulk_out(usb_transfer_batch_t *instance);
    6345
    6446qh_t * batch_qh(usb_transfer_batch_t *instance);
  • uspace/drv/bus/usb/uhci/hc.c

    r5fe0a69 r3afb758  
    4848    (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
    4949
    50 static int schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    51 {
    52         assert(hcd);
    53         return hc_schedule(hcd->private_data, batch);
    54 }
    5550
    5651static const irq_cmd_t uhci_irq_commands[] =
     
    6459};
    6560
     61static void hc_init_hw(const hc_t *instance);
     62static int hc_init_mem_structures(hc_t *instance);
    6663static int hc_init_transfer_lists(hc_t *instance);
    67 static int hc_init_mem_structures(hc_t *instance);
    68 static void hc_init_hw(hc_t *instance);
     64static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    6965
    7066static int hc_interrupt_emulator(void *arg);
     
    10298        cmds[3].addr = (void*)&registers->usbsts;
    10399        return EOK;
     100}
     101/*----------------------------------------------------------------------------*/
     102/** Take action based on the interrupt cause.
     103 *
     104 * @param[in] instance UHCI structure to use.
     105 * @param[in] status Value of the status register at the time of interrupt.
     106 *
     107 * Interrupt might indicate:
     108 * - transaction completed, either by triggering IOC, SPD, or an error
     109 * - some kind of device error
     110 * - resume from suspend state (not implemented)
     111 */
     112void hc_interrupt(hc_t *instance, uint16_t status)
     113{
     114        assert(instance);
     115        /* Lower 2 bits are transaction error and transaction complete */
     116        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     117                LIST_INITIALIZE(done);
     118                transfer_list_remove_finished(
     119                    &instance->transfers_interrupt, &done);
     120                transfer_list_remove_finished(
     121                    &instance->transfers_control_slow, &done);
     122                transfer_list_remove_finished(
     123                    &instance->transfers_control_full, &done);
     124                transfer_list_remove_finished(
     125                    &instance->transfers_bulk_full, &done);
     126
     127                while (!list_empty(&done)) {
     128                        link_t *item = list_first(&done);
     129                        list_remove(item);
     130                        usb_transfer_batch_t *batch =
     131                            list_get_instance(item, usb_transfer_batch_t, link);
     132                        usb_transfer_batch_finish(batch);
     133                }
     134        }
     135        /* Resume interrupts are not supported */
     136        if (status & UHCI_STATUS_RESUME) {
     137                usb_log_error("Resume interrupt!\n");
     138        }
     139
     140        /* Bits 4 and 5 indicate hc error */
     141        if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
     142                usb_log_error("UHCI hardware failure!.\n");
     143                ++instance->hw_failures;
     144                transfer_list_abort_all(&instance->transfers_interrupt);
     145                transfer_list_abort_all(&instance->transfers_control_slow);
     146                transfer_list_abort_all(&instance->transfers_control_full);
     147                transfer_list_abort_all(&instance->transfers_bulk_full);
     148
     149                if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
     150                        /* reinitialize hw, this triggers virtual disconnect*/
     151                        hc_init_hw(instance);
     152                } else {
     153                        usb_log_fatal("Too many UHCI hardware failures!.\n");
     154                        hc_fini(instance);
     155                }
     156        }
    104157}
    105158/*----------------------------------------------------------------------------*/
     
    138191        usb_log_debug(
    139192            "Device registers at %p (%zuB) accessible.\n", io, reg_size);
    140         hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11);
     193
     194        ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11);
     195        CHECK_RET_RETURN(ret, "Failed to initialize HCD generic driver: %s.\n",
     196            str_error(ret));
     197
    141198        instance->generic.private_data = instance;
    142         instance->generic.schedule = schedule;
     199        instance->generic.schedule = hc_schedule;
    143200        instance->generic.batch_private_ctor = uhci_transfer_batch_create;
    144201        instance->generic.batch_private_dtor = uhci_transfer_batch_dispose;
     202#undef CHECK_RET_DEST_FUN_RETURN
    145203
    146204        ret = hc_init_mem_structures(instance);
    147         CHECK_RET_RETURN(ret,
    148             "Failed to initialize UHCI memory structures: %s.\n",
    149             str_error(ret));
     205        if (ret != EOK) {
     206                usb_log_error(
     207                    "Failed to initialize UHCI memory structures: %s.\n",
     208                    str_error(ret));
     209                hcd_destroy(&instance->generic);
     210                return ret;
     211        }
    150212
    151213        hc_init_hw(instance);
     
    158220
    159221        return EOK;
    160 #undef CHECK_RET_DEST_FUN_RETURN
    161222}
    162223/*----------------------------------------------------------------------------*/
     
    166227 * For magic values see UHCI Design Guide
    167228 */
    168 void hc_init_hw(hc_t *instance)
     229void hc_init_hw(const hc_t *instance)
    169230{
    170231        assert(instance);
     
    210271 *
    211272 * Structures:
    212  *  - interrupt code (I/O addressses are customized per instance)
    213273 *  - transfer lists (queue heads need to be accessible by the hw)
    214274 *  - frame list page (needs to be one UHCI hw accessible 4K page)
     
    217277{
    218278        assert(instance);
    219 #define CHECK_RET_RETURN(ret, message...) \
    220         if (ret != EOK) { \
    221                 usb_log_error(message); \
    222                 return ret; \
    223         } else (void) 0
     279
     280        /* Init USB frame list page */
     281        instance->frame_list = get_page();
     282        if (!instance->frame_list) {
     283                return ENOMEM;
     284        }
     285        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    224286
    225287        /* Init transfer lists */
    226288        int ret = hc_init_transfer_lists(instance);
    227         CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
     289        if (ret != EOK) {
     290                usb_log_error("Failed to initialize transfer lists.\n");
     291                return_page(instance->frame_list);
     292                return ENOMEM;
     293        }
    228294        usb_log_debug("Initialized transfer lists.\n");
    229295
    230         /* Init device keeper */
    231         usb_device_keeper_init(&instance->manager);
    232         usb_log_debug("Initialized device keeper.\n");
    233 
    234         ret = usb_endpoint_manager_init(&instance->ep_manager,
    235             BANDWIDTH_AVAILABLE_USB11);
    236         CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
    237             str_error(ret));
    238 
    239         /* Init USB frame list page*/
    240         instance->frame_list = get_page();
    241         if (!instance->frame_list) {
    242                 usb_log_error("Failed to get frame list page.\n");
    243                 usb_endpoint_manager_destroy(&instance->ep_manager);
    244                 return ENOMEM;
    245         }
    246         usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    247296
    248297        /* Set all frames to point to the first queue head */
     
    255304
    256305        return EOK;
    257 #undef CHECK_RET_RETURN
    258306}
    259307/*----------------------------------------------------------------------------*/
     
    328376 * Checks for bandwidth availability and appends the batch to the proper queue.
    329377 */
    330 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
    331 {
     378int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
     379{
     380        assert(hcd);
     381        hc_t *instance = hcd->private_data;
    332382        assert(instance);
    333383        assert(batch);
     
    339389
    340390        return EOK;
    341 }
    342 /*----------------------------------------------------------------------------*/
    343 /** Take action based on the interrupt cause.
    344  *
    345  * @param[in] instance UHCI structure to use.
    346  * @param[in] status Value of the status register at the time of interrupt.
    347  *
    348  * Interrupt might indicate:
    349  * - transaction completed, either by triggering IOC, SPD, or an error
    350  * - some kind of device error
    351  * - resume from suspend state (not implemented)
    352  */
    353 void hc_interrupt(hc_t *instance, uint16_t status)
    354 {
    355         assert(instance);
    356         /* Lower 2 bits are transaction error and transaction complete */
    357         if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
    358                 LIST_INITIALIZE(done);
    359                 transfer_list_remove_finished(
    360                     &instance->transfers_interrupt, &done);
    361                 transfer_list_remove_finished(
    362                     &instance->transfers_control_slow, &done);
    363                 transfer_list_remove_finished(
    364                     &instance->transfers_control_full, &done);
    365                 transfer_list_remove_finished(
    366                     &instance->transfers_bulk_full, &done);
    367 
    368                 while (!list_empty(&done)) {
    369                         link_t *item = list_first(&done);
    370                         list_remove(item);
    371                         usb_transfer_batch_t *batch =
    372                             list_get_instance(item, usb_transfer_batch_t, link);
    373                         usb_transfer_batch_finish(batch);
    374                 }
    375         }
    376         /* Resume interrupts are not supported */
    377         if (status & UHCI_STATUS_RESUME) {
    378                 usb_log_error("Resume interrupt!\n");
    379         }
    380 
    381         /* Bits 4 and 5 indicate hc error */
    382         if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
    383                 usb_log_error("UHCI hardware failure!.\n");
    384                 ++instance->hw_failures;
    385                 transfer_list_abort_all(&instance->transfers_interrupt);
    386                 transfer_list_abort_all(&instance->transfers_control_slow);
    387                 transfer_list_abort_all(&instance->transfers_control_full);
    388                 transfer_list_abort_all(&instance->transfers_bulk_full);
    389 
    390                 if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
    391                         /* reinitialize hw, this triggers virtual disconnect*/
    392                         hc_init_hw(instance);
    393                 } else {
    394                         usb_log_fatal("Too many UHCI hardware failures!.\n");
    395                         hc_fini(instance);
    396                 }
    397         }
    398391}
    399392/*----------------------------------------------------------------------------*/
     
    415408                if (status != 0)
    416409                        usb_log_debug2("UHCI status: %x.\n", status);
    417 // Qemu fails to report stalled communication
    418 // see https://bugs.launchpad.net/qemu/+bug/757654
    419 // This is a simple workaround to force queue processing every time
    420         //      status |= 1;
    421410                hc_interrupt(instance, status);
    422411                async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
     
    424413        return EOK;
    425414}
    426 /*---------------------------------------------------------------------------*/
     415/*----------------------------------------------------------------------------*/
    427416/** Debug function, checks consistency of memory structures.
    428417 *
  • uspace/drv/bus/usb/uhci/hc.h

    r5fe0a69 r3afb758  
    3939#include <ddi.h>
    4040
    41 #include <usb/host/device_keeper.h>
    42 #include <usb/host/usb_endpoint_manager.h>
    4341#include <usb/host/batch.h>
    4442#include <usb/host/hcd.h>
     
    9593/** Main UHCI driver structure */
    9694typedef struct hc {
     95        /** Generic HCD driver structure */
    9796        hcd_t generic;
    98         /** USB bus driver, devices and addresses */
    99         usb_device_keeper_t manager;
    100         /** USB bus driver, endpoints */
    101         usb_endpoint_manager_t ep_manager;
    10297
    10398        /** Addresses of I/O registers */
     
    126121        unsigned hw_failures;
    127122} hc_t;
     123
    128124size_t hc_irq_cmd_count(void);
    129125int hc_get_irq_commands(
    130126    irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
     127void hc_interrupt(hc_t *instance, uint16_t status);
    131128int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);
    132 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
    133 void hc_interrupt(hc_t *instance, uint16_t status);
    134129
    135130/** Safely dispose host controller internal structures
     
    137132 * @param[in] instance Host controller structure to use.
    138133 */
    139 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ };
    140 
    141 /** Get and cast pointer to the driver data
    142  *
    143  * @param[in] fun DDF function pointer
    144  * @return cast pointer to driver_data
    145  */
    146 static inline hc_t * fun_to_hc(ddf_fun_t *fun)
    147 {
    148         assert(fun);
    149         return fun->driver_data;
    150 }
     134static inline void hc_fini(hc_t *instance) {} /* TODO: implement*/
    151135#endif
    152136/**
  • uspace/drv/bus/usb/uhci/pci.c

    r5fe0a69 r3afb758  
    142142{
    143143        assert(device);
    144        
     144
    145145        async_sess_t *parent_sess =
    146146            devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
     
    148148        if (!parent_sess)
    149149                return ENOMEM;
    150        
     150
    151151        /* See UHCI design guide for these values p.45,
    152152         * write all WC bits in USB legacy register */
    153153        const sysarg_t address = 0xc0;
    154154        const sysarg_t value = 0xaf00;
    155        
     155
    156156        async_exch_t *exch = async_exchange_begin(parent_sess);
    157        
     157
    158158        const int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
    159159            IPC_M_CONFIG_SPACE_WRITE_16, address, value);
    160        
     160
    161161        async_exchange_end(exch);
    162162        async_hangup(parent_sess);
    163        
     163
    164164        return rc;
    165165}
  • uspace/drv/bus/usb/uhci/uhci.c

    r5fe0a69 r3afb758  
    4141
    4242#include "uhci.h"
    43 #include "iface.h"
    4443#include "pci.h"
    4544
  • uspace/drv/bus/usb/uhci/utils/malloc32.h

    r5fe0a69 r3afb758  
    102102        if (free_address == 0)
    103103                return NULL;
    104         void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
     104        void *address = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
    105105                  AS_AREA_READ | AS_AREA_WRITE);
    106         if (ret != free_address)
     106        if (address != free_address)
    107107                return NULL;
    108         return ret;
     108        return address;
     109}
     110/*----------------------------------------------------------------------------*/
     111static inline void return_page(void *page)
     112{
     113        if (page)
     114                as_area_destroy(page);
    109115}
    110116
  • uspace/lib/usbhost/include/usb/host/hcd.h

    r5fe0a69 r3afb758  
    6161}
    6262/*----------------------------------------------------------------------------*/
     63static inline void hcd_destroy(hcd_t *hcd)
     64{
     65        usb_endpoint_manager_destroy(&hcd->ep_manager);
     66}
     67/*----------------------------------------------------------------------------*/
    6368static inline void reset_ep_if_need(
    6469    hcd_t *hcd, usb_target_t target, const char* setup_data)
Note: See TracChangeset for help on using the changeset viewer.