Changes in uspace/drv/bus/usb/uhci/hc.c [26858040:5203e256] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/hc.c
r26858040 r5203e256 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 };58 49 59 50 static int hc_init_transfer_lists(hc_t *instance); … … 63 54 static int hc_interrupt_emulator(void *arg); 64 55 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 }98 56 /*----------------------------------------------------------------------------*/ 99 57 /** Initialize UHCI hc driver structure … … 111 69 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts) 112 70 { 113 assert(reg_size >= sizeof( uhci_regs_t));71 assert(reg_size >= sizeof(regs_t)); 114 72 int ret; 115 73 … … 124 82 125 83 /* allow access to hc control registers */ 126 uhci_regs_t *io;84 regs_t *io; 127 85 ret = pio_enable(regs, reg_size, (void **)&io); 128 CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n", 129 io, str_error(ret)); 86 CHECK_RET_RETURN(ret, 87 "Failed(%d) to gain access to registers at %p: %s.\n", 88 ret, io, str_error(ret)); 130 89 instance->registers = io; 131 usb_log_debug( 132 "Device registers at %p (%zuB) accessible.\n",io, reg_size);90 usb_log_debug("Device registers at %p (%zuB) accessible.\n", 91 io, reg_size); 133 92 134 93 ret = hc_init_mem_structures(instance); 135 94 CHECK_RET_RETURN(ret, 136 "Failed to initialize UHCI memory structures: %s.\n",137 str_error(ret));95 "Failed(%d) to initialize UHCI memory structures: %s.\n", 96 ret, str_error(ret)); 138 97 139 98 hc_init_hw(instance); … … 157 116 { 158 117 assert(instance); 159 uhci_regs_t *registers = instance->registers;118 regs_t *registers = instance->registers; 160 119 161 120 /* Reset everything, who knows what touched it before us */ 162 121 pio_write_16(®isters->usbcmd, UHCI_CMD_GLOBAL_RESET); 163 async_usleep( 50000); /* 50ms according to USB spec(root hub reset)*/122 async_usleep(10000); /* 10ms according to USB spec */ 164 123 pio_write_16(®isters->usbcmd, 0); 165 124 166 /* Reset hc, all states and counters . Hope that hw is not broken*/125 /* Reset hc, all states and counters */ 167 126 pio_write_16(®isters->usbcmd, UHCI_CMD_HCRESET); 168 127 do { async_usleep(10); } … … 182 141 } 183 142 184 const uint16_t cmd= pio_read_16(®isters->usbcmd);185 if ( cmd!= 0)186 usb_log_warning("Previous command value: %x.\n", cmd);143 const uint16_t status = pio_read_16(®isters->usbcmd); 144 if (status != 0) 145 usb_log_warning("Previous command value: %x.\n", status); 187 146 188 147 /* Start the hc with large(64B) packet FSBR */ … … 211 170 } else (void) 0 212 171 172 /* Init interrupt code */ 173 instance->interrupt_code.cmds = instance->interrupt_commands; 174 { 175 /* Read status register */ 176 instance->interrupt_commands[0].cmd = CMD_PIO_READ_16; 177 instance->interrupt_commands[0].dstarg = 1; 178 instance->interrupt_commands[0].addr = 179 &instance->registers->usbsts; 180 181 /* Test whether we are the interrupt cause */ 182 instance->interrupt_commands[1].cmd = CMD_BTEST; 183 instance->interrupt_commands[1].value = 184 UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS; 185 instance->interrupt_commands[1].srcarg = 1; 186 instance->interrupt_commands[1].dstarg = 2; 187 188 /* Predicate cleaning and accepting */ 189 instance->interrupt_commands[2].cmd = CMD_PREDICATE; 190 instance->interrupt_commands[2].value = 2; 191 instance->interrupt_commands[2].srcarg = 2; 192 193 /* Write clean status register */ 194 instance->interrupt_commands[3].cmd = CMD_PIO_WRITE_A_16; 195 instance->interrupt_commands[3].srcarg = 1; 196 instance->interrupt_commands[3].addr = 197 &instance->registers->usbsts; 198 199 /* Accept interrupt */ 200 instance->interrupt_commands[4].cmd = CMD_ACCEPT; 201 202 instance->interrupt_code.cmdcount = UHCI_NEEDED_IRQ_COMMANDS; 203 } 204 213 205 /* Init transfer lists */ 214 206 int ret = hc_init_transfer_lists(instance); 215 CHECK_RET_RETURN(ret, "Failed to init ializetransfer lists.\n");207 CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n"); 216 208 usb_log_debug("Initialized transfer lists.\n"); 209 210 /* Init USB frame list page*/ 211 instance->frame_list = get_page(); 212 ret = instance->frame_list ? EOK : ENOMEM; 213 CHECK_RET_RETURN(ret, "Failed to get frame list page.\n"); 214 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list); 215 216 /* Set all frames to point to the first queue head */ 217 const uint32_t queue = LINK_POINTER_QH( 218 addr_to_phys(instance->transfers_interrupt.queue_head)); 219 220 unsigned i = 0; 221 for(; i < UHCI_FRAME_LIST_COUNT; ++i) { 222 instance->frame_list[i] = queue; 223 } 217 224 218 225 /* Init device keeper */ 219 226 usb_device_keeper_init(&instance->manager); 220 usb_log_debug("Initialized device keeper.\n");227 usb_log_debug("Initialized device manager.\n"); 221 228 222 229 ret = usb_endpoint_manager_init(&instance->ep_manager, … … 225 232 str_error(ret)); 226 233 227 /* Init USB frame list page*/228 instance->frame_list = get_page();229 if (!instance->frame_list) {230 usb_log_error("Failed to get frame list page.\n");231 usb_endpoint_manager_destroy(&instance->ep_manager);232 return ENOMEM;233 }234 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);235 236 /* Set all frames to point to the first queue head */237 const uint32_t queue = LINK_POINTER_QH(238 addr_to_phys(instance->transfers_interrupt.queue_head));239 unsigned i = 0;240 for(; i < UHCI_FRAME_LIST_COUNT; ++i) {241 instance->frame_list[i] = queue;242 }243 244 234 return EOK; 245 235 #undef CHECK_RET_RETURN … … 262 252 int ret = transfer_list_init(&instance->transfers_##type, name); \ 263 253 if (ret != EOK) { \ 264 usb_log_error("Failed to setup %s transfer list: %s.\n", \265 name, str_error(ret)); \254 usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \ 255 ret, name, str_error(ret)); \ 266 256 transfer_list_fini(&instance->transfers_bulk_full); \ 267 257 transfer_list_fini(&instance->transfers_control_full); \
Note:
See TracChangeset
for help on using the changeset viewer.