Changes in / [34e8bab:b77ce84] in mainline


Ignore:
Location:
uspace
Files:
16 edited

Legend:

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

    r34e8bab rb77ce84  
    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 structures were successfully created,
     78 * @return Valid pointer if all substructures were successfully created,
    7979 * NULL otherwise.
    8080 *
     
    126126
    127127        qh_init(uhci_data->qh);
    128         qh_set_element_td(uhci_data->qh, uhci_data->tds);
     128        qh_set_element_td(uhci_data->qh, addr_to_phys(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  */
    402398qh_t * batch_qh(usb_transfer_batch_t *instance)
    403399{
  • uspace/drv/uhci-hcd/batch.h

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

    r34e8bab rb77ce84  
    6666static int hc_interrupt_emulator(void *arg);
    6767static int hc_debug_checker(void *arg);
     68#if 0
     69static bool usb_is_allowed(
     70    bool low_speed, usb_transfer_type_t transfer, size_t size);
     71#endif
    6872/*----------------------------------------------------------------------------*/
    6973/** Initialize UHCI hcd driver structure
     
    8589        int ret;
    8690
    87 #define CHECK_RET_RETURN(ret, message...) \
     91#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    8892        if (ret != EOK) { \
    8993                usb_log_error(message); \
     94                if (instance->ddf_instance) \
     95                        ddf_fun_destroy(instance->ddf_instance); \
    9096                return ret; \
    9197        } else (void) 0
     
    9399        instance->hw_interrupts = interrupts;
    94100        instance->hw_failures = 0;
     101
     102        /* Setup UHCI function. */
     103        instance->ddf_instance = fun;
    95104
    96105        /* allow access to hc control registers */
    97106        regs_t *io;
    98107        ret = pio_enable(regs, reg_size, (void**)&io);
    99         CHECK_RET_RETURN(ret,
     108        CHECK_RET_DEST_FUN_RETURN(ret,
    100109            "Failed(%d) to gain access to registers at %p: %s.\n",
    101             ret, io, str_error(ret));
     110            ret, str_error(ret), io);
    102111        instance->registers = io;
    103112        usb_log_debug("Device registers at %p(%u) accessible.\n",
     
    105114
    106115        ret = hc_init_mem_structures(instance);
    107         CHECK_RET_RETURN(ret,
    108             "Failed(%d) to initialize UHCI memory structures: %s.\n",
    109             ret, str_error(ret));
     116        CHECK_RET_DEST_FUN_RETURN(ret,
     117            "Failed to initialize UHCI memory structures.\n");
    110118
    111119        hc_init_hw(instance);
    112120        if (!interrupts) {
    113                 instance->interrupt_emulator =
     121                instance->cleaner =
    114122                    fibril_create(hc_interrupt_emulator, instance);
    115                 fibril_add_ready(instance->interrupt_emulator);
    116         }
    117         (void)hc_debug_checker;
     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);
    118131
    119132        return EOK;
     
    215228        /* Set all frames to point to the first queue head */
    216229        const uint32_t queue =
    217             LINK_POINTER_QH(addr_to_phys(
    218                 instance->transfers_interrupt.queue_head));
     230          instance->transfers_interrupt.queue_head_pa
     231          | LINK_POINTER_QUEUE_HEAD_FLAG;
    219232
    220233        unsigned i = 0;
     
    223236        }
    224237
    225         /* Init device keeper */
     238        /* Init device keeper*/
    226239        usb_device_keeper_init(&instance->manager);
    227240        usb_log_debug("Initialized device manager.\n");
     
    466479#undef QH
    467480}
     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
     490bool 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
    468508/**
    469509 * @}
  • uspace/drv/uhci-hcd/hc.h

    r34e8bab rb77ce84  
    4848#include "transfer_list.h"
    4949
    50 /** UHCI I/O registers layout */
    5150typedef struct uhci_regs {
    52         /** Command register, controls HC behaviour */
    5351        uint16_t usbcmd;
    5452#define UHCI_CMD_MAX_PACKET (1 << 7)
     
    6159#define UHCI_CMD_RUN_STOP  (1 << 0)
    6260
    63         /** Status register, 1 means interrupt is asserted (if enabled) */
    6461        uint16_t usbsts;
    6562#define UHCI_STATUS_HALTED (1 << 5)
     
    7067#define UHCI_STATUS_INTERRUPT (1 << 0)
    7168
    72         /** Interrupt enabled registers */
    7369        uint16_t usbintr;
    7470#define UHCI_INTR_SHORT_PACKET (1 << 3)
     
    7773#define UHCI_INTR_CRC (1 << 0)
    7874
    79         /** Register stores frame number used in SOF packet */
    8075        uint16_t frnum;
    81 
    82         /** Pointer(physical) to the Frame List */
    8376        uint32_t flbaseadd;
    84 
    85         /** SOF modification to match external timers */
    8677        uint8_t sofmod;
    8778} regs_t;
     
    9283#define UHCI_ALLOWED_HW_FAIL 5
    9384
    94 /* Main HC driver structure */
    9585typedef struct hc {
    96         /** USB bus driver, devices and addresses */
    9786        usb_device_keeper_t manager;
    98         /** USB bus driver, endpoints */
    9987        usb_endpoint_manager_t ep_manager;
    10088
    101         /** Addresses of I/O registers */
    10289        regs_t *registers;
    10390
    104         /** Frame List contains 1024 link pointers */
    10591        link_pointer_t *frame_list;
    10692
    107         /** List and queue of interrupt transfers */
     93        transfer_list_t transfers_bulk_full;
     94        transfer_list_t transfers_control_full;
     95        transfer_list_t transfers_control_slow;
    10896        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 */
    112         transfer_list_t transfers_bulk_full;
    113         /** List and queue of full speed control transfers */
    114         transfer_list_t transfers_control_full;
    11597
    116         /** Pointer table to the above lists, helps during scheduling */
    11798        transfer_list_t *transfers[2][4];
    11899
    119         /** Code to be executed in kernel interrupt handler */
    120100        irq_code_t interrupt_code;
    121101
    122         /** Fibril periodically checking status register*/
    123         fid_t interrupt_emulator;
     102        fid_t cleaner;
     103        fid_t debug_checker;
     104        bool hw_interrupts;
     105        unsigned hw_failures;
    124106
    125         /** Indicator of hw interrupts availability */
    126         bool hw_interrupts;
    127 
    128         /** Number of hw failures detected. */
    129         unsigned hw_failures;
     107        ddf_fun_t *ddf_instance;
    130108} hc_t;
    131109
  • uspace/drv/uhci-hcd/hw_struct/queue_head.h

    r34e8bab rb77ce84  
    3434#ifndef DRV_UHCI_QH_H
    3535#define DRV_UHCI_QH_H
     36
     37/* libc */
    3638#include <assert.h>
    3739
    3840#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 */
    4342typedef struct queue_head {
    44         /** Pointer to the next entity (another QH or TD */
    4543        volatile link_pointer_t next;
    46         /** Pointer to the contained entities (execution controlled by vertical flag*/
    4744        volatile link_pointer_t element;
    4845} __attribute__((packed)) qh_t;
     
    6764 * @param[in] pa Physical address of the next queue head.
    6865 *
    69  * Adds proper flag. If the pointer is NULL, sets next to terminal NULL.
     66 * Adds proper flag. If the pointer is NULL or terminal, sets next to terminal
     67 * NULL.
    7068 */
    71 static inline void qh_set_next_qh(qh_t *instance, qh_t *next)
     69static inline void qh_set_next_qh(qh_t *instance, uint32_t pa)
    7270{
    73         uint32_t pa = addr_to_phys(next);
    74         if (pa) {
     71        /* Address is valid and not terminal */
     72        if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
    7573                instance->next = LINK_POINTER_QH(pa);
    7674        } else {
     
    8280 *
    8381 * @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 */
     87static 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.
    84100 * @param[in] pa Physical address of the TD structure.
    85101 *
    86  * Adds proper flag. If the pointer is NULL, sets element to terminal NULL.
     102 * Adds proper flag. If the pointer is NULL or terminal, sets element
     103 * to terminal NULL.
    87104 */
    88 static inline void qh_set_element_td(qh_t *instance, td_t *td)
     105static inline void qh_set_element_td(qh_t *instance, uint32_t pa)
    89106{
    90         uint32_t pa = addr_to_phys(td);
    91         if (pa) {
     107        if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
    92108                instance->element = LINK_POINTER_TD(pa);
    93109        } else {
     
    95111        }
    96112}
     113
    97114#endif
    98115/**
  • uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c

    r34e8bab rb77ce84  
    7777
    7878        instance->status = 0
    79             | ((err_count & TD_STATUS_ERROR_COUNT_MASK)
    80                 << TD_STATUS_ERROR_COUNT_POS)
     79            | ((err_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
    8180            | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
    8281            | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0)
     
    9089            | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
    9190            | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
    92             | ((target.address & TD_DEVICE_ADDRESS_MASK)
    93                 << TD_DEVICE_ADDRESS_POS)
    94             | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK)
    95                 << TD_DEVICE_ENDPOINT_POS)
     91            | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
     92            | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
    9693            | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
    9794
     
    117114        assert(instance);
    118115
    119         /* This is hc internal error it should never be reported. */
     116        /* this is hc internal error it should never be reported */
    120117        if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0)
    121118                return EAGAIN;
     
    126123                return EBADCHECKSUM;
    127124
    128         /* HC does not end transactions on these, it should never be reported */
     125        /* hc does not end transaction on these, it should never be reported */
    129126        if ((instance->status & TD_STATUS_ERROR_NAK) != 0)
    130127                return EAGAIN;
    131128
    132         /* Buffer overrun or underrun */
     129        /* buffer overrun or underrun */
    133130        if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0)
    134131                return ERANGE;
    135132
    136         /* Device babble is something serious */
     133        /* device babble is something serious */
    137134        if ((instance->status & TD_STATUS_ERROR_BABBLE) != 0)
    138135                return EIO;
    139136
    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*/
     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*/
    142139        if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
    143140                return ESTALL;
  • uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.h

    r34e8bab rb77ce84  
    4040#include "link_pointer.h"
    4141
    42 /** Transfer Descriptor, defined in UHCI design guide p. 26 */
     42/** UHCI Transfer Descriptor */
    4343typedef struct transfer_descriptor {
    44         /** Pointer to the next entity (TD or QH) */
    4544        link_pointer_t next;
    4645
    47         /** Status doubleword */
    4846        volatile uint32_t status;
    4947#define TD_STATUS_RESERVED_MASK 0xc000f800
    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)
     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 )
    5654
    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)
     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 )
    6563#define TD_STATUS_ERROR_POS 16
    66 #define TD_STATUS_ERROR_MASK 0xff
     64#define TD_STATUS_ERROR_MASK ( 0xff )
    6765
    6866#define TD_STATUS_ACTLEN_POS 0
    6967#define TD_STATUS_ACTLEN_MASK 0x7ff
    7068
    71         /* double word with USB device specific info */
    7269        volatile uint32_t device;
    7370#define TD_DEVICE_MAXLEN_POS 21
    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)
     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 )
    7774#define TD_DEVICE_ENDPOINT_POS 15
    78 #define TD_DEVICE_ENDPOINT_MASK 0xf
     75#define TD_DEVICE_ENDPOINT_MASK ( 0xf )
    7976#define TD_DEVICE_ADDRESS_POS 8
    80 #define TD_DEVICE_ADDRESS_MASK 0x7f
     77#define TD_DEVICE_ADDRESS_MASK ( 0x7f )
    8178#define TD_DEVICE_PID_POS 0
    82 #define TD_DEVICE_PID_MASK 0xff
     79#define TD_DEVICE_PID_MASK ( 0xff )
    8380
    84         /** Pointer(physical) to the beginning of the transaction's buffer */
    8581        volatile uint32_t buffer_ptr;
    8682
    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.
     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
    9186         */
    9287} __attribute__((packed)) td_t;
  • uspace/drv/uhci-hcd/main.c

    r34e8bab rb77ce84  
    3939#include <usb/debug.h>
    4040
     41#include "iface.h"
    4142#include "uhci.h"
    4243
     
    6162int uhci_add_device(ddf_dev_t *device)
    6263{
    63         usb_log_debug2("uhci_add_device() called\n");
     64        usb_log_debug("uhci_add_device() called\n");
    6465        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(%d) to initialize UHCI driver: %s.\n",
    75                     ret, str_error(ret));
     74                usb_log_error("Failed to initialize UHCI driver: %s.\n",
     75                    str_error(ret));
    7676                return ret;
    7777        }
     
    8585/** Initialize global driver structures (NONE).
    8686 *
    87  * @param[in] argc Number of arguments in argv vector (ignored).
     87 * @param[in] argc Nmber 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 */
    9698        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    9799
  • uspace/drv/uhci-hcd/pci.c

    r34e8bab rb77ce84  
    4444#include "pci.h"
    4545
    46 /** Get I/O address of registers and IRQ for given device.
     46/** Get 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, int *irq_no)
     55    uintptr_t *io_reg_address, size_t *io_reg_size,
     56    int *irq_no)
    5657{
    5758        assert(dev != NULL);
    5859
    59         int parent_phone =
    60             devman_parent_device_connect(dev->handle, IPC_FLAG_BLOCKING);
     60        int parent_phone = devman_parent_device_connect(dev->handle,
     61            IPC_FLAG_BLOCKING);
    6162        if (parent_phone < 0) {
    6263                return parent_phone;
    6364        }
    6465
     66        int rc;
    6567        hw_resource_list_t hw_resources;
    66         int rc = hw_res_get_resource_list(parent_phone, &hw_resources);
     68        rc = hw_res_get_resource_list(parent_phone, &hw_resources);
    6769        if (rc != EOK) {
    6870                goto leave;
     
    9395                            res->res.io_range.address, res->res.io_range.size);
    9496                        io_found = true;
    95                         break;
    9697
    9798                default:
     
    112113leave:
    113114        async_hangup(parent_phone);
     115
    114116        return rc;
    115117}
     
    143145        }
    144146
    145         /* See UHCI design guide for these values p.45,
     147        /* See UHCI design guide for these values,
    146148         * write all WC bits in USB legacy register */
    147149        sysarg_t address = 0xc0;
  • uspace/drv/uhci-hcd/root_hub.c

    r34e8bab rb77ce84  
    5555        int ret = asprintf(&match_str, "usb&uhci&root-hub");
    5656        if (ret < 0) {
    57                 usb_log_error(
    58                     "Failed(%d) to create root hub match string: %s.\n",
    59                     ret, str_error(ret));
    60                 return ret;
     57                usb_log_error("Failed to create root hub match string.\n");
     58                return ENOMEM;
    6159        }
    6260
    6361        ret = ddf_fun_add_match_id(fun, match_str, 100);
    6462        if (ret != EOK) {
    65                 free(match_str);
    6663                usb_log_error("Failed(%d) to add root hub match id: %s\n",
    6764                    ret, str_error(ret));
     
    6966        }
    7067
    71         /* Initialize resource structure */
    72         instance->resource_list.count = 1;
    73         instance->resource_list.resources = &instance->io_regs;
    74 
     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);
    7572        instance->io_regs.type = IO_RANGE;
    7673        instance->io_regs.res.io_range.address = reg_addr;
  • uspace/drv/uhci-hcd/root_hub.h

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

    r34e8bab rb77ce84  
    5757                return ENOMEM;
    5858        }
    59         uint32_t queue_head_pa = addr_to_phys(instance->queue_head);
     59        instance->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, queue_head_pa);
     61            name, instance->queue_head, instance->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  */
    75 void transfer_list_fini(transfer_list_t *instance)
    76 {
    77         assert(instance);
    78         free32(instance->queue_head);
    79 }
    8069/** Set the next list in transfer list chain.
    8170 *
     
    9281        if (!instance->queue_head)
    9382                return;
    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.
     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.
    9988 *
    10089 * @param[in] instance List to use.
    10190 * @param[in] batch Transfer batch to submit.
     91 * @return Error code
    10292 *
    10393 * The batch is added to the end of the list and queue.
     
    119109        } else {
    120110                /* There is something scheduled */
    121                 usb_transfer_batch_t *last =
    122                     usb_transfer_batch_from_link(instance->batch_list.prev);
     111                usb_transfer_batch_t *last = list_get_instance(
     112                    instance->batch_list.prev, usb_transfer_batch_t, link);
    123113                last_qh = batch_qh(last);
    124114        }
     
    128118        /* keep link */
    129119        batch_qh(batch)->next = last_qh->next;
    130         qh_set_next_qh(last_qh, batch_qh(batch));
     120        qh_set_next_qh(last_qh, pa);
    131121
    132122        asm volatile ("": : :"memory");
     
    142132}
    143133/*----------------------------------------------------------------------------*/
    144 /** Add completed bantches to the provided list.
     134/** Create list for finished batches.
    145135 *
    146136 * @param[in] instance List to use.
     
    157147                link_t *next = current->next;
    158148                usb_transfer_batch_t *batch =
    159                     usb_transfer_batch_from_link(current);
     149                    list_get_instance(current, usb_transfer_batch_t, link);
    160150
    161151                if (batch_is_complete(batch)) {
    162                         /* Save for processing */
     152                        /* Save for post-processing */
    163153                        transfer_list_remove_batch(instance, batch);
    164154                        list_append(current, done);
     
    169159}
    170160/*----------------------------------------------------------------------------*/
    171 /** Walk the list and finish all batches with EINTR.
     161/** Walk the list and abort all batches.
    172162 *
    173163 * @param[in] instance List to use.
     
    179169                link_t *current = instance->batch_list.next;
    180170                usb_transfer_batch_t *batch =
    181                     usb_transfer_batch_from_link(current);
     171                    list_get_instance(current, usb_transfer_batch_t, link);
    182172                transfer_list_remove_batch(instance, batch);
    183                 usb_transfer_batch_finish_error(batch, EINTR);
     173                usb_transfer_batch_finish_error(batch, EIO);
    184174        }
    185175        fibril_mutex_unlock(&instance->guard);
     
    190180 * @param[in] instance List to use.
    191181 * @param[in] batch Transfer batch to remove.
     182 * @return Error code
    192183 *
    193184 * Does not lock the transfer list, caller is responsible for that.
     
    206197
    207198        const char *qpos = NULL;
    208         qh_t *prev_qh = NULL;
    209199        /* Remove from the hardware queue */
    210200        if (instance->batch_list.next == &batch->link) {
    211201                /* I'm the first one here */
    212                 prev_qh = instance->queue_head;
     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;
    213205                qpos = "FIRST";
    214206        } else {
    215                 /* The thing before me is a batch too */
    216207                usb_transfer_batch_t *prev =
    217                     usb_transfer_batch_from_link(batch->link.prev);
    218                 prev_qh = batch_qh(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;
    219213                qpos = "NOT FIRST";
    220214        }
    221         assert((prev_qh->next & LINK_POINTER_ADDRESS_MASK)
    222             == addr_to_phys(batch_qh(batch)));
    223         prev_qh->next = batch_qh(batch)->next;
    224215        asm volatile ("": : :"memory");
    225216        /* Remove from the batch list */
    226217        list_remove(&batch->link);
    227         usb_log_debug("Batch(%p) removed (%s) from %s, next: %x.\n",
     218        usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n",
    228219            batch, qpos, instance->name, batch_qh(batch)->next);
    229220}
  • uspace/drv/uhci-hcd/transfer_list.h

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

    r34e8bab rb77ce84  
    4444#include "pci.h"
    4545
    46 /** IRQ handling callback, forward status from call to diver structure.
     46/** IRQ handling callback, identifies device
    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 from kernel.
     50 * @param[in] call Pointer to the call that represents interrupt.
    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] 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.
     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.
    6666 */
    6767static int usb_iface_get_address(
     
    6969{
    7070        assert(fun);
    71         usb_device_keeper_t *manager =
    72             &((uhci_t*)fun->dev->driver_data)->hc.manager;
     71        usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc.manager;
    7372
    7473        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    8483}
    8584/*----------------------------------------------------------------------------*/
    86 /** Gets handle of the respective hc.
    87  *
    88  * @param[in] fun DDF function of uhci device.
    89  * @param[out] handle Host cotnroller handle.
     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.
    9089 * @return Error code.
    9190 */
     
    101100}
    102101/*----------------------------------------------------------------------------*/
    103 /** USB interface implementation used by RH */
     102/** This iface is generic for both RH and HC. */
    104103static usb_iface_t usb_iface = {
    105104        .get_hc_handle = usb_iface_get_hc_handle,
     
    107106};
    108107/*----------------------------------------------------------------------------*/
    109 /** Operations supported by the HC driver */
    110108static ddf_dev_ops_t hc_ops = {
     109//      .interfaces[USB_DEV_IFACE] = &usb_iface,
    111110        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    112111};
     
    123122}
    124123/*----------------------------------------------------------------------------*/
    125 /** Interface to provide the root hub driver with hw info */
    126124static hw_res_ops_t hw_res_iface = {
    127125        .get_resource_list = get_resource_list,
     
    129127};
    130128/*----------------------------------------------------------------------------*/
    131 /** RH function support for uhci-rhd */
    132129static ddf_dev_ops_t rh_ops = {
    133130        .interfaces[USB_DEV_IFACE] = &usb_iface,
     
    135132};
    136133/*----------------------------------------------------------------------------*/
    137 /** Initialize hc and rh DDF structures and their respective drivers.
     134/** Initialize hc and rh ddf structures and their respective drivers.
    138135 *
    139136 * @param[in] instance UHCI structure to use.
     
    141138 *
    142139 * This function does all the preparatory work for hc and rh drivers:
    143  *  - gets device's hw resources
    144  *  - disables UHCI legacy support (PCI config space)
     140 *  - gets device hw resources
     141 *  - disables UHCI legacy support
    145142 *  - asks for interrupt
    146143 *  - registers interrupt handler
     
    196193        ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
    197194        CHECK_RET_DEST_FUN_RETURN(ret,
    198             "Failed(%d) to create HC function: %s.\n", ret, str_error(ret));
     195            "Failed(%d) to create HC function.\n", ret);
    199196
    200197        ret = hc_init(&instance->hc, instance->hc_fun,
    201198            (void*)io_reg_base, io_reg_size, interrupts);
    202         CHECK_RET_DEST_FUN_RETURN(ret,
    203             "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret));
    204 
     199        CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret);
    205200        instance->hc_fun->ops = &hc_ops;
    206201        instance->hc_fun->driver_data = &instance->hc;
     
    226221            &instance->hc.interrupt_code);
    227222        CHECK_RET_FINI_RETURN(ret,
    228             "Failed(%d) to register interrupt handler: %s.\n",
    229             ret, str_error(ret));
     223            "Failed(%d) to register interrupt handler.\n", ret);
    230224
    231225        instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
    232226        ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    233227        CHECK_RET_FINI_RETURN(ret,
    234             "Failed(%d) to create root hub function: %s.\n",
    235             ret, str_error(ret));
     228            "Failed(%d) to create root hub function.\n", ret);
    236229
    237230        ret = rh_init(&instance->rh, instance->rh_fun,
    238231            (uintptr_t)instance->hc.registers + 0x10, 4);
    239232        CHECK_RET_FINI_RETURN(ret,
    240             "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
     233            "Failed(%d) to setup UHCI root hub.\n", ret);
    241234
    242235        instance->rh_fun->ops = &rh_ops;
     
    244237        ret = ddf_fun_bind(instance->rh_fun);
    245238        CHECK_RET_FINI_RETURN(ret,
    246             "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
     239            "Failed(%d) to register UHCI root hub.\n", ret);
    247240
    248241        return EOK;
  • uspace/drv/uhci-hcd/uhci.h

    r34e8bab rb77ce84  
    4141#include "root_hub.h"
    4242
    43 /** Structure representing both functions of UHCI hc, USB host controller
    44  * and USB root hub */
    4543typedef struct uhci {
    46         /** Pointer to DDF represenation of UHCI host controller */
    4744        ddf_fun_t *hc_fun;
    48         /** Pointer to DDF represenation of UHCI root hub */
    4945        ddf_fun_t *rh_fun;
    5046
    51         /** Internal driver's represenation of UHCI host controller */
    5247        hc_t hc;
    53         /** Internal driver's represenation of UHCI root hub */
    5448        rh_t rh;
    5549} uhci_t;
    5650
    5751int uhci_init(uhci_t *instance, ddf_dev_t *device);
     52
    5853#endif
    5954/**
  • uspace/lib/usb/src/host/usb_endpoint_manager.c

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