Changes in uspace/drv/bus/usb/ohci/hc.c [8b54fe6:d57122c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/hc.c
r8b54fe6 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_MEM_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_ MEM_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 } … … 127 127 assert(hub_fun); 128 128 129 const usb_address_t hub_address = 130 usb_device_manager_get_free_address( 131 &instance->generic.dev_manager, USB_SPEED_FULL); 132 if (hub_address <= 0) { 129 /* Try to get address 1 for root hub. */ 130 instance->rh.address = 1; 131 int ret = usb_device_manager_request_address( 132 &instance->generic.dev_manager, &instance->rh.address, false, 133 USB_SPEED_FULL); 134 if (ret != EOK) { 133 135 usb_log_error("Failed to get OHCI root hub address: %s\n", 134 str_error(hub_address)); 135 return hub_address; 136 } 137 instance->rh.address = hub_address; 138 usb_device_manager_bind( 139 &instance->generic.dev_manager, hub_address, hub_fun->handle); 136 str_error(ret)); 137 return ret; 138 } 140 139 141 140 #define CHECK_RET_UNREG_RETURN(ret, message...) \ 142 141 if (ret != EOK) { \ 143 142 usb_log_error(message); \ 144 usb_endpoint_manager_unregister_ep( \ 145 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\ 146 usb_device_manager_release( \ 147 &instance->generic.dev_manager, hub_address); \ 143 usb_endpoint_manager_remove_ep( \ 144 &instance->generic.ep_manager, instance->rh.address, 0, \ 145 USB_DIRECTION_BOTH, NULL, NULL); \ 146 usb_device_manager_release_address( \ 147 &instance->generic.dev_manager, instance->rh.address); \ 148 148 return ret; \ 149 149 } else (void)0 150 int ret = usb_endpoint_manager_add_ep( 151 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, 152 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0); 150 151 ret = usb_endpoint_manager_add_ep( 152 &instance->generic.ep_manager, instance->rh.address, 0, 153 USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 154 0, NULL, NULL); 153 155 CHECK_RET_UNREG_RETURN(ret, 154 156 "Failed to register root hub control endpoint: %s.\n", … … 162 164 CHECK_RET_UNREG_RETURN(ret, 163 165 "Failed to bind root hub function: %s.\n", str_error(ret)); 166 167 ret = usb_device_manager_bind_address(&instance->generic.dev_manager, 168 instance->rh.address, hub_fun->handle); 169 if (ret != EOK) 170 usb_log_warning("Failed to bind root hub address: %s.\n", 171 str_error(ret)); 164 172 165 173 return EOK; … … 192 200 list_initialize(&instance->pending_batches); 193 201 194 ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11, 195 bandwidth_count_usb11); 196 CHECK_RET_RETURN(ret, "Failed to initialize generic driver: %s.\n", 197 str_error(ret)); 202 hcd_init(&instance->generic, USB_SPEED_FULL, 203 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 198 204 instance->generic.private_data = instance; 199 205 instance->generic.schedule = hc_schedule; 200 206 instance->generic.ep_add_hook = ohci_endpoint_init; 207 instance->generic.ep_remove_hook = ohci_endpoint_fini; 201 208 202 209 ret = hc_init_memory(instance); … … 221 228 } 222 229 /*----------------------------------------------------------------------------*/ 223 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep) 224 { 230 void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep) 231 { 232 assert(instance); 233 assert(ep); 234 225 235 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 226 236 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 237 assert(list); 238 assert(ohci_ep); 239 227 240 /* Enqueue ep */ 228 241 switch (ep->transfer_type) { … … 247 260 } 248 261 /*----------------------------------------------------------------------------*/ 249 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep) 250 { 262 void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep) 263 { 264 assert(instance); 265 assert(ep); 266 251 267 /* Dequeue ep */ 252 268 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 253 269 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 270 271 assert(list); 272 assert(ohci_ep); 254 273 switch (ep->transfer_type) { 255 274 case USB_TRANSFER_CONTROL: … … 565 584 566 585 /*Init HCCA */ 567 instance->hcca = malloc32(sizeof(hcca_t));586 instance->hcca = hcca_get(); 568 587 if (instance->hcca == NULL) 569 588 return ENOMEM; … … 571 590 usb_log_debug2("OHCI HCCA initialized at %p.\n", instance->hcca); 572 591 573 unsigned i = 0; 574 for (; i < 32; ++i) { 592 for (unsigned i = 0; i < 32; ++i) { 575 593 instance->hcca->int_ep[i] = 576 594 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa;
Note:
See TracChangeset
for help on using the changeset viewer.