Changeset dfe4955 in mainline
- Timestamp:
- 2011-07-12T18:38:27Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 26858040
- Parents:
- b4f291d
- Location:
- uspace/drv/bus/usb
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci.c
rb4f291d rdfe4955 202 202 hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size); 203 203 CHECK_RET_DEST_FREE_RETURN(ret, 204 "Failed to generate IRQ co de: %s.\n", str_error(ret));204 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 205 205 206 206 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds }; … … 217 217 if (ret != EOK) { 218 218 usb_log_warning("Failed to enable interrupts: %s." 219 " Falling back to polling\n", str_error(ret));219 " Falling back to polling\n", str_error(ret)); 220 220 /* We don't need that handler */ 221 221 unregister_interrupt_handler(device, irq); -
uspace/drv/bus/usb/uhci/hc.c
rb4f291d rdfe4955 47 47 (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT) 48 48 49 static const irq_cmd_t uhci_irq_commands[] = 50 { 51 { .cmd = CMD_PIO_READ_16, .dstarg = 1, .addr = NULL/*filled later*/}, 52 { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, 53 .value = UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS }, 54 { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 }, 55 { .cmd = CMD_PIO_WRITE_A_16, .srcarg = 1, .addr = NULL/*filled later*/}, 56 { .cmd = CMD_ACCEPT }, 57 }; 49 58 50 59 static int hc_init_transfer_lists(hc_t *instance); … … 54 63 static int hc_interrupt_emulator(void *arg); 55 64 static int hc_debug_checker(void *arg); 65 66 /*----------------------------------------------------------------------------*/ 67 /** Get number of commands used in IRQ code. 68 * @return Number of commands. 69 */ 70 size_t hc_irq_cmd_count(void) 71 { 72 return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t); 73 } 74 /*----------------------------------------------------------------------------*/ 75 /** Generate IRQ code commands. 76 * @param[out] cmds Place to store the commands. 77 * @param[in] cmd_size Size of the place (bytes). 78 * @param[in] regs Physical address of device's registers. 79 * @param[in] reg_size Size of the register area (bytes). 80 * 81 * @return Error code. 82 */ 83 int hc_get_irq_commands( 84 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size) 85 { 86 if (cmd_size < sizeof(uhci_irq_commands) 87 || reg_size < sizeof(uhci_regs_t)) 88 return EOVERFLOW; 89 90 uhci_regs_t *registers = (uhci_regs_t*)regs; 91 92 memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands)); 93 94 cmds[0].addr = (void*)®isters->usbsts; 95 cmds[3].addr = (void*)®isters->usbsts; 96 return EOK; 97 } 56 98 /*----------------------------------------------------------------------------*/ 57 99 /** Initialize UHCI hc driver structure … … 69 111 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts) 70 112 { 71 assert(reg_size >= sizeof( regs_t));113 assert(reg_size >= sizeof(uhci_regs_t)); 72 114 int ret; 73 115 … … 82 124 83 125 /* allow access to hc control registers */ 84 regs_t *io;126 uhci_regs_t *io; 85 127 ret = pio_enable(regs, reg_size, (void **)&io); 86 128 CHECK_RET_RETURN(ret, … … 116 158 { 117 159 assert(instance); 118 regs_t *registers = instance->registers;160 uhci_regs_t *registers = instance->registers; 119 161 120 162 /* Reset everything, who knows what touched it before us */ -
uspace/drv/bus/usb/uhci/hc.h
rb4f291d rdfe4955 84 84 /** SOF modification to match external timers */ 85 85 uint8_t sofmod; 86 } regs_t;86 } uhci_regs_t; 87 87 88 88 #define UHCI_FRAME_LIST_COUNT 1024 … … 100 100 101 101 /** Addresses of I/O registers */ 102 regs_t *registers;102 uhci_regs_t *registers; 103 103 104 104 /** Frame List contains 1024 link pointers */ … … 132 132 unsigned hw_failures; 133 133 } hc_t; 134 134 size_t hc_irq_cmd_count(void); 135 int hc_get_irq_commands( 136 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size); 135 137 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts); 136 137 138 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); 138 139 139 void hc_interrupt(hc_t *instance, uint16_t status); 140 140 -
uspace/drv/bus/usb/uhci/uhci.c
rb4f291d rdfe4955 64 64 { 65 65 assert(dev); 66 assert(dev->driver_data);67 66 return dev->driver_data; 68 67 } … … 78 77 assert(dev); 79 78 uhci_t *uhci = dev_to_uhci(dev); 79 if (!uhci) { 80 usb_log_error("Interrupt on not yet initialized device.\n"); 81 return; 82 } 80 83 hc_t *hc = &uhci->hc; 81 84 const uint16_t status = IPC_GET_ARG1(*call); 82 assert(hc);83 85 hc_interrupt(hc, status); 84 86 } … … 192 194 } \ 193 195 free(instance); \ 196 device->driver_data = NULL; \ 194 197 usb_log_error(message); \ 195 198 return ret; \ … … 222 225 ret = pci_disable_legacy(device); 223 226 CHECK_RET_DEST_FREE_RETURN(ret, 224 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 227 "Failed to disable legacy USB: %s.\n", str_error(ret)); 228 229 const size_t cmd_count = hc_irq_cmd_count(); 230 irq_cmd_t irq_cmds[cmd_count]; 231 ret = 232 hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size); 233 CHECK_RET_DEST_FREE_RETURN(ret, 234 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 235 236 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds }; 237 238 /* Register handler to avoid interrupt lockup */ 239 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 240 CHECK_RET_DEST_FREE_RETURN(ret, 241 "Failed to register interrupt handler: %s.\n", str_error(ret)); 225 242 226 243 bool interrupts = false; 227 #ifdef CONFIG_USBHC_NO_INTERRUPTS228 usb_log_warning("Interrupts disabled in OS config, " \229 "falling back to polling.\n");230 #else231 244 ret = pci_enable_interrupts(device); 232 245 if (ret != EOK) { 233 usb_log_warning("Failed to enable interrupts: %s.\n", 234 str_error(ret)); 235 usb_log_info("HW interrupts not available, " \ 236 "falling back to polling.\n"); 246 usb_log_warning("Failed to enable interrupts: %s." 247 " Falling back to polling.\n", str_error(ret)); 237 248 } else { 238 249 usb_log_debug("Hw interrupts enabled.\n"); 239 250 interrupts = true; 240 251 } 241 #endif242 243 252 244 253 ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts); 245 254 CHECK_RET_DEST_FREE_RETURN(ret, 246 255 "Failed(%d) to init uhci_hcd: %s.\n", ret, str_error(ret)); 256 257 device->driver_data = instance; 247 258 248 259 #define CHECK_RET_FINI_RETURN(ret, message...) \ … … 253 264 } else (void)0 254 265 255 /* It does no harm if we register this on polling */256 ret = register_interrupt_handler(device, irq, irq_handler,257 &instance->hc.interrupt_code);258 CHECK_RET_FINI_RETURN(ret,259 "Failed(%d) to register interrupt handler: %s.\n",260 ret, str_error(ret));261 262 266 ret = ddf_fun_bind(instance->hc_fun); 263 267 CHECK_RET_FINI_RETURN(ret, … … 278 282 "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret)); 279 283 280 device->driver_data = instance;281 284 return EOK; 282 285 #undef CHECK_RET_FINI_RETURN
Note:
See TracChangeset
for help on using the changeset viewer.