Changeset b4b534ac in mainline for uspace/drv/bus/usb/uhci


Ignore:
Timestamp:
2016-07-22T08:24:47Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f76d2c2
Parents:
5b18137 (diff), 8351f9a4 (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:

Merge from lp:~jan.vesely/helenos/usb

Location:
uspace/drv/bus/usb/uhci
Files:
1 added
3 deleted
12 edited
1 moved

Legend:

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

    r5b18137 rb4b534ac  
    3131LIBS = \
    3232        $(LIBUSBHOST_PREFIX)/libusbhost.a \
     33        $(LIBUSBVIRT_PREFIX)/libusbvirt.a \
    3334        $(LIBUSB_PREFIX)/libusb.a \
    3435        $(LIBDRV_PREFIX)/libdrv.a
     
    3637EXTRA_CFLAGS += \
    3738        -I$(LIBUSB_PREFIX)/include \
     39        -I$(LIBUSBDEV_PREFIX)/include \
    3840        -I$(LIBUSBHOST_PREFIX)/include \
     41        -I$(LIBUSBVIRT_PREFIX)/include \
    3942        -I$(LIBDRV_PREFIX)/include
    4043
     
    4447        hc.c \
    4548        main.c \
    46         res.c \
    47         root_hub.c \
    4849        transfer_list.c \
    49         uhci.c \
    5050        uhci_batch.c \
     51        uhci_rh.c \
    5152        hw_struct/transfer_descriptor.c
    5253
  • uspace/drv/bus/usb/uhci/hc.c

    r5b18137 rb4b534ac  
    3232 * @brief UHCI Host controller driver routines
    3333 */
     34
     35#include <adt/list.h>
     36#include <assert.h>
     37#include <async.h>
     38#include <ddi.h>
     39#include <device/hw_res_parsed.h>
     40#include <fibril.h>
    3441#include <errno.h>
     42#include <macros.h>
     43#include <mem.h>
     44#include <stdlib.h>
    3545#include <str_error.h>
    36 #include <adt/list.h>
    37 #include <ddi.h>
     46#include <sys/types.h>
    3847
    3948#include <usb/debug.h>
    4049#include <usb/usb.h>
    41 
     50#include <usb/host/utils/malloc32.h>
     51
     52#include "uhci_batch.h"
    4253#include "hc.h"
    43 #include "uhci_batch.h"
    4454
    4555#define UHCI_INTR_ALLOW_INTERRUPTS \
     
    8595static int hc_init_mem_structures(hc_t *instance);
    8696static int hc_init_transfer_lists(hc_t *instance);
    87 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    88 
    89 static int hc_interrupt_emulator(void *arg);
     97
    9098static int hc_debug_checker(void *arg);
    9199
    92 enum {
    93         /** Number of PIO ranges used in IRQ code */
    94         hc_irq_pio_range_count =
    95             sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t),
    96 
    97         /* Number of commands used in IRQ code */
    98         hc_irq_cmd_count =
    99             sizeof(uhci_irq_commands) / sizeof(irq_cmd_t)
    100 };
    101100
    102101/** Generate IRQ code.
    103  * @param[out] ranges PIO ranges buffer.
    104  * @param[in] ranges_size Size of the ranges buffer (bytes).
    105  * @param[out] cmds Commands buffer.
    106  * @param[in] cmds_size Size of the commands buffer (bytes).
    107  * @param[in] regs Device's register range.
     102 * @param[out] code IRQ code structure.
     103 * @param[in] hw_res Device's resources.
    108104 *
    109105 * @return Error code.
    110106 */
    111 int
    112 hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
    113     size_t cmds_size, addr_range_t *regs)
    114 {
    115         if ((ranges_size < sizeof(uhci_irq_pio_ranges)) ||
    116             (cmds_size < sizeof(uhci_irq_commands)) ||
    117             (RNGSZ(*regs) < sizeof(uhci_regs_t)))
     107int uhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
     108{
     109        assert(code);
     110        assert(hw_res);
     111
     112        if (hw_res->irqs.count != 1 || hw_res->io_ranges.count != 1)
     113                return EINVAL;
     114        const addr_range_t regs = hw_res->io_ranges.ranges[0];
     115
     116        if (RNGSZ(regs) < sizeof(uhci_regs_t))
    118117                return EOVERFLOW;
    119118
    120         memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
    121         ranges[0].base = RNGABS(*regs);
    122 
    123         memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
    124         uhci_regs_t *registers = (uhci_regs_t *) RNGABSPTR(*regs);
    125         cmds[0].addr = (void *) &registers->usbsts;
    126         cmds[3].addr = (void *) &registers->usbsts;
    127 
    128         return EOK;
    129 }
    130 
    131 /** Register interrupt handler.
    132  *
    133  * @param[in] device Host controller DDF device
    134  * @param[in] regs Register range
    135  * @param[in] irq Interrupt number
    136  * @paran[in] handler Interrupt handler
    137  *
    138  * @return EOK on success or negative error code
    139  */
    140 int hc_register_irq_handler(ddf_dev_t *device, addr_range_t *regs, int irq,
    141     interrupt_handler_t handler)
    142 {
    143         int rc;
    144         irq_pio_range_t irq_ranges[hc_irq_pio_range_count];
    145         irq_cmd_t irq_cmds[hc_irq_cmd_count];
    146         rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
    147             sizeof(irq_cmds), regs);
    148         if (rc != EOK) {
    149                 usb_log_error("Failed to generate IRQ commands: %s.\n",
    150                     str_error(rc));
    151                 return rc;
    152         }
    153        
    154         irq_code_t irq_code = {
    155                 .rangecount = hc_irq_pio_range_count,
    156                 .ranges = irq_ranges,
    157                 .cmdcount = hc_irq_cmd_count,
    158                 .cmds = irq_cmds
    159         };
    160        
    161         /* Register handler to avoid interrupt lockup */
    162         rc = register_interrupt_handler(device, irq, handler, &irq_code);
    163         if (rc != EOK) {
    164                 usb_log_error("Failed to register interrupt handler: %s.\n",
    165                     str_error(rc));
    166                 return rc;
    167         }
    168        
    169         return EOK;
     119        code->ranges = malloc(sizeof(uhci_irq_pio_ranges));
     120        if (code->ranges == NULL)
     121                return ENOMEM;
     122
     123        code->cmds = malloc(sizeof(uhci_irq_commands));
     124        if (code->cmds == NULL) {
     125                free(code->ranges);
     126                return ENOMEM;
     127        }
     128
     129        code->rangecount = ARRAY_SIZE(uhci_irq_pio_ranges);
     130        code->cmdcount = ARRAY_SIZE(uhci_irq_commands);
     131
     132        memcpy(code->ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
     133        code->ranges[0].base = RNGABS(regs);
     134
     135        memcpy(code->cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
     136        uhci_regs_t *registers = (uhci_regs_t *) RNGABSPTR(regs);
     137        code->cmds[0].addr = (void*)&registers->usbsts;
     138        code->cmds[3].addr = (void*)&registers->usbsts;
     139
     140        usb_log_debug("I/O regs at %p (size %zu), IRQ %d.\n",
     141            RNGABSPTR(regs), RNGSZ(regs), hw_res->irqs.irqs[0]);
     142
     143        return hw_res->irqs.irqs[0];
    170144}
    171145
    172146/** Take action based on the interrupt cause.
    173147 *
    174  * @param[in] instance UHCI structure to use.
     148 * @param[in] hcd HCD structure to use.
    175149 * @param[in] status Value of the status register at the time of interrupt.
    176150 *
     
    180154 * - resume from suspend state (not implemented)
    181155 */
    182 void hc_interrupt(hc_t *instance, uint16_t status)
    183 {
     156void uhci_hc_interrupt(hcd_t *hcd, uint32_t status)
     157{
     158        assert(hcd);
     159        hc_t *instance = hcd_get_driver_data(hcd);
    184160        assert(instance);
    185161        /* Lower 2 bits are transaction error and transaction complete */
     
    195171                    &instance->transfers_bulk_full, &done);
    196172
    197                 while (!list_empty(&done)) {
    198                         link_t *item = list_first(&done);
    199                         list_remove(item);
     173                list_foreach_safe(done, current, next) {
     174                        list_remove(current);
    200175                        uhci_transfer_batch_t *batch =
    201                             uhci_transfer_batch_from_link(item);
     176                            uhci_transfer_batch_from_link(current);
    202177                        uhci_transfer_batch_finish_dispose(batch);
    203178                }
     
    230205 *
    231206 * @param[in] instance Memory place to initialize.
    232  * @param[in] HC function node
    233207 * @param[in] regs Range of device's I/O control registers.
    234208 * @param[in] interrupts True if hw interrupts should be used.
     
    239213 * interrupt fibrils.
    240214 */
    241 int hc_init(hc_t *instance, ddf_fun_t *fun, addr_range_t *regs, bool interrupts)
    242 {
    243         assert(regs->size >= sizeof(uhci_regs_t));
    244         int rc;
     215int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
     216{
     217        assert(instance);
     218        assert(hw_res);
     219        if (hw_res->io_ranges.count != 1 ||
     220            hw_res->io_ranges.ranges[0].size < sizeof(uhci_regs_t))
     221            return EINVAL;
    245222
    246223        instance->hw_interrupts = interrupts;
     
    248225
    249226        /* allow access to hc control registers */
    250         uhci_regs_t *io;
    251         rc = pio_enable_range(regs, (void **) &io);
    252         if (rc != EOK) {
    253                 usb_log_error("Failed to gain access to registers at %p: %s.\n",
    254                     io, str_error(rc));
    255                 return rc;
    256         }
    257 
    258         instance->registers = io;
    259         usb_log_debug(
    260             "Device registers at %p (%zuB) accessible.\n", io, regs->size);
    261 
    262         rc = hc_init_mem_structures(instance);
    263         if (rc != EOK) {
    264                 usb_log_error("Failed to initialize UHCI memory structures: %s.\n",
    265                     str_error(rc));
    266                 return rc;
    267         }
    268 
    269         instance->generic = ddf_fun_data_alloc(fun, sizeof(hcd_t));
    270         if (instance->generic == NULL) {
    271                 usb_log_error("Out of memory.\n");
    272                 return ENOMEM;
    273         }
    274 
    275         hcd_init(instance->generic, USB_SPEED_FULL,
    276             BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    277 
    278         instance->generic->private_data = instance;
    279         instance->generic->schedule = hc_schedule;
    280         instance->generic->ep_add_hook = NULL;
     227        int ret = pio_enable_range(&hw_res->io_ranges.ranges[0],
     228            (void **) &instance->registers);
     229        if (ret != EOK) {
     230                usb_log_error("Failed to gain access to registers: %s.\n",
     231                    str_error(ret));
     232                return ret;
     233        }
     234
     235        usb_log_debug("Device registers at %" PRIx64 " (%zuB) accessible.\n",
     236            hw_res->io_ranges.ranges[0].address.absolute,
     237            hw_res->io_ranges.ranges[0].size);
     238
     239        ret = hc_init_mem_structures(instance);
     240        if (ret != EOK) {
     241                usb_log_error("Failed to init UHCI memory structures: %s.\n",
     242                    str_error(ret));
     243                // TODO: we should disable pio here
     244                return ret;
     245        }
    281246
    282247        hc_init_hw(instance);
    283         if (!interrupts) {
    284                 instance->interrupt_emulator =
    285                     fibril_create(hc_interrupt_emulator, instance);
    286                 fibril_add_ready(instance->interrupt_emulator);
    287         }
    288248        (void)hc_debug_checker;
    289249
     250        uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
     251
    290252        return EOK;
     253}
     254
     255/** Safely dispose host controller internal structures
     256 *
     257 * @param[in] instance Host controller structure to use.
     258 */
     259void hc_fini(hc_t *instance)
     260{
     261        assert(instance);
     262        //TODO Implement
    291263}
    292264
     
    432404        instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] =
    433405          &instance->transfers_bulk_full;
    434         instance->transfers[USB_SPEED_LOW][USB_TRANSFER_BULK] =
    435           &instance->transfers_bulk_full;
    436 
     406
     407        return EOK;
     408}
     409
     410int uhci_hc_status(hcd_t *hcd, uint32_t *status)
     411{
     412        assert(hcd);
     413        assert(status);
     414        hc_t *instance = hcd_get_driver_data(hcd);
     415        assert(instance);
     416
     417        *status = 0;
     418        if (instance->registers) {
     419                uint16_t s = pio_read_16(&instance->registers->usbsts);
     420                pio_write_16(&instance->registers->usbsts, s);
     421                *status = s;
     422        }
    437423        return EOK;
    438424}
     
    446432 * Checks for bandwidth availability and appends the batch to the proper queue.
    447433 */
    448 int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
     434int uhci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    449435{
    450436        assert(hcd);
    451         hc_t *instance = hcd->private_data;
     437        hc_t *instance = hcd_get_driver_data(hcd);
    452438        assert(instance);
    453439        assert(batch);
     440
     441        if (batch->ep->address == uhci_rh_get_address(&instance->rh))
     442                return uhci_rh_schedule(&instance->rh, batch);
     443
    454444        uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch);
    455445        if (!uhci_batch) {
     
    463453        transfer_list_add_batch(list, uhci_batch);
    464454
    465         return EOK;
    466 }
    467 
    468 /** Polling function, emulates interrupts.
    469  *
    470  * @param[in] arg UHCI hc structure to use.
    471  * @return EOK (should never return)
    472  */
    473 int hc_interrupt_emulator(void* arg)
    474 {
    475         usb_log_debug("Started interrupt emulator.\n");
    476         hc_t *instance = arg;
    477         assert(instance);
    478 
    479         while (1) {
    480                 /* Read and clear status register */
    481                 uint16_t status = pio_read_16(&instance->registers->usbsts);
    482                 pio_write_16(&instance->registers->usbsts, status);
    483                 if (status != 0)
    484                         usb_log_debug2("UHCI status: %x.\n", status);
    485                 hc_interrupt(instance, status);
    486                 async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
    487         }
    488455        return EOK;
    489456}
  • uspace/drv/bus/usb/uhci/hc.h

    r5b18137 rb4b534ac  
    3636#define DRV_UHCI_HC_H
    3737
    38 #include <ddf/driver.h>
    39 #include <ddf/interrupt.h>
    4038#include <device/hw_res_parsed.h>
    4139#include <fibril.h>
     40#include <macros.h>
     41#include <stdbool.h>
     42#include <sys/types.h>
    4243#include <usb/host/hcd.h>
     44#include <usb/host/usb_transfer_batch.h>
    4345
     46#include "uhci_rh.h"
    4447#include "transfer_list.h"
     48#include "hw_struct/link_pointer.h"
    4549
    4650/** UHCI I/O registers layout */
     
    8387        /** SOF modification to match external timers */
    8488        ioport8_t sofmod;
     89
     90        PADD8[3];
     91        ioport16_t ports[];
    8592} uhci_regs_t;
    8693
    8794#define UHCI_FRAME_LIST_COUNT 1024
    88 #define UHCI_INT_EMULATOR_TIMEOUT 10000
    8995#define UHCI_DEBUGER_TIMEOUT 5000000
    9096#define UHCI_ALLOWED_HW_FAIL 5
    91 #define UHCI_NEEDED_IRQ_COMMANDS 5
    9297
    9398/** Main UHCI driver structure */
    9499typedef struct hc {
    95         /** Generic HCD driver structure */
    96         hcd_t *generic;
    97 
     100        uhci_rh_t rh;
    98101        /** Addresses of I/O registers */
    99102        uhci_regs_t *registers;
     
    113116        /** Pointer table to the above lists, helps during scheduling */
    114117        transfer_list_t *transfers[2][4];
    115         /** Fibril periodically checking status register*/
    116         fid_t interrupt_emulator;
    117118        /** Indicator of hw interrupts availability */
    118119        bool hw_interrupts;
     
    122123} hc_t;
    123124
    124 int hc_register_irq_handler(ddf_dev_t *, addr_range_t *, int,
    125     interrupt_handler_t);
    126 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t,
    127     addr_range_t *);
    128 void hc_interrupt(hc_t *instance, uint16_t status);
    129 int hc_init(hc_t *, ddf_fun_t *, addr_range_t *, bool);
     125int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interupts);
     126void hc_fini(hc_t *instance);
    130127
    131 /** Safely dispose host controller internal structures
    132  *
    133  * @param[in] instance Host controller structure to use.
    134  */
    135 static inline void hc_fini(hc_t *instance) {} /* TODO: implement*/
     128int uhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res);
     129
     130void uhci_hc_interrupt(hcd_t *hcd, uint32_t status);
     131int uhci_hc_status(hcd_t *hcd, uint32_t *status);
     132int uhci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
     133
    136134#endif
    137135
  • uspace/drv/bus/usb/uhci/hw_struct/link_pointer.h

    r5b18137 rb4b534ac  
    3535#define DRV_UHCI_HW_STRUCT_LINK_POINTER_H
    3636
     37#include <sys/types.h>
     38
    3739/** UHCI link pointer, used by many data structures */
    3840typedef uint32_t link_pointer_t;
  • uspace/drv/bus/usb/uhci/hw_struct/queue_head.h

    r5b18137 rb4b534ac  
    3434#ifndef DRV_UHCI_HW_STRUCT_QH_H
    3535#define DRV_UHCI_HW_STRUCT_QH_H
     36
    3637#include <assert.h>
     38#include <sys/types.h>
     39#include <usb/host/utils/malloc32.h>
    3740
    3841#include "link_pointer.h"
    3942#include "transfer_descriptor.h"
    40 #include "../utils/malloc32.h"
    4143
    4244/** This structure is defined in UHCI design guide p. 31 */
  • uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.c

    r5b18137 rb4b534ac  
    3232 * @brief UHCI driver
    3333 */
     34
     35#include <assert.h>
    3436#include <errno.h>
     37
    3538#include <usb/debug.h>
     39#include <usb/usb.h>
     40#include <usb/host/utils/malloc32.h>
    3641
     42#include "link_pointer.h"
    3743#include "transfer_descriptor.h"
    38 #include "../utils/malloc32.h"
    3944
    4045/** Initialize Transfer Descriptor
  • uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.h

    r5b18137 rb4b534ac  
    3535#define DRV_UHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H
    3636
    37 #include <mem.h>
     37#include <assert.h>
    3838#include <usb/usb.h>
     39#include <stdbool.h>
     40#include <sys/types.h>
    3941
    4042#include "link_pointer.h"
  • uspace/drv/bus/usb/uhci/main.c

    r5b18137 rb4b534ac  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbuhcihc
     28/** @addtogroup drvusbuhci
    2929 * @{
    3030 */
     
    3232 * @brief UHCI driver initialization
    3333 */
     34
     35#include <assert.h>
    3436#include <ddf/driver.h>
     37#include <devman.h>
    3538#include <errno.h>
     39#include <io/log.h>
     40#include <io/logctl.h>
     41#include <pci_dev_iface.h>
     42#include <stdio.h>
    3643#include <str_error.h>
     44#include <usb/debug.h>
     45#include <usb/host/ddf_helpers.h>
    3746
    38 #include <usb/ddfiface.h>
    39 #include <usb/debug.h>
    40 
    41 #include "uhci.h"
     47#include "hc.h"
    4248
    4349#define NAME "uhci"
    4450
    45 static int uhci_dev_add(ddf_dev_t *device);
     51static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
     52static void uhci_driver_fini(hcd_t *);
     53static int disable_legacy(ddf_dev_t *);
    4654
    47 static driver_ops_t uhci_driver_ops = {
    48         .dev_add = uhci_dev_add,
     55static const ddf_hc_driver_t uhci_hc_driver = {
     56        .claim = disable_legacy,
     57        .hc_speed = USB_SPEED_FULL,
     58        .irq_code_gen = uhci_hc_gen_irq_code,
     59        .init = uhci_driver_init,
     60        .fini = uhci_driver_fini,
     61        .name = "UHCI",
     62        .ops = {
     63                .schedule    = uhci_hc_schedule,
     64                .irq_hook    = uhci_hc_interrupt,
     65                .status_hook = uhci_hc_status,
     66        },
    4967};
    5068
    51 static driver_t uhci_driver = {
    52         .name = NAME,
    53         .driver_ops = &uhci_driver_ops
    54 };
     69static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
     70{
     71        assert(hcd);
     72        assert(hcd_get_driver_data(hcd) == NULL);
     73
     74        hc_t *instance = malloc(sizeof(hc_t));
     75        if (!instance)
     76                return ENOMEM;
     77
     78        const int ret = hc_init(instance, res, irq);
     79        if (ret == EOK) {
     80                hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops);
     81        } else {
     82                free(instance);
     83        }
     84        return ret;
     85}
     86
     87static void uhci_driver_fini(hcd_t *hcd)
     88{
     89        assert(hcd);
     90        hc_t *hc = hcd_get_driver_data(hcd);
     91        if (hc)
     92                hc_fini(hc);
     93
     94        hcd_set_implementation(hcd, NULL, NULL);
     95        free(hc);
     96}
     97
     98/** Call the PCI driver with a request to clear legacy support register
     99 *
     100 * @param[in] device Device asking to disable interrupts
     101 * @return Error code.
     102 */
     103static int disable_legacy(ddf_dev_t *device)
     104{
     105        assert(device);
     106
     107        async_sess_t *parent_sess = devman_parent_device_connect(
     108            ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
     109        if (!parent_sess)
     110                return ENOMEM;
     111
     112        /* See UHCI design guide page 45 for these values.
     113         * Write all WC bits in USB legacy register */
     114        const int rc = pci_config_space_write_16(parent_sess, 0xc0, 0xaf00);
     115
     116        async_hangup(parent_sess);
     117        return rc;
     118}
    55119
    56120/** Initialize a new ddf driver instance for uhci hc and hub.
     
    59123 * @return Error code.
    60124 */
    61 int uhci_dev_add(ddf_dev_t *device)
     125static int uhci_dev_add(ddf_dev_t *device)
    62126{
    63127        usb_log_debug2("uhci_dev_add() called\n");
    64128        assert(device);
     129        return hcd_ddf_add_hc(device, &uhci_hc_driver);
     130}
    65131
    66         const int ret = device_setup_uhci(device);
    67         if (ret != EOK) {
    68                 usb_log_error("Failed to initialize UHCI driver: %s.\n",
    69                     str_error(ret));
    70         } else {
    71                 usb_log_info("Controlling new UHCI device '%s'.\n",
    72                     ddf_dev_get_name(device));
    73         }
     132static const driver_ops_t uhci_driver_ops = {
     133        .dev_add = uhci_dev_add,
     134};
    74135
    75         return ret;
    76 }
     136static const driver_t uhci_driver = {
     137        .name = NAME,
     138        .driver_ops = &uhci_driver_ops
     139};
     140
    77141
    78142/** Initialize global driver structures (NONE).
     
    88152        printf(NAME ": HelenOS UHCI driver.\n");
    89153        log_init(NAME);
    90 
     154        logctl_set_log_level(NAME, LVL_NOTE);
    91155        return ddf_driver_main(&uhci_driver);
    92156}
  • uspace/drv/bus/usb/uhci/transfer_list.c

    r5b18137 rb4b534ac  
    3434 */
    3535
     36#include <assert.h>
    3637#include <errno.h>
     38#include <libarch/barrier.h>
     39#include <sys/types.h>
    3740#include <usb/debug.h>
    38 #include <libarch/barrier.h>
    39 
     41#include <usb/host/usb_transfer_batch.h>
     42#include <usb/host/utils/malloc32.h>
     43
     44#include "hw_struct/link_pointer.h"
    4045#include "transfer_list.h"
    4146
  • uspace/drv/bus/usb/uhci/transfer_list.h

    r5b18137 rb4b534ac  
    3535#define DRV_UHCI_TRANSFER_LIST_H
    3636
     37#include <adt/list.h>
    3738#include <fibril_synch.h>
    3839
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r5b18137 rb4b534ac  
    3232 * @brief UHCI driver USB transfer structure
    3333 */
     34
     35#include <assert.h>
    3436#include <errno.h>
    35 #include <str_error.h>
    3637#include <macros.h>
     38#include <mem.h>
     39#include <stdlib.h>
    3740
    3841#include <usb/usb.h>
    3942#include <usb/debug.h>
     43#include <usb/host/endpoint.h>
     44#include <usb/host/utils/malloc32.h>
    4045
    4146#include "uhci_batch.h"
    42 #include "transfer_list.h"
    4347#include "hw_struct/transfer_descriptor.h"
    44 #include "utils/malloc32.h"
    4548
    4649#define DEFAULT_ERROR_COUNT 3
     
    6770        assert(uhci_batch);
    6871        assert(uhci_batch->usb_batch);
     72        assert(!link_in_use(&uhci_batch->link));
    6973        usb_transfer_batch_finish(uhci_batch->usb_batch,
    7074            uhci_transfer_batch_data_buffer(uhci_batch));
  • uspace/drv/bus/usb/uhci/uhci_batch.h

    r5b18137 rb4b534ac  
    3535#define DRV_UHCI_BATCH_H
    3636
     37#include <adt/list.h>
     38#include <assert.h>
     39#include <errno.h>
     40#include <stdbool.h>
     41#include <sys/types.h>
    3742#include <usb/host/usb_transfer_batch.h>
    38 #include <adt/list.h>
    3943
    4044#include "hw_struct/queue_head.h"
  • uspace/drv/bus/usb/uhci/uhci_rh.h

    r5b18137 rb4b534ac  
    11/*
    2  * Copyright (c) 2011 Jan Vesely
     2 * Copyright (c) 2013 Jan Vesely
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
    33  * @brief UHCI driver
     33 * @brief UHCI host controller driver structure
    3434 */
    35 #ifndef DRV_UHCI_RH_H
    36 #define DRV_UHCI_RH_H
     35#ifndef DRV_UHCI_UHCI_RH_H
     36#define DRV_UHCI_UHCI_RH_H
    3737
    38 #include <ddf/driver.h>
    39 #include <ops/hw_res.h>
    40 #include <ops/pio_window.h>
     38#include <usbvirt/virthub_base.h>
     39#include <usb/host/usb_transfer_batch.h>
     40#include <usb/usb.h>
    4141
    42 /** DDF support structure for uhci_rhd driver, provides I/O resources */
    43 typedef struct rh {
    44         /** List of resources available to the root hub. */
    45         hw_resource_list_t resource_list;
    46         /** The only resource in the RH resource list */
    47         hw_resource_t io_regs;
    48         /** PIO window in which the RH will operate. */
    49         pio_window_t pio_window;       
    50 } rh_t;
     42#include <stdbool.h>
     43#include <sys/types.h>
    5144
    52 extern int rh_init(rh_t *, ddf_fun_t *, addr_range_t *, uintptr_t, size_t);
     45/** Endpoint number for status change pipe. */
     46#define HUB_STATUS_CHANGE_PIPE   1
     47
     48/** Virtual to UHCI hub connector */
     49typedef struct {
     50        /** Virtual hub software implementation */
     51        virthub_base_t base;
     52        /** UHCI root hub port io registers */
     53        ioport16_t *ports[2];
     54        /** Reset change indicator, it is not reported by regs */
     55        bool reset_changed[2];
     56} uhci_rh_t;
     57
     58int uhci_rh_init(uhci_rh_t *instance, ioport16_t *ports, const char *name);
     59int uhci_rh_schedule(uhci_rh_t *instance, usb_transfer_batch_t *batch);
     60
     61/** Get UHCI rh address.
     62 *
     63 * @param instance UHCI rh instance.
     64 * @return USB address assigned to the hub.
     65 * Wrapper for virtual hub address
     66 */
     67static inline usb_address_t uhci_rh_get_address(uhci_rh_t *instance)
     68{
     69        return virthub_base_get_address(&instance->base);
     70}
    5371
    5472#endif
Note: See TracChangeset for help on using the changeset viewer.