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

Changeset 34e8bab in mainline


Ignore:
Timestamp:
2011-04-13T21:41:50Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
8d517c3, a39cfb8, d8b275d
Parents:
b77ce84 (diff), 3eeb270f (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:

uhci-hcd cleanup and doxygen

Fixed: usb_endpoint_manager returns EBUSY when trying to unregister active endpoint

Location:
uspace
Files:
16 edited

Legend:

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

    rb77ce84 r34e8bab  
    7676 * @param[in] func_out function to call on outbound transfer completion
    7777 * @param[in] arg additional parameter to func_in or func_out
    78  * @return Valid pointer if all substructures were successfully created,
     78 * @return Valid pointer if all structures were successfully created,
    7979 * NULL otherwise.
    8080 *
     
    126126
    127127        qh_init(uhci_data->qh);
    128         qh_set_element_td(uhci_data->qh, addr_to_phys(uhci_data->tds));
     128        qh_set_element_td(uhci_data->qh, uhci_data->tds);
    129129
    130130        usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
     
    396396}
    397397/*----------------------------------------------------------------------------*/
     398/** Provides access to QH data structure.
     399 * @param[in] instance Batch pointer to use.
     400 * @return Pointer to the QH used by the batch.
     401 */
    398402qh_t * batch_qh(usb_transfer_batch_t *instance)
    399403{
  • uspace/drv/uhci-hcd/batch.h

    rb77ce84 r34e8bab  
    3030 */
    3131/** @file
    32  * @brief UHCI driver USB transaction structure
     32 * @brief UHCI driver USB tranfer helper functions
    3333 */
    3434#ifndef DRV_UHCI_BATCH_H
  • uspace/drv/uhci-hcd/hc.c

    rb77ce84 r34e8bab  
    6666static int hc_interrupt_emulator(void *arg);
    6767static int hc_debug_checker(void *arg);
    68 #if 0
    69 static bool usb_is_allowed(
    70     bool low_speed, usb_transfer_type_t transfer, size_t size);
    71 #endif
    7268/*----------------------------------------------------------------------------*/
    7369/** Initialize UHCI hcd driver structure
     
    8985        int ret;
    9086
    91 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
     87#define CHECK_RET_RETURN(ret, message...) \
    9288        if (ret != EOK) { \
    9389                usb_log_error(message); \
    94                 if (instance->ddf_instance) \
    95                         ddf_fun_destroy(instance->ddf_instance); \
    9690                return ret; \
    9791        } else (void) 0
     
    9993        instance->hw_interrupts = interrupts;
    10094        instance->hw_failures = 0;
    101 
    102         /* Setup UHCI function. */
    103         instance->ddf_instance = fun;
    10495
    10596        /* allow access to hc control registers */
    10697        regs_t *io;
    10798        ret = pio_enable(regs, reg_size, (void**)&io);
    108         CHECK_RET_DEST_FUN_RETURN(ret,
     99        CHECK_RET_RETURN(ret,
    109100            "Failed(%d) to gain access to registers at %p: %s.\n",
    110             ret, str_error(ret), io);
     101            ret, io, str_error(ret));
    111102        instance->registers = io;
    112103        usb_log_debug("Device registers at %p(%u) accessible.\n",
     
    114105
    115106        ret = hc_init_mem_structures(instance);
    116         CHECK_RET_DEST_FUN_RETURN(ret,
    117             "Failed to initialize UHCI memory structures.\n");
     107        CHECK_RET_RETURN(ret,
     108            "Failed(%d) to initialize UHCI memory structures: %s.\n",
     109            ret, str_error(ret));
    118110
    119111        hc_init_hw(instance);
    120112        if (!interrupts) {
    121                 instance->cleaner =
     113                instance->interrupt_emulator =
    122114                    fibril_create(hc_interrupt_emulator, instance);
    123                 fibril_add_ready(instance->cleaner);
    124         } else {
    125                 /* TODO: enable interrupts here */
    126         }
    127 
    128         instance->debug_checker =
    129             fibril_create(hc_debug_checker, instance);
    130 //      fibril_add_ready(instance->debug_checker);
     115                fibril_add_ready(instance->interrupt_emulator);
     116        }
     117        (void)hc_debug_checker;
    131118
    132119        return EOK;
     
    228215        /* Set all frames to point to the first queue head */
    229216        const uint32_t queue =
    230           instance->transfers_interrupt.queue_head_pa
    231           | LINK_POINTER_QUEUE_HEAD_FLAG;
     217            LINK_POINTER_QH(addr_to_phys(
     218                instance->transfers_interrupt.queue_head));
    232219
    233220        unsigned i = 0;
     
    236223        }
    237224
    238         /* Init device keeper*/
     225        /* Init device keeper */
    239226        usb_device_keeper_init(&instance->manager);
    240227        usb_log_debug("Initialized device manager.\n");
     
    479466#undef QH
    480467}
    481 /*----------------------------------------------------------------------------*/
    482 /** Check transfers for USB validity
    483  *
    484  * @param[in] low_speed Transfer speed.
    485  * @param[in] transfer Transer type
    486  * @param[in] size Size of data packets
    487  * @return True if transaction is allowed by USB specs, false otherwise
    488  */
    489 #if 0
    490 bool usb_is_allowed(
    491     bool low_speed, usb_transfer_type_t transfer, size_t size)
    492 {
    493         /* see USB specification chapter 5.5-5.8 for magic numbers used here */
    494         switch(transfer)
    495         {
    496         case USB_TRANSFER_ISOCHRONOUS:
    497                 return (!low_speed && size < 1024);
    498         case USB_TRANSFER_INTERRUPT:
    499                 return size <= (low_speed ? 8 : 64);
    500         case USB_TRANSFER_CONTROL: /* device specifies its own max size */
    501                 return (size <= (low_speed ? 8 : 64));
    502         case USB_TRANSFER_BULK: /* device specifies its own max size */
    503                 return (!low_speed && size <= 64);
    504         }
    505         return false;
    506 }
    507 #endif
    508468/**
    509469 * @}
  • uspace/drv/uhci-hcd/hc.h

    rb77ce84 r34e8bab  
    4848#include "transfer_list.h"
    4949
     50/** UHCI I/O registers layout */
    5051typedef struct uhci_regs {
     52        /** Command register, controls HC behaviour */
    5153        uint16_t usbcmd;
    5254#define UHCI_CMD_MAX_PACKET (1 << 7)
     
    5961#define UHCI_CMD_RUN_STOP  (1 << 0)
    6062
     63        /** Status register, 1 means interrupt is asserted (if enabled) */
    6164        uint16_t usbsts;
    6265#define UHCI_STATUS_HALTED (1 << 5)
     
    6770#define UHCI_STATUS_INTERRUPT (1 << 0)
    6871
     72        /** Interrupt enabled registers */
    6973        uint16_t usbintr;
    7074#define UHCI_INTR_SHORT_PACKET (1 << 3)
     
    7377#define UHCI_INTR_CRC (1 << 0)
    7478
     79        /** Register stores frame number used in SOF packet */
    7580        uint16_t frnum;
     81
     82        /** Pointer(physical) to the Frame List */
    7683        uint32_t flbaseadd;
     84
     85        /** SOF modification to match external timers */
    7786        uint8_t sofmod;
    7887} regs_t;
     
    8392#define UHCI_ALLOWED_HW_FAIL 5
    8493
     94/* Main HC driver structure */
    8595typedef struct hc {
     96        /** USB bus driver, devices and addresses */
    8697        usb_device_keeper_t manager;
     98        /** USB bus driver, endpoints */
    8799        usb_endpoint_manager_t ep_manager;
    88100
     101        /** Addresses of I/O registers */
    89102        regs_t *registers;
    90103
     104        /** Frame List contains 1024 link pointers */
    91105        link_pointer_t *frame_list;
    92106
     107        /** List and queue of interrupt transfers */
     108        transfer_list_t transfers_interrupt;
     109        /** List and queue of low speed control transfers */
     110        transfer_list_t transfers_control_slow;
     111        /** List and queue of full speed bulk transfers */
    93112        transfer_list_t transfers_bulk_full;
     113        /** List and queue of full speed control transfers */
    94114        transfer_list_t transfers_control_full;
    95         transfer_list_t transfers_control_slow;
    96         transfer_list_t transfers_interrupt;
    97115
     116        /** Pointer table to the above lists, helps during scheduling */
    98117        transfer_list_t *transfers[2][4];
    99118
     119        /** Code to be executed in kernel interrupt handler */
    100120        irq_code_t interrupt_code;
    101121
    102         fid_t cleaner;
    103         fid_t debug_checker;
     122        /** Fibril periodically checking status register*/
     123        fid_t interrupt_emulator;
     124
     125        /** Indicator of hw interrupts availability */
    104126        bool hw_interrupts;
     127
     128        /** Number of hw failures detected. */
    105129        unsigned hw_failures;
    106 
    107         ddf_fun_t *ddf_instance;
    108130} hc_t;
    109131
  • uspace/drv/uhci-hcd/hw_struct/queue_head.h

    rb77ce84 r34e8bab  
    3434#ifndef DRV_UHCI_QH_H
    3535#define DRV_UHCI_QH_H
    36 
    37 /* libc */
    3836#include <assert.h>
    3937
    4038#include "link_pointer.h"
     39#include "transfer_descriptor.h"
     40#include "utils/malloc32.h"
    4141
     42/** This structure is defined in UHCI design guide p. 31 */
    4243typedef struct queue_head {
     44        /** Pointer to the next entity (another QH or TD */
    4345        volatile link_pointer_t next;
     46        /** Pointer to the contained entities (execution controlled by vertical flag*/
    4447        volatile link_pointer_t element;
    4548} __attribute__((packed)) qh_t;
     
    6467 * @param[in] pa Physical address of the next queue head.
    6568 *
    66  * Adds proper flag. If the pointer is NULL or terminal, sets next to terminal
    67  * NULL.
     69 * Adds proper flag. If the pointer is NULL, sets next to terminal NULL.
    6870 */
    69 static inline void qh_set_next_qh(qh_t *instance, uint32_t pa)
     71static inline void qh_set_next_qh(qh_t *instance, qh_t *next)
    7072{
    71         /* Address is valid and not terminal */
    72         if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
     73        uint32_t pa = addr_to_phys(next);
     74        if (pa) {
    7375                instance->next = LINK_POINTER_QH(pa);
    7476        } else {
     
    8082 *
    8183 * @param[in] instance qh_t structure to initialize.
    82  * @param[in] pa Physical address of the next queue head.
    83  *
    84  * Adds proper flag. If the pointer is NULL or terminal, sets element
    85  * to terminal NULL.
    86  */
    87 static inline void qh_set_element_qh(qh_t *instance, uint32_t pa)
    88 {
    89         /* Address is valid and not terminal */
    90         if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
    91                 instance->element = LINK_POINTER_QH(pa);
    92         } else {
    93                 instance->element = LINK_POINTER_TERM;
    94         }
    95 }
    96 /*----------------------------------------------------------------------------*/
    97 /** Set queue head element pointer
    98  *
    99  * @param[in] instance qh_t structure to initialize.
    10084 * @param[in] pa Physical address of the TD structure.
    10185 *
    102  * Adds proper flag. If the pointer is NULL or terminal, sets element
    103  * to terminal NULL.
     86 * Adds proper flag. If the pointer is NULL, sets element to terminal NULL.
    10487 */
    105 static inline void qh_set_element_td(qh_t *instance, uint32_t pa)
     88static inline void qh_set_element_td(qh_t *instance, td_t *td)
    10689{
    107         if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
     90        uint32_t pa = addr_to_phys(td);
     91        if (pa) {
    10892                instance->element = LINK_POINTER_TD(pa);
    10993        } else {
     
    11195        }
    11296}
    113 
    11497#endif
    11598/**
  • uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c

    rb77ce84 r34e8bab  
    7777
    7878        instance->status = 0
    79             | ((err_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
     79            | ((err_count & TD_STATUS_ERROR_COUNT_MASK)
     80                << TD_STATUS_ERROR_COUNT_POS)
    8081            | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
    8182            | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0)
     
    8990            | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
    9091            | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
    91             | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
    92             | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
     92            | ((target.address & TD_DEVICE_ADDRESS_MASK)
     93                << TD_DEVICE_ADDRESS_POS)
     94            | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK)
     95                << TD_DEVICE_ENDPOINT_POS)
    9396            | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
    9497
     
    114117        assert(instance);
    115118
    116         /* this is hc internal error it should never be reported */
     119        /* This is hc internal error it should never be reported. */
    117120        if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0)
    118121                return EAGAIN;
     
    123126                return EBADCHECKSUM;
    124127
    125         /* hc does not end transaction on these, it should never be reported */
     128        /* HC does not end transactions on these, it should never be reported */
    126129        if ((instance->status & TD_STATUS_ERROR_NAK) != 0)
    127130                return EAGAIN;
    128131
    129         /* buffer overrun or underrun */
     132        /* Buffer overrun or underrun */
    130133        if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0)
    131134                return ERANGE;
    132135
    133         /* device babble is something serious */
     136        /* Device babble is something serious */
    134137        if ((instance->status & TD_STATUS_ERROR_BABBLE) != 0)
    135138                return EIO;
    136139
    137         /* stall might represent err count reaching zero or stall response from
    138          * the device, is err count reached zero, one of the above is reported*/
     140        /* Stall might represent err count reaching zero or stall response from
     141         * the device. If err count reached zero, one of the above is reported*/
    139142        if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
    140143                return ESTALL;
  • uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.h

    rb77ce84 r34e8bab  
    4040#include "link_pointer.h"
    4141
    42 /** UHCI Transfer Descriptor */
     42/** Transfer Descriptor, defined in UHCI design guide p. 26 */
    4343typedef struct transfer_descriptor {
     44        /** Pointer to the next entity (TD or QH) */
    4445        link_pointer_t next;
    4546
     47        /** Status doubleword */
    4648        volatile uint32_t status;
    4749#define TD_STATUS_RESERVED_MASK 0xc000f800
    48 #define TD_STATUS_SPD_FLAG ( 1 << 29 )
    49 #define TD_STATUS_ERROR_COUNT_POS ( 27 )
    50 #define TD_STATUS_ERROR_COUNT_MASK ( 0x3 )
    51 #define TD_STATUS_LOW_SPEED_FLAG ( 1 << 26 )
    52 #define TD_STATUS_ISOCHRONOUS_FLAG ( 1 << 25 )
    53 #define TD_STATUS_IOC_FLAG ( 1 << 24 )
     50#define TD_STATUS_SPD_FLAG         (1 << 29)
     51#define TD_STATUS_ERROR_COUNT_POS 27
     52#define TD_STATUS_ERROR_COUNT_MASK 0x3
     53#define TD_STATUS_LOW_SPEED_FLAG   (1 << 26)
     54#define TD_STATUS_ISOCHRONOUS_FLAG (1 << 25)
     55#define TD_STATUS_IOC_FLAG         (1 << 24)
    5456
    55 #define TD_STATUS_ERROR_ACTIVE ( 1 << 23 )
    56 #define TD_STATUS_ERROR_STALLED ( 1 << 22 )
    57 #define TD_STATUS_ERROR_BUFFER ( 1 << 21 )
    58 #define TD_STATUS_ERROR_BABBLE ( 1 << 20 )
    59 #define TD_STATUS_ERROR_NAK ( 1 << 19 )
    60 #define TD_STATUS_ERROR_CRC ( 1 << 18 )
    61 #define TD_STATUS_ERROR_BIT_STUFF ( 1 << 17 )
    62 #define TD_STATUS_ERROR_RESERVED ( 1 << 16 )
     57#define TD_STATUS_ERROR_ACTIVE    (1 << 23)
     58#define TD_STATUS_ERROR_STALLED   (1 << 22)
     59#define TD_STATUS_ERROR_BUFFER    (1 << 21)
     60#define TD_STATUS_ERROR_BABBLE    (1 << 20)
     61#define TD_STATUS_ERROR_NAK       (1 << 19)
     62#define TD_STATUS_ERROR_CRC       (1 << 18)
     63#define TD_STATUS_ERROR_BIT_STUFF (1 << 17)
     64#define TD_STATUS_ERROR_RESERVED  (1 << 16)
    6365#define TD_STATUS_ERROR_POS 16
    64 #define TD_STATUS_ERROR_MASK ( 0xff )
     66#define TD_STATUS_ERROR_MASK 0xff
    6567
    6668#define TD_STATUS_ACTLEN_POS 0
    6769#define TD_STATUS_ACTLEN_MASK 0x7ff
    6870
     71        /* double word with USB device specific info */
    6972        volatile uint32_t device;
    7073#define TD_DEVICE_MAXLEN_POS 21
    71 #define TD_DEVICE_MAXLEN_MASK ( 0x7ff )
    72 #define TD_DEVICE_RESERVED_FLAG ( 1 << 20 )
    73 #define TD_DEVICE_DATA_TOGGLE_ONE_FLAG ( 1 << 19 )
     74#define TD_DEVICE_MAXLEN_MASK 0x7ff
     75#define TD_DEVICE_RESERVED_FLAG        (1 << 20)
     76#define TD_DEVICE_DATA_TOGGLE_ONE_FLAG (1 << 19)
    7477#define TD_DEVICE_ENDPOINT_POS 15
    75 #define TD_DEVICE_ENDPOINT_MASK ( 0xf )
     78#define TD_DEVICE_ENDPOINT_MASK 0xf
    7679#define TD_DEVICE_ADDRESS_POS 8
    77 #define TD_DEVICE_ADDRESS_MASK ( 0x7f )
     80#define TD_DEVICE_ADDRESS_MASK 0x7f
    7881#define TD_DEVICE_PID_POS 0
    79 #define TD_DEVICE_PID_MASK ( 0xff )
     82#define TD_DEVICE_PID_MASK 0xff
    8083
     84        /** Pointer(physical) to the beginning of the transaction's buffer */
    8185        volatile uint32_t buffer_ptr;
    8286
    83         /* there is 16 bytes of data available here, according to UHCI
    84          * Design guide, according to linux kernel the hardware does not care,
    85          * it just needs to be aligned, we don't use it anyway
     87        /* According to UHCI design guide, there is 16 bytes of
     88         * data available here.
     89         * According to linux kernel the hardware does not care,
     90         * it just needs to be aligned. We don't use it anyway.
    8691         */
    8792} __attribute__((packed)) td_t;
  • uspace/drv/uhci-hcd/main.c

    rb77ce84 r34e8bab  
    3939#include <usb/debug.h>
    4040
    41 #include "iface.h"
    4241#include "uhci.h"
    4342
     
    6261int uhci_add_device(ddf_dev_t *device)
    6362{
    64         usb_log_debug("uhci_add_device() called\n");
     63        usb_log_debug2("uhci_add_device() called\n");
    6564        assert(device);
     65
    6666        uhci_t *uhci = malloc(sizeof(uhci_t));
    6767        if (uhci == NULL) {
     
    7272        int ret = uhci_init(uhci, device);
    7373        if (ret != EOK) {
    74                 usb_log_error("Failed to initialize UHCI driver: %s.\n",
    75                     str_error(ret));
     74                usb_log_error("Failed(%d) to initialize UHCI driver: %s.\n",
     75                    ret, str_error(ret));
    7676                return ret;
    7777        }
     
    8585/** Initialize global driver structures (NONE).
    8686 *
    87  * @param[in] argc Nmber of arguments in argv vector (ignored).
     87 * @param[in] argc Number of arguments in argv vector (ignored).
    8888 * @param[in] argv Cmdline argument vector (ignored).
    8989 * @return Error code.
     
    9494{
    9595        printf(NAME ": HelenOS UHCI driver.\n");
    96 
    97         sleep(3); /* TODO: remove in final version */
    9896        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    9997
  • uspace/drv/uhci-hcd/pci.c

    rb77ce84 r34e8bab  
    4444#include "pci.h"
    4545
    46 /** Get address of registers and IRQ for given device.
     46/** Get I/O address of registers and IRQ for given device.
    4747 *
    4848 * @param[in] dev Device asking for the addresses.
     
    5353 */
    5454int pci_get_my_registers(ddf_dev_t *dev,
    55     uintptr_t *io_reg_address, size_t *io_reg_size,
    56     int *irq_no)
     55    uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
    5756{
    5857        assert(dev != NULL);
    5958
    60         int parent_phone = devman_parent_device_connect(dev->handle,
    61             IPC_FLAG_BLOCKING);
     59        int parent_phone =
     60            devman_parent_device_connect(dev->handle, IPC_FLAG_BLOCKING);
    6261        if (parent_phone < 0) {
    6362                return parent_phone;
    6463        }
    6564
    66         int rc;
    6765        hw_resource_list_t hw_resources;
    68         rc = hw_res_get_resource_list(parent_phone, &hw_resources);
     66        int rc = hw_res_get_resource_list(parent_phone, &hw_resources);
    6967        if (rc != EOK) {
    7068                goto leave;
     
    9593                            res->res.io_range.address, res->res.io_range.size);
    9694                        io_found = true;
     95                        break;
    9796
    9897                default:
     
    113112leave:
    114113        async_hangup(parent_phone);
    115 
    116114        return rc;
    117115}
     
    145143        }
    146144
    147         /* See UHCI design guide for these values,
     145        /* See UHCI design guide for these values p.45,
    148146         * write all WC bits in USB legacy register */
    149147        sysarg_t address = 0xc0;
  • uspace/drv/uhci-hcd/root_hub.c

    rb77ce84 r34e8bab  
    5555        int ret = asprintf(&match_str, "usb&uhci&root-hub");
    5656        if (ret < 0) {
    57                 usb_log_error("Failed to create root hub match string.\n");
    58                 return ENOMEM;
     57                usb_log_error(
     58                    "Failed(%d) to create root hub match string: %s.\n",
     59                    ret, str_error(ret));
     60                return ret;
    5961        }
    6062
    6163        ret = ddf_fun_add_match_id(fun, match_str, 100);
    6264        if (ret != EOK) {
     65                free(match_str);
    6366                usb_log_error("Failed(%d) to add root hub match id: %s\n",
    6467                    ret, str_error(ret));
     
    6669        }
    6770
    68         hw_resource_list_t *resource_list = &instance->resource_list;
    69         resource_list->count = 1;
    70         resource_list->resources = &instance->io_regs;
    71         assert(resource_list->resources);
     71        /* Initialize resource structure */
     72        instance->resource_list.count = 1;
     73        instance->resource_list.resources = &instance->io_regs;
     74
    7275        instance->io_regs.type = IO_RANGE;
    7376        instance->io_regs.res.io_range.address = reg_addr;
  • uspace/drv/uhci-hcd/root_hub.h

    rb77ce84 r34e8bab  
    3939#include <ops/hw_res.h>
    4040
     41/** DDF support structure for uhci-rhd driver, provides I/O resources */
    4142typedef struct rh {
     43        /** List of resources available to the root hub. */
    4244        hw_resource_list_t resource_list;
     45        /** The only resource in the above list */
    4346        hw_resource_t io_regs;
    4447} rh_t;
  • uspace/drv/uhci-hcd/transfer_list.c

    rb77ce84 r34e8bab  
    5757                return ENOMEM;
    5858        }
    59         instance->queue_head_pa = addr_to_phys(instance->queue_head);
     59        uint32_t queue_head_pa = addr_to_phys(instance->queue_head);
    6060        usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n",
    61             name, instance->queue_head, instance->queue_head_pa);
     61            name, instance->queue_head, queue_head_pa);
    6262
    6363        qh_init(instance->queue_head);
     
    6767}
    6868/*----------------------------------------------------------------------------*/
     69/** Dispose transfer list structures.
     70 *
     71 * @param[in] instance Memory place to use.
     72 *
     73 * Frees memory for internal qh_t structure.
     74 */
     75void transfer_list_fini(transfer_list_t *instance)
     76{
     77        assert(instance);
     78        free32(instance->queue_head);
     79}
    6980/** Set the next list in transfer list chain.
    7081 *
     
    8192        if (!instance->queue_head)
    8293                return;
    83         /* Set both queue_head.next to point to the follower */
    84         qh_set_next_qh(instance->queue_head, next->queue_head_pa);
    85 }
    86 /*----------------------------------------------------------------------------*/
    87 /** Submit transfer batch to the list and queue.
     94        /* Set queue_head.next to point to the follower */
     95        qh_set_next_qh(instance->queue_head, next->queue_head);
     96}
     97/*----------------------------------------------------------------------------*/
     98/** Add transfer batch to the list and queue.
    8899 *
    89100 * @param[in] instance List to use.
    90101 * @param[in] batch Transfer batch to submit.
    91  * @return Error code
    92102 *
    93103 * The batch is added to the end of the list and queue.
     
    109119        } else {
    110120                /* There is something scheduled */
    111                 usb_transfer_batch_t *last = list_get_instance(
    112                     instance->batch_list.prev, usb_transfer_batch_t, link);
     121                usb_transfer_batch_t *last =
     122                    usb_transfer_batch_from_link(instance->batch_list.prev);
    113123                last_qh = batch_qh(last);
    114124        }
     
    118128        /* keep link */
    119129        batch_qh(batch)->next = last_qh->next;
    120         qh_set_next_qh(last_qh, pa);
     130        qh_set_next_qh(last_qh, batch_qh(batch));
    121131
    122132        asm volatile ("": : :"memory");
     
    132142}
    133143/*----------------------------------------------------------------------------*/
    134 /** Create list for finished batches.
     144/** Add completed bantches to the provided list.
    135145 *
    136146 * @param[in] instance List to use.
     
    147157                link_t *next = current->next;
    148158                usb_transfer_batch_t *batch =
    149                     list_get_instance(current, usb_transfer_batch_t, link);
     159                    usb_transfer_batch_from_link(current);
    150160
    151161                if (batch_is_complete(batch)) {
    152                         /* Save for post-processing */
     162                        /* Save for processing */
    153163                        transfer_list_remove_batch(instance, batch);
    154164                        list_append(current, done);
     
    159169}
    160170/*----------------------------------------------------------------------------*/
    161 /** Walk the list and abort all batches.
     171/** Walk the list and finish all batches with EINTR.
    162172 *
    163173 * @param[in] instance List to use.
     
    169179                link_t *current = instance->batch_list.next;
    170180                usb_transfer_batch_t *batch =
    171                     list_get_instance(current, usb_transfer_batch_t, link);
     181                    usb_transfer_batch_from_link(current);
    172182                transfer_list_remove_batch(instance, batch);
    173                 usb_transfer_batch_finish_error(batch, EIO);
     183                usb_transfer_batch_finish_error(batch, EINTR);
    174184        }
    175185        fibril_mutex_unlock(&instance->guard);
     
    180190 * @param[in] instance List to use.
    181191 * @param[in] batch Transfer batch to remove.
    182  * @return Error code
    183192 *
    184193 * Does not lock the transfer list, caller is responsible for that.
     
    197206
    198207        const char *qpos = NULL;
     208        qh_t *prev_qh = NULL;
    199209        /* Remove from the hardware queue */
    200210        if (instance->batch_list.next == &batch->link) {
    201211                /* I'm the first one here */
    202                 assert((instance->queue_head->next & LINK_POINTER_ADDRESS_MASK)
    203                     == addr_to_phys(batch_qh(batch)));
    204                 instance->queue_head->next = batch_qh(batch)->next;
     212                prev_qh = instance->queue_head;
    205213                qpos = "FIRST";
    206214        } else {
     215                /* The thing before me is a batch too */
    207216                usb_transfer_batch_t *prev =
    208                     list_get_instance(
    209                         batch->link.prev, usb_transfer_batch_t, link);
    210                 assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK)
    211                     == addr_to_phys(batch_qh(batch)));
    212                 batch_qh(prev)->next = batch_qh(batch)->next;
     217                    usb_transfer_batch_from_link(batch->link.prev);
     218                prev_qh = batch_qh(prev);
    213219                qpos = "NOT FIRST";
    214220        }
     221        assert((prev_qh->next & LINK_POINTER_ADDRESS_MASK)
     222            == addr_to_phys(batch_qh(batch)));
     223        prev_qh->next = batch_qh(batch)->next;
    215224        asm volatile ("": : :"memory");
    216225        /* Remove from the batch list */
    217226        list_remove(&batch->link);
    218         usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n",
     227        usb_log_debug("Batch(%p) removed (%s) from %s, next: %x.\n",
    219228            batch, qpos, instance->name, batch_qh(batch)->next);
    220229}
  • uspace/drv/uhci-hcd/transfer_list.h

    rb77ce84 r34e8bab  
    3939#include "batch.h"
    4040#include "hw_struct/queue_head.h"
    41 #include "utils/malloc32.h"
    4241
     42/** Structure maintaining both hw queue and software list
     43 * of currently executed transfers
     44 */
    4345typedef struct transfer_list
    4446{
     47        /** Guard against multiple add/remove races */
    4548        fibril_mutex_t guard;
     49        /** UHCI hw structure represeting this queue */
    4650        qh_t *queue_head;
    47         uint32_t queue_head_pa;
     51        /** Assigned name, for nicer debug output */
    4852        const char *name;
     53        /** List of all batches in this list */
    4954        link_t batch_list;
    5055} transfer_list_t;
    5156
    52 /** Dispose transfer list structures.
    53  *
    54  * @param[in] instance Memory place to use.
    55  *
    56  * Frees memory for internal qh_t structure.
    57  */
    58 static inline void transfer_list_fini(transfer_list_t *instance)
    59 {
    60         assert(instance);
    61         free32(instance->queue_head);
    62 }
    63 
     57void transfer_list_fini(transfer_list_t *instance);
    6458int transfer_list_init(transfer_list_t *instance, const char *name);
    65 
    6659void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
    67 
    68 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);
    69 
     60void transfer_list_add_batch(
     61    transfer_list_t *instance, usb_transfer_batch_t *batch);
    7062void transfer_list_remove_finished(transfer_list_t *instance, link_t *done);
    71 
    7263void transfer_list_abort_all(transfer_list_t *instance);
    7364#endif
  • uspace/drv/uhci-hcd/uhci.c

    rb77ce84 r34e8bab  
    4444#include "pci.h"
    4545
    46 /** IRQ handling callback, identifies device
     46/** IRQ handling callback, forward status from call to diver structure.
    4747 *
    4848 * @param[in] dev DDF instance of the device to use.
    4949 * @param[in] iid (Unused).
    50  * @param[in] call Pointer to the call that represents interrupt.
     50 * @param[in] call Pointer to the call from kernel.
    5151 */
    5252static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
     
    6161/** Get address of the device identified by handle.
    6262 *
    63  * @param[in] dev DDF instance of the device to use.
    64  * @param[in] iid (Unused).
    65  * @param[in] call Pointer to the call that represents interrupt.
     63 * @param[in] fun DDF instance of the function to use.
     64 * @param[in] handle DDF handle of the driver seeking its USB address.
     65 * @param[out] address Found address.
    6666 */
    6767static int usb_iface_get_address(
     
    6969{
    7070        assert(fun);
    71         usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc.manager;
     71        usb_device_keeper_t *manager =
     72            &((uhci_t*)fun->dev->driver_data)->hc.manager;
    7273
    7374        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    8384}
    8485/*----------------------------------------------------------------------------*/
    85 /** Gets handle of the respective hc (this or parent device).
    86  *
    87  * @param[in] root_hub_fun Root hub function seeking hc handle.
    88  * @param[out] handle Place to write the handle.
     86/** Gets handle of the respective hc.
     87 *
     88 * @param[in] fun DDF function of uhci device.
     89 * @param[out] handle Host cotnroller handle.
    8990 * @return Error code.
    9091 */
     
    100101}
    101102/*----------------------------------------------------------------------------*/
    102 /** This iface is generic for both RH and HC. */
     103/** USB interface implementation used by RH */
    103104static usb_iface_t usb_iface = {
    104105        .get_hc_handle = usb_iface_get_hc_handle,
     
    106107};
    107108/*----------------------------------------------------------------------------*/
     109/** Operations supported by the HC driver */
    108110static ddf_dev_ops_t hc_ops = {
    109 //      .interfaces[USB_DEV_IFACE] = &usb_iface,
    110111        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    111112};
     
    122123}
    123124/*----------------------------------------------------------------------------*/
     125/** Interface to provide the root hub driver with hw info */
    124126static hw_res_ops_t hw_res_iface = {
    125127        .get_resource_list = get_resource_list,
     
    127129};
    128130/*----------------------------------------------------------------------------*/
     131/** RH function support for uhci-rhd */
    129132static ddf_dev_ops_t rh_ops = {
    130133        .interfaces[USB_DEV_IFACE] = &usb_iface,
     
    132135};
    133136/*----------------------------------------------------------------------------*/
    134 /** Initialize hc and rh ddf structures and their respective drivers.
     137/** Initialize hc and rh DDF structures and their respective drivers.
    135138 *
    136139 * @param[in] instance UHCI structure to use.
     
    138141 *
    139142 * This function does all the preparatory work for hc and rh drivers:
    140  *  - gets device hw resources
    141  *  - disables UHCI legacy support
     143 *  - gets device's hw resources
     144 *  - disables UHCI legacy support (PCI config space)
    142145 *  - asks for interrupt
    143146 *  - registers interrupt handler
     
    193196        ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
    194197        CHECK_RET_DEST_FUN_RETURN(ret,
    195             "Failed(%d) to create HC function.\n", ret);
     198            "Failed(%d) to create HC function: %s.\n", ret, str_error(ret));
    196199
    197200        ret = hc_init(&instance->hc, instance->hc_fun,
    198201            (void*)io_reg_base, io_reg_size, interrupts);
    199         CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret);
     202        CHECK_RET_DEST_FUN_RETURN(ret,
     203            "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret));
     204
    200205        instance->hc_fun->ops = &hc_ops;
    201206        instance->hc_fun->driver_data = &instance->hc;
     
    221226            &instance->hc.interrupt_code);
    222227        CHECK_RET_FINI_RETURN(ret,
    223             "Failed(%d) to register interrupt handler.\n", ret);
     228            "Failed(%d) to register interrupt handler: %s.\n",
     229            ret, str_error(ret));
    224230
    225231        instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
    226232        ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    227233        CHECK_RET_FINI_RETURN(ret,
    228             "Failed(%d) to create root hub function.\n", ret);
     234            "Failed(%d) to create root hub function: %s.\n",
     235            ret, str_error(ret));
    229236
    230237        ret = rh_init(&instance->rh, instance->rh_fun,
    231238            (uintptr_t)instance->hc.registers + 0x10, 4);
    232239        CHECK_RET_FINI_RETURN(ret,
    233             "Failed(%d) to setup UHCI root hub.\n", ret);
     240            "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
    234241
    235242        instance->rh_fun->ops = &rh_ops;
     
    237244        ret = ddf_fun_bind(instance->rh_fun);
    238245        CHECK_RET_FINI_RETURN(ret,
    239             "Failed(%d) to register UHCI root hub.\n", ret);
     246            "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
    240247
    241248        return EOK;
  • uspace/drv/uhci-hcd/uhci.h

    rb77ce84 r34e8bab  
    4141#include "root_hub.h"
    4242
     43/** Structure representing both functions of UHCI hc, USB host controller
     44 * and USB root hub */
    4345typedef struct uhci {
     46        /** Pointer to DDF represenation of UHCI host controller */
    4447        ddf_fun_t *hc_fun;
     48        /** Pointer to DDF represenation of UHCI root hub */
    4549        ddf_fun_t *rh_fun;
    4650
     51        /** Internal driver's represenation of UHCI host controller */
    4752        hc_t hc;
     53        /** Internal driver's represenation of UHCI root hub */
    4854        rh_t rh;
    4955} uhci_t;
    5056
    5157int uhci_init(uhci_t *instance, ddf_dev_t *device);
    52 
    5358#endif
    5459/**
  • uspace/lib/usb/src/host/usb_endpoint_manager.c

    rb77ce84 r34e8bab  
    211211
    212212        node_t *node = hash_table_get_instance(item, node_t, link);
     213        if (node->ep->active)
     214                return EBUSY;
     215
    213216        instance->free_bw += node->bw;
    214217        hash_table_remove(&instance->ep_table, key, MAX_KEYS);
Note: See TracChangeset for help on using the changeset viewer.