Ignore:
File:
1 edited

Legend:

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

    rb9d910f r83c439c  
    3939
    4040#include "uhci.h"
    41 static irq_cmd_t uhci_cmds[] = {
    42         {
    43                 .cmd = CMD_PIO_READ_16,
    44                 .addr = (void*)0xc022,
    45                 .dstarg = 1
    46         },
    47         {
    48                 .cmd = CMD_PIO_WRITE_16,
    49                 .addr = (void*)0xc022,
    50                 .value = 0x1f
    51         },
    52         {
    53                 .cmd = CMD_ACCEPT
    54         }
    55 };
    5641
    5742static int uhci_init_transfer_lists(uhci_t *instance);
    58 static int uhci_init_mem_structures(uhci_t *instance);
    59 static void uhci_init_hw(uhci_t *instance);
    60 
    61 static int uhci_interrupt_emulator(void *arg);
     43static int uhci_clean_finished(void *arg);
    6244static int uhci_debug_checker(void *arg);
    63 
    6445static bool allowed_usb_packet(
    6546        bool low_speed, usb_transfer_type_t, size_t size);
    6647
    67 #define CHECK_RET_RETURN(ret, message...) \
     48int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     49{
     50#define CHECK_RET_RETURN(message...) \
    6851        if (ret != EOK) { \
    6952                usb_log_error(message); \
     
    7154        } else (void) 0
    7255
    73 int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
    74 {
    75         assert(reg_size >= sizeof(regs_t));
     56        /* init address keeper(libusb) */
     57        usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
     58        usb_log_debug("Initialized address manager.\n");
    7659
    7760        /* allow access to hc control registers */
    7861        regs_t *io;
     62        assert(reg_size >= sizeof(regs_t));
    7963        int ret = pio_enable(regs, reg_size, (void**)&io);
    80         CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io);
     64        CHECK_RET_RETURN("Failed to gain access to registers at %p.\n", io);
    8165        instance->registers = io;
    8266        usb_log_debug("Device registers accessible.\n");
    8367
    84         ret = uhci_init_mem_structures(instance);
    85         CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n");
    86 
    87         uhci_init_hw(instance);
    88 
    89         instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
    90 //      fibril_add_ready(instance->cleaner);
    91 
    92         instance->debug_checker = fibril_create(uhci_debug_checker, instance);
    93         fibril_add_ready(instance->debug_checker);
    94 
    95         return EOK;
    96 }
    97 /*----------------------------------------------------------------------------*/
    98 void uhci_init_hw(uhci_t *instance)
    99 {
    100 
    101         /* set framelist pointer */
    102         const uint32_t pa = addr_to_phys(instance->frame_list);
    103         pio_write_32(&instance->registers->flbaseadd, pa);
    104 
    105         /* enable all interrupts, but resume interrupt */
    106         pio_write_16(&instance->registers->usbintr,
    107                   UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
    108 
    109         /* Start the hc with large(64B) packet FSBR */
    110         pio_write_16(&instance->registers->usbcmd,
    111             UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
    112         usb_log_debug("Started UHCI HC.\n");
    113 }
    114 /*----------------------------------------------------------------------------*/
    115 int uhci_init_mem_structures(uhci_t *instance)
    116 {
    117         assert(instance);
    118 
    119         /* init interrupt code */
    120         irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds));
    121         if (interrupt_commands == NULL) {
    122                 return ENOMEM;
    123         }
    124         memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
    125         interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
    126         interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
    127         instance->interrupt_code.cmds = interrupt_commands;
    128         instance->interrupt_code.cmdcount =
    129             sizeof(uhci_cmds) / sizeof(irq_cmd_t);
    130 
    13168        /* init transfer lists */
    132         int ret = uhci_init_transfer_lists(instance);
    133         CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
    134         usb_log_debug("Initialized transfer lists.\n");
    135 
    136         /* frame list initialization */
     69        ret = uhci_init_transfer_lists(instance);
     70        CHECK_RET_RETURN("Failed to initialize transfer lists.\n");
     71        usb_log_debug("Transfer lists initialized.\n");
     72
     73
     74        usb_log_debug("Initializing frame list.\n");
    13775        instance->frame_list = get_page();
    13876        ret = instance ? EOK : ENOMEM;
    139         CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
    140         usb_log_debug("Initialized frame list.\n");
     77        CHECK_RET_RETURN("Failed to get frame list page.\n");
    14178
    14279        /* initialize all frames to point to the first queue head */
     
    14986        }
    15087
    151         /* init address keeper(libusb) */
    152         usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
    153         usb_log_debug("Initialized address manager.\n");
     88        const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
     89        pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
     90
     91        list_initialize(&instance->batch_list);
     92        fibril_mutex_initialize(&instance->batch_list_mutex);
     93
     94        instance->cleaner = fibril_create(uhci_clean_finished, instance);
     95        fibril_add_ready(instance->cleaner);
     96
     97        instance->debug_checker = fibril_create(uhci_debug_checker, instance);
     98        fibril_add_ready(instance->debug_checker);
     99
     100        /* Start the hc with large(64B) packet FSBR */
     101        pio_write_16(&instance->registers->usbcmd,
     102            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
     103        usb_log_debug("Started UHCI HC.\n");
     104
     105        uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
     106        cmd |= UHCI_CMD_DEBUG;
     107        pio_write_16(&instance->registers->usbcmd, cmd);
    154108
    155109        return EOK;
     
    160114        assert(instance);
    161115
    162         /* initialize TODO: check errors */
     116        /* initialize */
    163117        int ret;
    164118        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
     
    192146        instance->transfers[1][USB_TRANSFER_CONTROL] =
    193147          &instance->transfers_control_slow;
    194         instance->transfers[0][USB_TRANSFER_BULK] =
    195           &instance->transfers_bulk_full;
     148        instance->transfers[0][USB_TRANSFER_CONTROL] =
     149          &instance->transfers_control_full;
    196150
    197151        return EOK;
     
    220174}
    221175/*----------------------------------------------------------------------------*/
    222 void uhci_interrupt(uhci_t *instance, uint16_t status)
    223 {
    224         assert(instance);
    225         if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
    226                 return;
    227         usb_log_debug("UHCI interrupt: %X.\n", status);
    228         transfer_list_check(&instance->transfers_interrupt);
    229         transfer_list_check(&instance->transfers_control_slow);
    230         transfer_list_check(&instance->transfers_control_full);
    231         transfer_list_check(&instance->transfers_bulk_full);
    232 }
    233 /*----------------------------------------------------------------------------*/
    234 int uhci_interrupt_emulator(void* arg)
    235 {
    236         usb_log_debug("Started interrupt emulator.\n");
     176int uhci_clean_finished(void* arg)
     177{
     178        usb_log_debug("Started cleaning fibril.\n");
    237179        uhci_t *instance = (uhci_t*)arg;
    238180        assert(instance);
    239181
    240182        while(1) {
    241                 uint16_t status = pio_read_16(&instance->registers->usbsts);
    242                 uhci_interrupt(instance, status);
     183                transfer_list_check(&instance->transfers_interrupt);
     184                transfer_list_check(&instance->transfers_control_slow);
     185                transfer_list_check(&instance->transfers_control_full);
     186                transfer_list_check(&instance->transfers_bulk_full);
    243187                async_usleep(UHCI_CLEANER_TIMEOUT);
    244188        }
     
    251195        assert(instance);
    252196        while (1) {
    253                 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    254                 const uint16_t sts = pio_read_16(&instance->registers->usbsts);
    255                 const uint16_t intr = pio_read_16(&instance->registers->usbintr);
    256                 usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
    257                     cmd, sts, intr);
     197                uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
     198                uint16_t sts = pio_read_16(&instance->registers->usbsts);
     199                usb_log_debug("Command register: %X Status register: %X\n", cmd, sts);
    258200
    259201                uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
    260                 if (frame_list != addr_to_phys(instance->frame_list)) {
     202                if (frame_list != (uintptr_t)addr_to_phys(instance->frame_list)) {
    261203                        usb_log_debug("Framelist address: %p vs. %p.\n",
    262204                                frame_list, addr_to_phys(instance->frame_list));
Note: See TracChangeset for help on using the changeset viewer.