Changes in / [374552ef:6edc69a] in mainline


Ignore:
Location:
uspace/drv/uhci-hcd
Files:
1 deleted
6 edited

Legend:

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

    r374552ef r6edc69a  
    141141        usb_log_debug("Checking(%p) %d packet for completion.\n",
    142142            instance, instance->packets);
    143         /* This is just an ugly trick to support the old API */
    144143        instance->transfered_size = 0;
    145144        size_t i = 0;
     
    157156                    transfer_descriptor_actual_size(&instance->tds[i]);
    158157        }
     158        /* This is just an ugly trick to support the old API */
    159159        instance->transfered_size -= instance->setup_size;
    160160        return true;
     
    191191            0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
    192192
     193        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     194
    193195        instance->next_step = batch_call_out_and_dispose;
    194196        batch_schedule(instance);
     
    221223        transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    222224            0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
     225
     226        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    223227
    224228        instance->next_step = batch_call_in_and_dispose;
     
    244248        }
    245249
     250        instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     251
    246252        instance->next_step = batch_call_in_and_dispose;
    247253        batch_schedule(instance);
     
    268274        }
    269275
     276        instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     277
    270278        instance->next_step = batch_call_out_and_dispose;
    271279        batch_schedule(instance);
  • uspace/drv/uhci-hcd/main.c

    r374552ef r6edc69a  
    3434#include <driver.h>
    3535#include <usb_iface.h>
     36#include <ipc/irc.h>
     37#include <ipc/ns.h>
     38#include <ipc/services.h>
     39#include <sysinfo.h>
    3640
    3741#include <errno.h>
     
    4650#define NAME "uhci-hcd"
    4751
     52static int uhci_add_device(device_t *device);
     53static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle);
     54/*----------------------------------------------------------------------------*/
    4855static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
    4956{
     
    5461        return EOK;
    5562}
    56 
     63/*----------------------------------------------------------------------------*/
    5764static usb_iface_t hc_usb_iface = {
    5865        .get_hc_handle = usb_iface_get_hc_handle
    5966};
    60 
     67/*----------------------------------------------------------------------------*/
    6168static device_ops_t uhci_ops = {
    6269        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    6370        .interfaces[USBHC_DEV_IFACE] = &uhci_iface
    6471};
    65 
     72/*----------------------------------------------------------------------------*/
     73static driver_ops_t uhci_driver_ops = {
     74        .add_device = uhci_add_device,
     75};
     76/*----------------------------------------------------------------------------*/
     77static driver_t uhci_driver = {
     78        .name = NAME,
     79        .driver_ops = &uhci_driver_ops
     80};
     81/*----------------------------------------------------------------------------*/
     82static irq_cmd_t uhci_cmds[] = {
     83        {
     84                .cmd = CMD_PIO_READ_16,
     85                .addr = (void*)0xc022,
     86                .dstarg = 1
     87        },
     88        {
     89                .cmd = CMD_PIO_WRITE_16,
     90                .addr = (void*)0xc022,
     91                .value = 0x1f
     92        },
     93        {
     94                .cmd = CMD_ACCEPT
     95        }
     96};
     97/*----------------------------------------------------------------------------*/
     98static irq_code_t uhci_code = {
     99        sizeof(uhci_cmds) / sizeof(irq_cmd_t),
     100        uhci_cmds
     101};
     102/*----------------------------------------------------------------------------*/
     103static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
     104{
     105        assert(device);
     106        uhci_t *hc = dev_to_uhci(device);
     107        usb_log_info("LOL HARDWARE INTERRUPT: %p.\n", hc);
     108        uint16_t status = IPC_GET_ARG1(*call);
     109        assert(hc);
     110        uhci_interrupt(hc, status);
     111}
     112/*----------------------------------------------------------------------------*/
    66113static int uhci_add_device(device_t *device)
    67114{
     
    75122        int irq;
    76123
    77         int rc = pci_get_my_registers(device,
    78             &io_reg_base, &io_reg_size, &irq);
    79 
    80         if (rc != EOK) {
    81                 usb_log_error("Failed(%d) to get I/O registers addresses for device:.\n",
    82                     rc, device->handle);
    83                 return rc;
     124        int ret =
     125            pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
     126
     127        if (ret != EOK) {
     128                usb_log_error(
     129                    "Failed(%d) to get I/O registers addresses for device:.\n",
     130                    ret, device->handle);
     131                return ret;
    84132        }
    85133
     
    87135            io_reg_base, io_reg_size, irq);
    88136
     137
     138  sysarg_t apic;
     139  sysarg_t i8259;
     140        int irc_phone = -1;
     141        int irc_service = 0;
     142
     143  if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
     144    irc_service = SERVICE_APIC;
     145                usb_log_debug("SERVICE_APIC\n");
     146        } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
     147    irc_service = SERVICE_I8259;
     148                usb_log_debug("SERVICE_I8259\n");
     149        }
     150
     151  if (irc_service) {
     152    while (irc_phone < 0)
     153      irc_phone = service_connect_blocking(irc_service, 0, 0);
     154  }
     155        usb_log_debug("Interrupt conttroller phone: %d\n", irc_phone);
     156
     157        async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     158        async_hangup(irc_phone);
     159
     160        ret = register_interrupt_handler(device, irq, irq_handler, &uhci_code);
     161        usb_log_debug("Registered interrupt handler %d.\n", ret);
     162
    89163        uhci_t *uhci_hc = malloc(sizeof(uhci_t));
    90164        if (!uhci_hc) {
    91                 usb_log_error("Failed to allocaete memory for uhci hcd driver.\n");
     165                usb_log_error("Failed to allocate memory for uhci hcd driver.\n");
    92166                return ENOMEM;
    93167        }
    94168
    95         int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
     169        ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
    96170        if (ret != EOK) {
    97171                usb_log_error("Failed to init uhci-hcd.\n");
     
    100174        device_t *rh;
    101175        ret = setup_root_hub(&rh, device);
    102 
    103176        if (ret != EOK) {
    104177                usb_log_error("Failed to setup uhci root hub.\n");
     
    118191        return EOK;
    119192}
    120 
    121 static driver_ops_t uhci_driver_ops = {
    122         .add_device = uhci_add_device,
    123 };
    124 
    125 static driver_t uhci_driver = {
    126         .name = NAME,
    127         .driver_ops = &uhci_driver_ops
    128 };
    129 
     193/*----------------------------------------------------------------------------*/
    130194int main(int argc, char *argv[])
    131195{
    132         /*
    133          * Do some global initializations.
    134          */
    135         sleep(5);
    136         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     196        sleep(3);
     197        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    137198
    138199        return driver_main(&uhci_driver);
  • uspace/drv/uhci-hcd/transfer_list.c

    r374552ef r6edc69a  
    111111        /* I'm the first one here */
    112112        if (batch->link.prev == &instance->batch_list) {
    113                 usb_log_debug("Removing tracer %p was first, next element %x.\n",
     113                usb_log_debug("Removing batch %p was first, next element %x.\n",
    114114                        batch, batch->qh->next_queue);
    115115                instance->queue_head->element = batch->qh->next_queue;
    116116        } else {
    117                 usb_log_debug("Removing tracer %p was NOT first, next element %x.\n",
     117                usb_log_debug("Removing batch %p was NOT first, next element %x.\n",
    118118                        batch, batch->qh->next_queue);
    119119                batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
  • uspace/drv/uhci-hcd/uhci-hcd.ma

    r374552ef r6edc69a  
    1110 pci/ven=8086&dev=7020
    2 
     210 pci/ven=8086&dev=7112
  • uspace/drv/uhci-hcd/uhci.c

    r374552ef r6edc69a  
    4141
    4242static int uhci_init_transfer_lists(uhci_t *instance);
    43 static int uhci_clean_finished(void *arg);
     43static int uhci_init_mem_structures(uhci_t *instance);
     44static void uhci_init_hw(uhci_t *instance);
     45
     46static int uhci_interrupt_emulator(void *arg);
    4447static int uhci_debug_checker(void *arg);
     48
    4549static bool allowed_usb_packet(
    4650        bool low_speed, usb_transfer_type_t, size_t size);
    4751
    48 int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
    49 {
    50 #define CHECK_RET_RETURN(message...) \
     52#define CHECK_RET_RETURN(ret, message...) \
    5153        if (ret != EOK) { \
    5254                usb_log_error(message); \
     
    5456        } else (void) 0
    5557
    56         /* init address keeper(libusb) */
    57         usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
    58         usb_log_debug("Initialized address manager.\n");
     58int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     59{
     60        assert(reg_size >= sizeof(regs_t));
    5961
    6062        /* allow access to hc control registers */
    6163        regs_t *io;
    62         assert(reg_size >= sizeof(regs_t));
    6364        int ret = pio_enable(regs, reg_size, (void**)&io);
    64         CHECK_RET_RETURN("Failed to gain access to registers at %p.\n", io);
     65        CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io);
    6566        instance->registers = io;
    6667        usb_log_debug("Device registers accessible.\n");
    6768
     69        ret = uhci_init_mem_structures(instance);
     70        CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n");
     71
     72        uhci_init_hw(instance);
     73
     74        instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
     75//      fibril_add_ready(instance->cleaner);
     76
     77        instance->debug_checker = fibril_create(uhci_debug_checker, instance);
     78        fibril_add_ready(instance->debug_checker);
     79
     80        return EOK;
     81}
     82/*----------------------------------------------------------------------------*/
     83void uhci_init_hw(uhci_t *instance)
     84{
     85
     86        /* set framelist pointer */
     87        const uint32_t pa = addr_to_phys(instance->frame_list);
     88        pio_write_32(&instance->registers->flbaseadd, pa);
     89
     90        /* enable all interrupts, but resume interrupt */
     91        pio_write_16(&instance->registers->usbintr,
     92                  UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     93
     94        /* Start the hc with large(64B) packet FSBR */
     95        pio_write_16(&instance->registers->usbcmd,
     96            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
     97        usb_log_debug("Started UHCI HC.\n");
     98}
     99/*----------------------------------------------------------------------------*/
     100int uhci_init_mem_structures(uhci_t *instance)
     101{
     102        assert(instance);
    68103        /* init transfer lists */
    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");
     104        int ret = uhci_init_transfer_lists(instance);
     105        CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
     106        usb_log_debug("Initialized transfer lists.\n");
     107
     108        /* frame list initialization */
    75109        instance->frame_list = get_page();
    76110        ret = instance ? EOK : ENOMEM;
    77         CHECK_RET_RETURN("Failed to get frame list page.\n");
     111        CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
     112        usb_log_debug("Initialized frame list.\n");
    78113
    79114        /* initialize all frames to point to the first queue head */
     
    86121        }
    87122
    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);
     123        /* init address keeper(libusb) */
     124        usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
     125        usb_log_debug("Initialized address manager.\n");
    108126
    109127        return EOK;
     
    114132        assert(instance);
    115133
    116         /* initialize */
     134        /* initialize TODO: check errors */
    117135        int ret;
    118136        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
     
    146164        instance->transfers[1][USB_TRANSFER_CONTROL] =
    147165          &instance->transfers_control_slow;
    148         instance->transfers[0][USB_TRANSFER_CONTROL] =
    149           &instance->transfers_control_full;
     166        instance->transfers[0][USB_TRANSFER_BULK] =
     167          &instance->transfers_bulk_full;
    150168
    151169        return EOK;
     
    174192}
    175193/*----------------------------------------------------------------------------*/
    176 int uhci_clean_finished(void* arg)
    177 {
    178         usb_log_debug("Started cleaning fibril.\n");
     194void uhci_interrupt(uhci_t *instance, uint16_t status)
     195{
     196        assert(instance);
     197        if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
     198                return;
     199        usb_log_debug("UHCI interrupt: %X.\n", status);
     200        transfer_list_check(&instance->transfers_interrupt);
     201        transfer_list_check(&instance->transfers_control_slow);
     202        transfer_list_check(&instance->transfers_control_full);
     203        transfer_list_check(&instance->transfers_bulk_full);
     204}
     205/*----------------------------------------------------------------------------*/
     206int uhci_interrupt_emulator(void* arg)
     207{
     208        usb_log_debug("Started interrupt emulator.\n");
    179209        uhci_t *instance = (uhci_t*)arg;
    180210        assert(instance);
    181211
    182212        while(1) {
    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);
     213                uint16_t status = pio_read_16(&instance->registers->usbsts);
     214                uhci_interrupt(instance, status);
    187215                async_usleep(UHCI_CLEANER_TIMEOUT);
    188216        }
     
    195223        assert(instance);
    196224        while (1) {
    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);
     225                const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
     226                const uint16_t sts = pio_read_16(&instance->registers->usbsts);
     227                const uint16_t intr = pio_read_16(&instance->registers->usbintr);
     228                usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
     229                    cmd, sts, intr);
    200230
    201231                uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
    202                 if (frame_list != (uintptr_t)addr_to_phys(instance->frame_list)) {
     232                if (frame_list != addr_to_phys(instance->frame_list)) {
    203233                        usb_log_debug("Framelist address: %p vs. %p.\n",
    204234                                frame_list, addr_to_phys(instance->frame_list));
  • uspace/drv/uhci-hcd/uhci.h

    r374552ef r6edc69a  
    6666
    6767        uint16_t usbintr;
     68#define UHCI_INTR_SHORT_PACKET (1 << 3)
     69#define UHCI_INTR_COMPLETE (1 << 2)
     70#define UHCI_INTR_RESUME (1 << 1)
     71#define UHCI_INTR_CRC (1 << 0)
     72
    6873        uint16_t frnum;
    6974        uint32_t flbaseadd;
     
    8085
    8186        link_pointer_t *frame_list;
    82 
    83         link_t batch_list;
    84         fibril_mutex_t batch_list_mutex;
    8587
    8688        transfer_list_t transfers_bulk_full;
     
    115117int uhci_schedule(uhci_t *instance, batch_t *batch);
    116118
     119void uhci_interrupt(uhci_t *instance, uint16_t status);
     120
    117121static inline uhci_t * dev_to_uhci(device_t *dev)
    118122        { return (uhci_t*)dev->driver_data; }
Note: See TracChangeset for help on using the changeset viewer.