Changeset a8fa88d in mainline


Ignore:
Timestamp:
2011-04-02T18:57:54Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b8f7a0d2
Parents:
d8987b1 (diff), c2be0e5 (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:

OHCI bandwidth and basic initialization

Location:
uspace
Files:
7 edited

Legend:

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

    rd8987b1 ra8fa88d  
    4545
    4646static int interrupt_emulator(hc_t *instance);
     47static void hc_gain_control(hc_t *instance);
     48static void hc_init_hw(hc_t *instance);
    4749/*----------------------------------------------------------------------------*/
    4850int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
     
    7779        assert(instance);
    7880        int ret = EOK;
     81#define CHECK_RET_RETURN(ret, message...) \
     82if (ret != EOK) { \
     83        usb_log_error(message); \
     84        return ret; \
     85} else (void)0
    7986
    8087        ret = pio_enable((void*)regs, reg_size, (void**)&instance->registers);
    81         if (ret != EOK) {
    82                 usb_log_error("Failed to gain access to device registers.\n");
    83                 return ret;
    84         }
     88        CHECK_RET_RETURN(ret,
     89            "Failed(%d) to gain access to device registers: %s.\n",
     90            ret, str_error(ret));
     91
    8592        instance->ddf_instance = fun;
    8693        usb_device_keeper_init(&instance->manager);
     94        ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,
     95            bandwidth_count_usb11);
     96        CHECK_RET_RETURN(ret, "Failed to initialize bandwidth allocator: %s.\n",
     97            ret, str_error(ret));
    8798
    8899        if (!interrupts) {
     
    92103        }
    93104
     105        hc_gain_control(instance);
     106
    94107        rh_init(&instance->rh, dev, instance->registers);
     108
     109        hc_init_hw(instance);
    95110
    96111        /* TODO: implement */
     
    117132                rh_interrupt(&instance->rh);
    118133
     134        usb_log_info("OHCI interrupt: %x.\n", status);
     135
    119136        /* TODO: Check for further interrupt causes */
    120137        /* TODO: implement */
     
    126143        usb_log_info("Started interrupt emulator.\n");
    127144        while (1) {
    128                 uint32_t status = instance->registers->interrupt_status;
     145                const uint32_t status = instance->registers->interrupt_status;
    129146                instance->registers->interrupt_status = status;
    130147                hc_interrupt(instance, status);
     
    133150        return EOK;
    134151}
     152/*----------------------------------------------------------------------------*/
     153void hc_gain_control(hc_t *instance)
     154{
     155        assert(instance);
     156        /* Interrupt routing enabled => smm driver is active */
     157        if (instance->registers->control & C_IR) {
     158                usb_log_info("Found SMM driver requesting ownership change.\n");
     159                instance->registers->command_status |= CS_OCR;
     160                while (instance->registers->control & C_IR) {
     161                        async_usleep(1000);
     162                }
     163                usb_log_info("Ownership taken from SMM driver.\n");
     164                return;
     165        }
     166
     167        const unsigned hc_status =
     168            (instance->registers->control >> C_HCFS_SHIFT) & C_HCFS_MASK;
     169        /* Interrupt routing disabled && status != USB_RESET => BIOS active */
     170        if (hc_status != C_HCFS_RESET) {
     171                usb_log_info("Found BIOS driver.\n");
     172                if (hc_status == C_HCFS_OPERATIONAL) {
     173                        usb_log_info("HC operational(BIOS).\n");
     174                        return;
     175                }
     176                /* HC is suspended assert resume for 20ms */
     177                instance->registers->control &= (C_HCFS_RESUME << C_HCFS_SHIFT);
     178                async_usleep(20000);
     179                return;
     180        }
     181
     182        /* HC is in reset (hw startup) => no other driver
     183         * maintain reset for at least the time specified in USB spec (50 ms)*/
     184        async_usleep(50000);
     185}
     186/*----------------------------------------------------------------------------*/
     187void hc_init_hw(hc_t *instance)
     188{
     189        assert(instance);
     190        const uint32_t fm_interval = instance->registers->fm_interval;
     191        instance->registers->command_status = CS_HCR;
     192        async_usleep(10);
     193        instance->registers->fm_interval = fm_interval;
     194        assert((instance->registers->command_status & CS_HCR) == 0);
     195        /* hc is now in suspend state */
     196        /* TODO: init HCCA block */
     197        /* TODO: init queues */
     198        /* TODO: enable queues */
     199        /* TODO: enable interrupts */
     200        /* TODO: set periodic start to 90% */
     201
     202        instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT);
     203        usb_log_info("OHCI HC up and running.\n");
     204}
    135205/**
    136206 * @}
  • uspace/drv/ohci/hc.h

    rd8987b1 ra8fa88d  
    4242#include <usb/usb.h>
    4343#include <usb/host/device_keeper.h>
     44#include <usb/host/bandwidth.h>
    4445#include <usbhc_iface.h>
    4546
     
    5455        ddf_fun_t *ddf_instance;
    5556        usb_device_keeper_t manager;
     57        bandwidth_t bandwidth;
    5658        fid_t interrupt_emulator;
    5759} hc_t;
  • uspace/drv/ohci/iface.c

    rd8987b1 ra8fa88d  
    151151    size_t max_packet_size, unsigned int interval)
    152152{
    153         UNSUPPORTED("register_endpoint");
    154 
    155         return ENOTSUP;
     153        assert(fun);
     154        hc_t *hc = fun_to_hc(fun);
     155        assert(hc);
     156        if (address == hc->rh.address)
     157                return EOK;
     158        const usb_speed_t speed =
     159                usb_device_keeper_get_speed(&hc->manager, address);
     160        const size_t size = max_packet_size;
     161        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
     162            address, endpoint, usb_str_transfer_type(transfer_type),
     163            usb_str_speed(speed), direction, size, max_packet_size, interval);
     164        return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction,
     165            speed, transfer_type, max_packet_size, size, interval);
    156166}
    157167/*----------------------------------------------------------------------------*/
     
    168178    usb_endpoint_t endpoint, usb_direction_t direction)
    169179{
    170         UNSUPPORTED("unregister_endpoint");
     180        assert(fun);
     181        hc_t *hc = fun_to_hc(fun);
     182        assert(hc);
     183        usb_log_debug("Unregister endpoint %d:%d %d.\n",
     184            address, endpoint, direction);
     185        return bandwidth_release(&hc->bandwidth, address, endpoint, direction);
    171186
    172187        return ENOTSUP;
  • uspace/drv/ohci/ohci_regs.h

    rd8987b1 ra8fa88d  
    3939typedef struct ohci_regs
    4040{
    41         volatile uint32_t revision;
     41        const volatile uint32_t revision;
    4242        volatile uint32_t control;
     43#define C_CSBR_MASK (0x3)
     44#define C_CSBR_SHIFT (0)
     45#define C_PLE (1 << 2)
     46#define C_IE (1 << 3)
     47#define C_CLE (1 << 4)
     48#define C_BLE (1 << 5)
     49
     50#define C_HCFS_MASK (0x3)
     51#define C_HCFS_SHIFT (6)
     52#define C_HCFS_RESET (0x0)
     53#define C_HCFS_OPERATIONAL (0x1)
     54#define C_HCFS_RESUME (0x2)
     55#define C_HCFS_SUSPEND (0x3)
     56
     57#define C_IR (1 << 8)
     58#define C_RWC (1 << 9)
     59#define C_RWE (1 << 10)
     60
    4361        volatile uint32_t command_status;
     62#define CS_HCR (1 << 0)
     63#define CS_CLF (1 << 1)
     64#define CS_BLF (1 << 2)
     65#define CS_OCR (1 << 3)
     66#define CS_SOC_MASK (0x3)
     67#define CS_SOC_SHIFT (16)
     68
    4469        volatile uint32_t interrupt_status;
    4570#define IS_SO (1 << 0)
     
    5176#define IS_RHSC (1 << 6)
    5277#define IS_OC (1 << 30)
     78
    5379        volatile uint32_t interupt_enable;
    5480#define IE_SO   (1 << 0)
  • uspace/drv/ohci/root_hub.c

    rd8987b1 ra8fa88d  
    252252
    253253
    254         usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff);
     254        usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
    255255
    256256        //start generic usb hub driver
  • uspace/drv/uhci-hcd/hc.c

    rd8987b1 ra8fa88d  
    241241        ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,
    242242            bandwidth_count_usb11);
    243         assert(ret == true);
     243        assert(ret == EOK);
    244244
    245245        return EOK;
  • uspace/lib/usb/src/host/bandwidth.c

    rd8987b1 ra8fa88d  
    127127        instance->free = bandwidth;
    128128        instance->usage_fnc = usage_fnc;
    129         return
     129        bool ht =
    130130            hash_table_create(&instance->reserved, BUCKET_COUNT, MAX_KEYS, &op);
     131        return ht ? EOK : ENOMEM;
    131132}
    132133/*----------------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.