Changes in uspace/drv/bus/usb/uhci/hc.c [5203e256:26858040] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/hc.c
r5203e256 r26858040 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 CHECK_RET_RETURN(ret, 87 "Failed(%d) to gain access to registers at %p: %s.\n", 88 ret, io, str_error(ret)); 128 CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n", 129 io, str_error(ret)); 89 130 instance->registers = io; 90 usb_log_debug( "Device registers at %p (%zuB) accessible.\n",91 io, reg_size);131 usb_log_debug( 132 "Device registers at %p (%zuB) accessible.\n", io, reg_size); 92 133 93 134 ret = hc_init_mem_structures(instance); 94 135 CHECK_RET_RETURN(ret, 95 "Failed (%d)to initialize UHCI memory structures: %s.\n",96 ret,str_error(ret));136 "Failed to initialize UHCI memory structures: %s.\n", 137 str_error(ret)); 97 138 98 139 hc_init_hw(instance); … … 116 157 { 117 158 assert(instance); 118 regs_t *registers = instance->registers;159 uhci_regs_t *registers = instance->registers; 119 160 120 161 /* Reset everything, who knows what touched it before us */ 121 162 pio_write_16(®isters->usbcmd, UHCI_CMD_GLOBAL_RESET); 122 async_usleep( 10000); /* 10ms according to USB spec*/163 async_usleep(50000); /* 50ms according to USB spec(root hub reset) */ 123 164 pio_write_16(®isters->usbcmd, 0); 124 165 125 /* Reset hc, all states and counters */166 /* Reset hc, all states and counters. Hope that hw is not broken */ 126 167 pio_write_16(®isters->usbcmd, UHCI_CMD_HCRESET); 127 168 do { async_usleep(10); } … … 141 182 } 142 183 143 const uint16_t status= pio_read_16(®isters->usbcmd);144 if ( status!= 0)145 usb_log_warning("Previous command value: %x.\n", status);184 const uint16_t cmd = pio_read_16(®isters->usbcmd); 185 if (cmd != 0) 186 usb_log_warning("Previous command value: %x.\n", cmd); 146 187 147 188 /* Start the hc with large(64B) packet FSBR */ … … 170 211 } else (void) 0 171 212 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 205 213 /* Init transfer lists */ 206 214 int ret = hc_init_transfer_lists(instance); 207 CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n");215 CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n"); 208 216 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 }224 217 225 218 /* Init device keeper */ 226 219 usb_device_keeper_init(&instance->manager); 227 usb_log_debug("Initialized device manager.\n");220 usb_log_debug("Initialized device keeper.\n"); 228 221 229 222 ret = usb_endpoint_manager_init(&instance->ep_manager, … … 232 225 str_error(ret)); 233 226 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 234 244 return EOK; 235 245 #undef CHECK_RET_RETURN … … 252 262 int ret = transfer_list_init(&instance->transfers_##type, name); \ 253 263 if (ret != EOK) { \ 254 usb_log_error("Failed (%d)to setup %s transfer list: %s.\n", \255 ret,name, str_error(ret)); \264 usb_log_error("Failed to setup %s transfer list: %s.\n", \ 265 name, str_error(ret)); \ 256 266 transfer_list_fini(&instance->transfers_bulk_full); \ 257 267 transfer_list_fini(&instance->transfers_control_full); \
Note:
See TracChangeset
for help on using the changeset viewer.