Changeset d57122c in mainline
- Timestamp:
- 2012-02-12T18:41:44Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bd8c6537
- Parents:
- a996ae31
- Location:
- uspace/drv/bus/usb
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hc.c
ra996ae31 rd57122c 47 47 (I_SO | I_WDH | I_UE | I_RHSC) 48 48 49 static const irq_cmd_t ohci_irq_commands[] = 50 { 51 { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /*filled later*/ }, 49 static const irq_pio_range_t ohci_pio_ranges[] = { 50 { 51 .base = 0, /* filled later */ 52 .size = sizeof(ohci_regs_t) 53 } 54 }; 55 56 static const irq_cmd_t ohci_irq_commands[] = { 57 { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ }, 52 58 { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = OHCI_USED_INTERRUPTS }, 53 59 { .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 */ }, 55 61 { .cmd = CMD_ACCEPT }, 56 62 }; … … 63 69 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 64 70 /*----------------------------------------------------------------------------*/ 71 /** Get number of PIO ranges used in IRQ code. 72 * @return Number of ranges. 73 */ 74 size_t hc_irq_pio_range_count(void) 75 { 76 return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t); 77 } 78 /*----------------------------------------------------------------------------*/ 79 /*----------------------------------------------------------------------------*/ 65 80 /** Get number of commands used in IRQ code. 66 81 * @return Number of commands. … … 71 86 } 72 87 /*----------------------------------------------------------------------------*/ 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). 76 93 * @param[in] regs Physical address of device's registers. 77 94 * @param[in] reg_size Size of the register area (bytes). … … 79 96 * @return Error code. 80 97 */ 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)) 98 int 99 hc_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))) 86 105 return EOVERFLOW; 87 106 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**)®isters); 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; 109 109 110 110 memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands)); 111 112 void *address = (void*)®isters->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 *) ®isters->interrupt_status; 113 cmds[3].addr = (void *) ®isters->interrupt_status; 114 115 115 return EOK; 116 116 } -
uspace/drv/bus/usb/ohci/hc.h
ra996ae31 rd57122c 74 74 } hc_t; 75 75 76 size_t hc_irq_pio_range_count(void); 76 77 size_t hc_irq_cmd_count(void); 77 int hc_get_irq_co mmands(78 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);78 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t, 79 size_t); 79 80 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 80 81 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); -
uspace/drv/bus/usb/ohci/ohci.c
ra996ae31 rd57122c 187 187 (void *) reg_base, reg_size, irq); 188 188 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)); 197 204 198 205 -
uspace/drv/bus/usb/uhci/hc.c
ra996ae31 rd57122c 48 48 (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT) 49 49 50 51 static const irq_cmd_t uhci_irq_commands[] = 52 { 50 static const irq_pio_range_t uhci_irq_pio_ranges[] = { 51 { 52 .base = 0, /* filled later */ 53 .size = sizeof(uhci_regs_t) 54 } 55 }; 56 57 static const irq_cmd_t uhci_irq_commands[] = { 53 58 { .cmd = CMD_PIO_READ_16, .dstarg = 1, .addr = NULL/*filled later*/}, 54 59 { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, … … 68 73 69 74 /*----------------------------------------------------------------------------*/ 75 /** Get number of PIO ranges used in IRQ code. 76 * @return Number of ranges. 77 */ 78 size_t hc_irq_pio_range_count(void) 79 { 80 return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t); 81 } 82 /*----------------------------------------------------------------------------*/ 70 83 /** Get number of commands used in IRQ code. 71 84 * @return Number of commands. … … 76 89 } 77 90 /*----------------------------------------------------------------------------*/ 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). 81 96 * @param[in] regs Physical address of device's registers. 82 97 * @param[in] reg_size Size of the register area (bytes). … … 84 99 * @return Error code. 85 100 */ 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)) 101 int 102 hc_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))) 91 108 return EOVERFLOW; 92 109 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; 94 112 95 113 memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands)); 96 97 cmds[0].addr = (void*)®isters->usbsts; 98 cmds[3].addr = (void*)®isters->usbsts; 114 uhci_regs_t *registers = (uhci_regs_t *) regs; 115 cmds[0].addr = ®isters->usbsts; 116 cmds[3].addr = ®isters->usbsts; 117 99 118 return EOK; 100 119 } -
uspace/drv/bus/usb/uhci/hc.h
ra996ae31 rd57122c 121 121 } hc_t; 122 122 123 size_t hc_irq_pio_range_count(void); 123 124 size_t hc_irq_cmd_count(void); 124 int hc_get_irq_co mmands(125 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);125 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t, 126 size_t); 126 127 void hc_interrupt(hc_t *instance, uint16_t status); 127 128 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts); -
uspace/drv/bus/usb/uhci/uhci.c
ra996ae31 rd57122c 198 198 "Failed to disable legacy USB: %s.\n", str_error(ret)); 199 199 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); 204 206 CHECK_RET_DEST_FREE_RETURN(ret, 205 207 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 206 208 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 }; 208 215 209 216 /* Register handler to avoid interrupt lockup */
Note:
See TracChangeset
for help on using the changeset viewer.