Changeset a81a1d09 in mainline for uspace/drv/ohci/hc.c


Ignore:
Timestamp:
2011-05-11T16:49:28Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
19387b61
Parents:
e1dbcbc (diff), 9212f8a (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 development/ changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/hc.c

    re1dbcbc ra81a1d09  
    4040#include <usb/usb.h>
    4141#include <usb/ddfiface.h>
    42 #include <usb/usbdevice.h>
    4342
    4443#include "hc.h"
    4544#include "hcd_endpoint.h"
    4645
     46#define OHCI_USED_INTERRUPTS \
     47    (I_SO | I_WDH | I_UE | I_RHSC)
    4748static int interrupt_emulator(hc_t *instance);
    4849static void hc_gain_control(hc_t *instance);
    49 static void hc_init_hw(hc_t *instance);
    5050static int hc_init_transfer_lists(hc_t *instance);
    5151static int hc_init_memory(hc_t *instance);
     
    9090                usb_log_error("Failed add root hub match-id.\n");
    9191        }
     92        ret = ddf_fun_bind(hub_fun);
    9293        return ret;
    9394}
    9495/*----------------------------------------------------------------------------*/
    95 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
    96     uintptr_t regs, size_t reg_size, bool interrupts)
     96int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts)
    9797{
    9898        assert(instance);
     
    109109            ret, str_error(ret));
    110110
     111        list_initialize(&instance->pending_batches);
    111112        usb_device_keeper_init(&instance->manager);
    112113        ret = usb_endpoint_manager_init(&instance->ep_manager,
     
    115116            str_error(ret));
    116117
    117         hc_gain_control(instance);
    118118        ret = hc_init_memory(instance);
    119119        CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n",
    120120            str_error(ret));
    121         hc_init_hw(instance);
     121#undef CHECK_RET_RETURN
     122
     123
     124//      hc_init_hw(instance);
     125        hc_gain_control(instance);
    122126        fibril_mutex_initialize(&instance->guard);
    123127
     
    130134        }
    131135
    132         list_initialize(&instance->pending_batches);
    133 #undef CHECK_RET_RETURN
    134136        return EOK;
    135137}
     
    285287{
    286288        assert(instance);
    287         if ((status & ~IS_SF) == 0) /* ignore sof status */
     289        usb_log_debug("OHCI(%p) interrupt: %x.\n", instance, 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,
     
    332334{
    333335        assert(instance);
     336        usb_log_debug("Requesting OHCI control.\n");
    334337        /* Turn off legacy emulation */
    335338        volatile uint32_t *ohci_emulation_reg =
    336339            (uint32_t*)((char*)instance->registers + 0x100);
    337340        usb_log_debug("OHCI legacy register %p: %x.\n",
    338                 ohci_emulation_reg, *ohci_emulation_reg);
    339         *ohci_emulation_reg = 0;
     341            ohci_emulation_reg, *ohci_emulation_reg);
     342        /* Do not change A20 state */
     343        *ohci_emulation_reg &= 0x100;
     344        usb_log_debug("OHCI legacy register %p: %x.\n",
     345            ohci_emulation_reg, *ohci_emulation_reg);
    340346
    341347        /* Interrupt routing enabled => smm driver is active */
     
    347353                }
    348354                usb_log_info("SMM driver: Ownership taken.\n");
     355                instance->registers->control &= (C_HCFS_RESET << C_HCFS_SHIFT);
     356                async_usleep(50000);
    349357                return;
    350358        }
     
    372380}
    373381/*----------------------------------------------------------------------------*/
    374 void hc_init_hw(hc_t *instance)
     382void hc_start_hw(hc_t *instance)
    375383{
    376384        /* OHCI guide page 42 */
     
    421429            instance->registers->control);
    422430
    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;
     431        /* Enable interrupts */
     432        instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;
    428433        usb_log_debug2("Enabled interrupts: %x.\n",
    429434            instance->registers->interrupt_enable);
     435        instance->registers->interrupt_enable = I_MI;
    430436
    431437        /* Set periodic start to 90% */
     
    473479{
    474480        assert(instance);
     481
     482        bzero(&instance->rh, sizeof(instance->rh));
    475483        /* Init queues */
    476484        hc_init_transfer_lists(instance);
     
    492500            instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
    493501
     502        /* Init interrupt code */
     503        instance->interrupt_code.cmds = instance->interrupt_commands;
     504        {
     505                /* Read status register */
     506                instance->interrupt_commands[0].cmd = CMD_MEM_READ_32;
     507                instance->interrupt_commands[0].dstarg = 1;
     508                instance->interrupt_commands[0].addr =
     509                    (void*)&instance->registers->interrupt_status;
     510
     511                /* Test whether we are the interrupt cause */
     512                instance->interrupt_commands[1].cmd = CMD_BTEST;
     513                instance->interrupt_commands[1].value =
     514                    OHCI_USED_INTERRUPTS;
     515                instance->interrupt_commands[1].srcarg = 1;
     516                instance->interrupt_commands[1].dstarg = 2;
     517
     518                /* Predicate cleaning and accepting */
     519                instance->interrupt_commands[2].cmd = CMD_PREDICATE;
     520                instance->interrupt_commands[2].value = 2;
     521                instance->interrupt_commands[2].srcarg = 2;
     522
     523                /* Write clean status register */
     524                instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32;
     525                instance->interrupt_commands[3].srcarg = 1;
     526                instance->interrupt_commands[3].addr =
     527                    (void*)&instance->registers->interrupt_status;
     528
     529                /* Accept interrupt */
     530                instance->interrupt_commands[4].cmd = CMD_ACCEPT;
     531
     532                instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
     533        }
     534
    494535        return EOK;
    495536}
Note: See TracChangeset for help on using the changeset viewer.