Changeset 561112f in mainline


Ignore:
Timestamp:
2011-05-06T08:37:19Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
180255f
Parents:
f7ccf46
Message:

OHCI interrupt support

Location:
uspace/drv
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ehci-hcd/pci.c

    rf7ccf46 r561112f  
    186186        CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read PCI config space.\n",
    187187            ret);
    188         usb_log_info("Register space BAR at %p:%" PRIxn ".\n", (void *) address, value);
     188        usb_log_info("Register space BAR at %p:%" PRIxn ".\n",
     189            (void *) address, value);
    189190
    190191        /* clear lower byte, it's not part of the BASE address */
  • uspace/drv/ohci/hc.c

    rf7ccf46 r561112f  
    4545#include "hcd_endpoint.h"
    4646
     47#define OHCI_USED_INTERRUPTS \
     48    (I_SO | I_WDH | I_UE | I_RHSC)
    4749static int interrupt_emulator(hc_t *instance);
    4850static void hc_gain_control(hc_t *instance);
     
    285287{
    286288        assert(instance);
    287         if ((status & ~IS_SF) == 0) /* ignore sof status */
     289        usb_log_debug("OHCI interrupt: %x.\n", status);
     290        if ((status & ~I_SF) == 0) /* ignore sof status */
    288291                return;
    289         if (status & IS_RHSC)
     292        if (status & I_RHSC)
    290293                rh_interrupt(&instance->rh);
    291294
    292         usb_log_debug("OHCI interrupt: %x.\n", status);
    293 
    294         if (status & IS_WDH) {
     295
     296        if (status & I_WDH) {
    295297                fibril_mutex_lock(&instance->guard);
    296298                usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,
     
    421423            instance->registers->control);
    422424
    423         /* Disable interrupts */
    424         instance->registers->interrupt_disable = I_SF | I_OC;
    425         usb_log_debug2("Disabling interrupts: %x.\n",
    426             instance->registers->interrupt_disable);
    427         instance->registers->interrupt_disable = I_MI;
     425        /* Enable interrupts */
     426        instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;
    428427        usb_log_debug2("Enabled interrupts: %x.\n",
    429428            instance->registers->interrupt_enable);
     429        instance->registers->interrupt_enable = I_MI;
     430        /* Disable interrupts */
     431//      instance->registers->interrupt_disable = I_SF | I_OC;
     432//      usb_log_debug2("Disabling interrupts: %x.\n",
     433//          instance->registers->interrupt_disable);
     434//      instance->registers->interrupt_disable = I_MI;
    430435
    431436        /* Set periodic start to 90% */
     
    492497            instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
    493498
     499        /* Init interrupt code */
     500        instance->interrupt_code.cmds = instance->interrupt_commands;
     501        {
     502                /* Read status register */
     503                instance->interrupt_commands[0].cmd = CMD_MEM_READ_32;
     504                instance->interrupt_commands[0].dstarg = 1;
     505                instance->interrupt_commands[0].addr = (void*)
     506                    addr_to_phys((void*)&instance->registers->interrupt_status);
     507
     508                /* Test whether we are the interrupt cause */
     509                instance->interrupt_commands[1].cmd = CMD_BTEST;
     510                instance->interrupt_commands[1].value =
     511                    OHCI_USED_INTERRUPTS;
     512                instance->interrupt_commands[1].srcarg = 1;
     513                instance->interrupt_commands[1].dstarg = 2;
     514
     515                /* Predicate cleaning and accepting */
     516                instance->interrupt_commands[2].cmd = CMD_PREDICATE;
     517                instance->interrupt_commands[2].value = 2;
     518                instance->interrupt_commands[2].srcarg = 2;
     519
     520                /* Write clean status register */
     521                instance->interrupt_commands[3].cmd = CMD_PIO_WRITE_A_32;
     522                instance->interrupt_commands[3].srcarg = 1;
     523                instance->interrupt_commands[3].addr = (void*)
     524                    addr_to_phys((void*)&instance->registers->interrupt_status);
     525
     526                /* Accept interrupt */
     527                instance->interrupt_commands[4].cmd = CMD_ACCEPT;
     528
     529                instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
     530        }
     531
    494532        return EOK;
    495533}
  • uspace/drv/ohci/hc.h

    rf7ccf46 r561112f  
    5151#include "hw_struct/hcca.h"
    5252
     53#define OHCI_NEEDED_IRQ_COMMANDS 5
     54
    5355typedef struct hc {
    5456        ohci_regs_t *registers;
     
    6567        fid_t interrupt_emulator;
    6668        fibril_mutex_t guard;
     69
     70        /** Code to be executed in kernel interrupt handler */
     71        irq_code_t interrupt_code;
     72
     73        /** Commands that form interrupt code */
     74        irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS];
    6775} hc_t;
    6876
  • uspace/drv/ohci/ohci.c

    rf7ccf46 r561112f  
    202202
    203203        /* It does no harm if we register this on polling */
    204         ret = register_interrupt_handler(device, irq, irq_handler, NULL);
     204        ret = register_interrupt_handler(device, irq, irq_handler,
     205            &instance->hc.interrupt_code);
    205206        CHECK_RET_FINI_RETURN(ret,
    206207            "Failed(%d) to register interrupt handler.\n", ret);
  • uspace/drv/ohci/ohci_regs.h

    rf7ccf46 r561112f  
    7272#define CS_SOC_SHIFT (16)
    7373
     74        /** Interupt enable/disable/status,
     75         * reads give the same value,
     76         * writing causes enable/disable,
     77         * status is write-clean (writing 1 clears the bit*/
    7478        volatile uint32_t interrupt_status;
    75 #define IS_SO   (1 << 0)  /* Scheduling overrun */
    76 #define IS_WDH  (1 << 1)  /* Write-back done head */
    77 #define IS_SF   (1 << 2)  /* Start of frame */
    78 #define IS_RD   (1 << 3)  /* Resume detected */
    79 #define IS_UE   (1 << 4)  /* Unrecoverable error */
    80 #define IS_FNO  (1 << 5)  /* Frame number overflow */
    81 #define IS_RHSC (1 << 6)  /* Root hub status change */
    82 #define IS_OC   (1 << 30) /* Ownership change */
    83 
    84         /** Interupt enable/disable, reads give the same value, writing causes
    85          * enable/disable */
    8679        volatile uint32_t interrupt_enable;
    8780        volatile uint32_t interrupt_disable;
  • uspace/drv/ohci/pci.c

    rf7ccf46 r561112f  
    146146int pci_enable_interrupts(ddf_dev_t *device)
    147147{
    148         return ENOTSUP;
    149148        int parent_phone =
    150149            devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
Note: See TracChangeset for help on using the changeset viewer.