Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset d57122c in mainline


Ignore:
Timestamp:
2012-02-12T18:41:44Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
master
Children:
bd8c6537
Parents:
a996ae31
Message:

UHCI and OHCI HC's now define and use proper IRQ PIO range.

Location:
uspace/drv/bus/usb
Files:
6 edited

Legend:

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

    ra996ae31 rd57122c  
    4747    (I_SO | I_WDH | I_UE | I_RHSC)
    4848
    49 static const irq_cmd_t ohci_irq_commands[] =
    50 {
    51         { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /*filled later*/ },
     49static const irq_pio_range_t ohci_pio_ranges[] = {
     50        {
     51                .base = 0,      /* filled later */
     52                .size = sizeof(ohci_regs_t)
     53        }
     54};
     55
     56static const irq_cmd_t ohci_irq_commands[] = {
     57        { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ },
    5258        { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = OHCI_USED_INTERRUPTS },
    5359        { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 },
    54         { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /*filled later*/ },
     60        { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /* filled later */ },
    5561        { .cmd = CMD_ACCEPT },
    5662};
     
    6369static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    6470/*----------------------------------------------------------------------------*/
     71/** Get number of PIO ranges used in IRQ code.
     72 * @return Number of ranges.
     73 */
     74size_t hc_irq_pio_range_count(void)
     75{
     76        return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
     77}
     78/*----------------------------------------------------------------------------*/
     79/*----------------------------------------------------------------------------*/
    6580/** Get number of commands used in IRQ code.
    6681 * @return Number of commands.
     
    7186}
    7287/*----------------------------------------------------------------------------*/
    73 /** Generate IRQ code commands.
    74  * @param[out] cmds Place to store the commands.
    75  * @param[in] cmd_size Size of the place (bytes).
     88/** Generate IRQ code.
     89 * @param[out] ranges PIO ranges buffer.
     90 * @param[in] ranges_size Size of the ranges buffer (bytes).
     91 * @param[out] cmds Commands buffer.
     92 * @param[in] cmds_size Size of the commands buffer (bytes).
    7693 * @param[in] regs Physical address of device's registers.
    7794 * @param[in] reg_size Size of the register area (bytes).
     
    7996 * @return Error code.
    8097 */
    81 int hc_get_irq_commands(
    82     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size)
    83 {
    84         if (cmd_size < sizeof(ohci_irq_commands)
    85             || reg_size < sizeof(ohci_regs_t))
     98int
     99hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
     100    size_t cmds_size, uintptr_t regs, size_t reg_size)
     101{
     102        if ((ranges_size < sizeof(ohci_pio_ranges)) ||
     103            (cmds_size < sizeof(ohci_irq_commands)) ||
     104            (reg_size < sizeof(ohci_regs_t)))
    86105                return EOVERFLOW;
    87106
    88         /* Create register mapping to use in IRQ handler.
    89          * This mapping should be present in kernel only.
    90          * Remove it from here when kernel knows how to create mappings
    91          * and accepts physical addresses in IRQ code.
    92          * TODO: remove */
    93         ohci_regs_t *registers;
    94         const int ret = pio_enable((void*)regs, reg_size, (void**)&registers);
    95         if (ret != EOK)
    96                 return ret;
    97 
    98         /* Some bogus access to force create mapping. DO NOT remove,
    99          * unless whole virtual addresses in irq is replaced
    100          * NOTE: Compiler won't remove this as ohci_regs_t members
    101          * are declared volatile.
    102          *
    103          * Introducing CMD_MEM set of IRQ code commands broke
    104          * assumption that IRQ code does not cause page faults.
    105          * If this happens during idling (THREAD == NULL)
    106          * it causes kernel panic.
    107          */
    108         registers->revision;
     107        memcpy(ranges, ohci_pio_ranges, sizeof(ohci_pio_ranges));
     108        ranges[0].base = regs;
    109109
    110110        memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands));
    111 
    112         void *address = (void*)&registers->interrupt_status;
    113         cmds[0].addr = address;
    114         cmds[3].addr = address;
     111        ohci_regs_t *registers = (ohci_regs_t *) regs;
     112        cmds[0].addr = (void *) &registers->interrupt_status;
     113        cmds[3].addr = (void *) &registers->interrupt_status;
     114
    115115        return EOK;
    116116}
  • uspace/drv/bus/usb/ohci/hc.h

    ra996ae31 rd57122c  
    7474} hc_t;
    7575
     76size_t hc_irq_pio_range_count(void);
    7677size_t hc_irq_cmd_count(void);
    77 int hc_get_irq_commands(
    78     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
     78int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
     79    size_t);
    7980int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
    8081int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
  • uspace/drv/bus/usb/ohci/ohci.c

    ra996ae31 rd57122c  
    187187            (void *) reg_base, reg_size, irq);
    188188
    189         const size_t cmd_count = hc_irq_cmd_count();
    190         irq_cmd_t irq_cmds[cmd_count];
    191         irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
    192 
    193         ret =
    194             hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size);
    195         CHECK_RET_DEST_FREE_RETURN(ret,
    196             "Failed to generate IRQ commands: %s.\n", str_error(ret));
     189        const size_t ranges_count = hc_irq_pio_range_count();
     190        const size_t cmds_count = hc_irq_cmd_count();
     191        irq_pio_range_t irq_ranges[ranges_count];
     192        irq_cmd_t irq_cmds[cmds_count];
     193        irq_code_t irq_code = {
     194                .rangecount = ranges_count,
     195                .ranges = irq_ranges,
     196                .cmdcount = cmds_count,
     197                .cmds = irq_cmds
     198        };
     199
     200        ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     201            sizeof(irq_cmds), reg_base, reg_size);
     202        CHECK_RET_DEST_FREE_RETURN(ret,
     203            "Failed to generate IRQ code: %s.\n", str_error(ret));
    197204
    198205
  • uspace/drv/bus/usb/uhci/hc.c

    ra996ae31 rd57122c  
    4848    (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
    4949
    50 
    51 static const irq_cmd_t uhci_irq_commands[] =
    52 {
     50static const irq_pio_range_t uhci_irq_pio_ranges[] = {
     51        {
     52                .base = 0,      /* filled later */
     53                .size = sizeof(uhci_regs_t)
     54        }
     55};
     56
     57static const irq_cmd_t uhci_irq_commands[] = {
    5358        { .cmd = CMD_PIO_READ_16, .dstarg = 1, .addr = NULL/*filled later*/},
    5459        { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2,
     
    6873
    6974/*----------------------------------------------------------------------------*/
     75/** Get number of PIO ranges used in IRQ code.
     76 * @return Number of ranges.
     77 */
     78size_t hc_irq_pio_range_count(void)
     79{
     80        return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t);
     81}
     82/*----------------------------------------------------------------------------*/
    7083/** Get number of commands used in IRQ code.
    7184 * @return Number of commands.
     
    7689}
    7790/*----------------------------------------------------------------------------*/
    78 /** Generate IRQ code commands.
    79  * @param[out] cmds Place to store the commands.
    80  * @param[in] cmd_size Size of the place (bytes).
     91/** Generate IRQ code.
     92 * @param[out] ranges PIO ranges buffer.
     93 * @param[in] ranges_size Size of the ranges buffer (bytes).
     94 * @param[out] cmds Commands buffer.
     95 * @param[in] cmds_size Size of the commands buffer (bytes).
    8196 * @param[in] regs Physical address of device's registers.
    8297 * @param[in] reg_size Size of the register area (bytes).
     
    8499 * @return Error code.
    85100 */
    86 int hc_get_irq_commands(
    87     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size)
    88 {
    89         if (cmd_size < sizeof(uhci_irq_commands)
    90             || reg_size < sizeof(uhci_regs_t))
     101int
     102hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
     103    size_t cmds_size, uintptr_t regs, size_t reg_size)
     104{
     105        if ((ranges_size < sizeof(uhci_irq_pio_ranges)) ||
     106            (cmds_size < sizeof(uhci_irq_commands)) ||
     107            (reg_size < sizeof(uhci_regs_t)))
    91108                return EOVERFLOW;
    92109
    93         uhci_regs_t *registers = (uhci_regs_t*)regs;
     110        memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
     111        ranges[0].base = regs;
    94112
    95113        memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
    96 
    97         cmds[0].addr = (void*)&registers->usbsts;
    98         cmds[3].addr = (void*)&registers->usbsts;
     114        uhci_regs_t *registers = (uhci_regs_t *) regs;
     115        cmds[0].addr = &registers->usbsts;
     116        cmds[3].addr = &registers->usbsts;
     117
    99118        return EOK;
    100119}
  • uspace/drv/bus/usb/uhci/hc.h

    ra996ae31 rd57122c  
    121121} hc_t;
    122122
     123size_t hc_irq_pio_range_count(void);
    123124size_t hc_irq_cmd_count(void);
    124 int hc_get_irq_commands(
    125     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
     125int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
     126    size_t);
    126127void hc_interrupt(hc_t *instance, uint16_t status);
    127128int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);
  • uspace/drv/bus/usb/uhci/uhci.c

    ra996ae31 rd57122c  
    198198            "Failed to disable legacy USB: %s.\n", str_error(ret));
    199199
    200         const size_t cmd_count = hc_irq_cmd_count();
    201         irq_cmd_t irq_cmds[cmd_count];
    202         ret =
    203             hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size);
     200        const size_t ranges_count = hc_irq_pio_range_count();
     201        const size_t cmds_count = hc_irq_cmd_count();
     202        irq_pio_range_t irq_ranges[ranges_count];
     203        irq_cmd_t irq_cmds[cmds_count];
     204        ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     205            sizeof(irq_cmds), reg_base, reg_size);
    204206        CHECK_RET_DEST_FREE_RETURN(ret,
    205207            "Failed to generate IRQ commands: %s.\n", str_error(ret));
    206208
    207         irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
     209        irq_code_t irq_code = {
     210                .rangecount = ranges_count,
     211                .ranges = irq_ranges,
     212                .cmdcount = cmds_count,
     213                .cmds = irq_cmds
     214        };
    208215
    209216        /* Register handler to avoid interrupt lockup */
Note: See TracChangeset for help on using the changeset viewer.