Changes in / [ac8285d:4c7c251] in mainline
- Location:
- uspace
- Files:
-
- 3 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/pciintel/pci.c
rac8285d r4c7c251 59 59 #include <ddi.h> 60 60 #include <libarch/ddi.h> 61 #include <pci_dev_iface.h> 61 62 62 63 #include "pci.h" … … 121 122 } 122 123 124 static int pci_config_space_write_16(ddf_fun_t *fun, uint32_t address, uint16_t data) 125 { 126 if (address > 254) 127 return EINVAL; 128 pci_conf_write_16(PCI_FUN(fun), address, data); 129 return EOK; 130 } 131 132 123 133 static hw_res_ops_t pciintel_hw_res_ops = { 124 134 &pciintel_get_resources, … … 126 136 }; 127 137 128 static ddf_dev_ops_t pci_fun_ops; 138 static pci_dev_iface_t pci_dev_ops = { 139 .config_space_read_8 = NULL, 140 .config_space_read_16 = NULL, 141 .config_space_read_32 = NULL, 142 .config_space_write_8 = NULL, 143 .config_space_write_16 = &pci_config_space_write_16, 144 .config_space_write_32 = NULL 145 }; 146 147 static ddf_dev_ops_t pci_fun_ops = { 148 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 149 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 150 }; 129 151 130 152 static int pci_add_device(ddf_dev_t *); … … 593 615 { 594 616 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 617 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops; 595 618 } 596 619 -
uspace/drv/uhci-hcd/main.c
rac8285d r4c7c251 34 34 #include <ddf/driver.h> 35 35 #include <ddf/interrupt.h> 36 #include <device/hw_res.h> 37 #include <errno.h> 38 #include <str_error.h> 39 36 40 #include <usb_iface.h> 37 41 #include <usb/ddfiface.h> 38 #include <device/hw_res.h>39 40 #include <errno.h>41 42 42 #include <usb/debug.h> 43 43 … … 50 50 51 51 static int uhci_add_device(ddf_dev_t *device); 52 53 52 /*----------------------------------------------------------------------------*/ 54 53 static driver_ops_t uhci_driver_ops = { … … 70 69 } 71 70 /*----------------------------------------------------------------------------*/ 72 #define CHECK_RET_RETURN(ret, message...) \73 if (ret != EOK) { \74 usb_log_error(message); \75 return ret; \76 }77 78 71 static int uhci_add_device(ddf_dev_t *device) 79 72 { 80 73 assert(device); 74 uhci_t *hcd = NULL; 75 #define CHECK_RET_FREE_HC_RETURN(ret, message...) \ 76 if (ret != EOK) { \ 77 usb_log_error(message); \ 78 if (hcd != NULL) \ 79 free(hcd); \ 80 return ret; \ 81 } 81 82 82 83 usb_log_info("uhci_add_device() called\n"); … … 88 89 int ret = 89 90 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 90 91 CHECK_RET_RETURN(ret, 91 CHECK_RET_FREE_HC_RETURN(ret, 92 92 "Failed(%d) to get I/O addresses:.\n", ret, device->handle); 93 93 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n", 94 94 io_reg_base, io_reg_size, irq); 95 95 96 // ret = pci_enable_interrupts(device); 97 // CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret); 96 ret = pci_disable_legacy(device); 97 CHECK_RET_FREE_HC_RETURN(ret, 98 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret)); 98 99 99 uhci_t *uhci_hc = malloc(sizeof(uhci_t)); 100 ret = (uhci_hc != NULL) ? EOK : ENOMEM; 101 CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n"); 100 #if 0 101 ret = pci_enable_interrupts(device); 102 if (ret != EOK) { 103 usb_log_warning( 104 "Failed(%d) to enable interrupts, fall back to polling.\n", 105 ret); 106 } 107 #endif 102 108 103 ret = uhci_init(uhci_hc, device, (void*)io_reg_base, io_reg_size); 104 if (ret != EOK) { 105 usb_log_error("Failed to init uhci-hcd.\n"); 106 free(uhci_hc); 107 return ret; 108 } 109 hcd = malloc(sizeof(uhci_t)); 110 ret = (hcd != NULL) ? EOK : ENOMEM; 111 CHECK_RET_FREE_HC_RETURN(ret, 112 "Failed(%d) to allocate memory for uhci hcd.\n", ret); 113 114 ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size); 115 CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", 116 ret); 117 #undef CHECK_RET_FREE_HC_RETURN 109 118 110 119 /* 111 * We might free uhci_hc, but that does not matter since no one120 * We might free hcd, but that does not matter since no one 112 121 * else would access driver_data anyway. 113 122 */ 114 device->driver_data = uhci_hc; 123 device->driver_data = hcd; 124 125 ddf_fun_t *rh = NULL; 126 #define CHECK_RET_FINI_FREE_RETURN(ret, message...) \ 127 if (ret != EOK) { \ 128 usb_log_error(message); \ 129 if (hcd != NULL) {\ 130 uhci_fini(hcd); \ 131 free(hcd); \ 132 } \ 133 if (rh != NULL) \ 134 free(rh); \ 135 return ret; \ 136 } 137 138 /* It does no harm if we register this on polling */ 115 139 ret = register_interrupt_handler(device, irq, irq_handler, 116 &uhci_hc->interrupt_code); 117 if (ret != EOK) { 118 usb_log_error("Failed to register interrupt handler.\n"); 119 uhci_fini(uhci_hc); 120 free(uhci_hc); 121 return ret; 122 } 140 &hcd->interrupt_code); 141 CHECK_RET_FINI_FREE_RETURN(ret, 142 "Failed(%d) to register interrupt handler.\n", ret); 123 143 124 ddf_fun_t *rh;125 144 ret = setup_root_hub(&rh, device); 126 if (ret != EOK) { 127 usb_log_error("Failed to setup uhci root hub.\n"); 128 uhci_fini(uhci_hc); 129 free(uhci_hc); 130 return ret; 131 } 132 rh->driver_data = uhci_hc->ddf_instance; 145 CHECK_RET_FINI_FREE_RETURN(ret, 146 "Failed(%d) to setup UHCI root hub.\n", ret); 147 rh->driver_data = hcd->ddf_instance; 133 148 134 149 ret = ddf_fun_bind(rh); 135 if (ret != EOK) { 136 usb_log_error("Failed to register root hub.\n"); 137 uhci_fini(uhci_hc); 138 free(uhci_hc); 139 free(rh); 140 return ret; 141 } 150 CHECK_RET_FINI_FREE_RETURN(ret, 151 "Failed(%d) to register UHCI root hub.\n", ret); 142 152 143 153 return EOK; 154 #undef CHECK_RET_FINI_FREE_RETURN 144 155 } 145 156 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/pci.c
rac8285d r4c7c251 40 40 41 41 #include <usb/debug.h> 42 #include <pci_dev_iface.h> 42 43 43 44 #include "pci.h" … … 128 129 return enabled ? EOK : EIO; 129 130 } 131 /*----------------------------------------------------------------------------*/ 132 int pci_disable_legacy(ddf_dev_t *device) 133 { 134 assert(device); 135 int parent_phone = devman_parent_device_connect(device->handle, 136 IPC_FLAG_BLOCKING); 137 if (parent_phone < 0) { 138 return parent_phone; 139 } 140 141 /* See UHCI design guide for these values, 142 * write all WC bits in USB legacy register */ 143 sysarg_t address = 0xc0; 144 sysarg_t value = 0x8f00; 145 146 int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 147 IPC_M_CONFIG_SPACE_WRITE_16, address, value); 148 async_hangup(parent_phone); 149 150 return rc; 151 } 152 /*----------------------------------------------------------------------------*/ 130 153 /** 131 154 * @} -
uspace/drv/uhci-hcd/pci.h
rac8285d r4c7c251 40 40 int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 41 int pci_enable_interrupts(ddf_dev_t *); 42 int pci_disable_legacy(ddf_dev_t *); 42 43 43 44 #endif -
uspace/drv/uhci-hcd/uhci.c
rac8285d r4c7c251 90 90 .interfaces[USBHC_DEV_IFACE] = &uhci_iface, 91 91 }; 92 92 /*----------------------------------------------------------------------------*/ 93 93 static int uhci_init_transfer_lists(uhci_t *instance); 94 94 static int uhci_init_mem_structures(uhci_t *instance); … … 115 115 } else (void) 0 116 116 117 /* 118 * Create UHCI function. 119 */ 117 /* Create UHCI function. */ 120 118 instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci"); 121 119 ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK; 122 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to create UHCI device function.\n"); 120 CHECK_RET_DEST_FUN_RETURN(ret, 121 "Failed to create UHCI device function.\n"); 123 122 124 123 instance->ddf_instance->ops = &uhci_ops; … … 126 125 127 126 ret = ddf_fun_bind(instance->ddf_instance); 128 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to bind UHCI device function: %s.\n", 127 CHECK_RET_DEST_FUN_RETURN(ret, 128 "Failed(%d) to bind UHCI device function: %s.\n", 129 129 ret, str_error(ret)); 130 130 … … 132 132 regs_t *io; 133 133 ret = pio_enable(regs, reg_size, (void**)&io); 134 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to gain access to registers at %p: %s.\n", 134 CHECK_RET_DEST_FUN_RETURN(ret, 135 "Failed(%d) to gain access to registers at %p: %s.\n", 135 136 ret, str_error(ret), io); 136 137 instance->registers = io; 137 usb_log_debug("Device registers at %p(%u) accessible.\n", io, reg_size); 138 usb_log_debug("Device registers at %p(%u) accessible.\n", 139 io, reg_size); 138 140 139 141 ret = uhci_init_mem_structures(instance); 140 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to initialize UHCI memory structures.\n"); 142 CHECK_RET_DEST_FUN_RETURN(ret, 143 "Failed to initialize UHCI memory structures.\n"); 141 144 142 145 uhci_init_hw(instance); 143 144 instance->cleaner =fibril_create(uhci_interrupt_emulator, instance);146 instance->cleaner = 147 fibril_create(uhci_interrupt_emulator, instance); 145 148 fibril_add_ready(instance->cleaner); 146 149 … … 155 158 void uhci_init_hw(uhci_t *instance) 156 159 { 160 assert(instance); 161 157 162 /* reset everything, who knows what touched it before us */ 158 163 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET); … … 171 176 /* enable all interrupts, but resume interrupt */ 172 177 pio_write_16(&instance->registers->usbintr, 173 178 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 174 179 175 180 /* Start the hc with large(64B) packet FSBR */ … … 200 205 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 201 206 instance->interrupt_code.cmdcount = 202 207 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 203 208 } 204 209 … … 249 254 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 250 255 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 256 251 257 ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL"); 252 258 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 259 253 260 ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW"); 254 261 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 262 255 263 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 256 264 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); … … 292 300 low_speed, batch->transfer_type, batch->max_packet_size)) { 293 301 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 294 302 low_speed ? "LOW" : "FULL" , batch->transfer_type, 295 303 batch->max_packet_size); 296 304 return ENOTSUP; … … 309 317 { 310 318 assert(instance); 311 // if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)312 // return;313 // usb_log_debug2("UHCI interrupt: %X.\n", status);314 319 transfer_list_remove_finished(&instance->transfers_interrupt); 315 320 transfer_list_remove_finished(&instance->transfers_control_slow); … … 340 345 uhci_t *instance = (uhci_t*)arg; 341 346 assert(instance); 347 348 #define QH(queue) \ 349 instance->transfers_##queue.queue_head 350 342 351 while (1) { 343 352 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 344 353 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 345 const uint16_t intr = pio_read_16(&instance->registers->usbintr); 354 const uint16_t intr = 355 pio_read_16(&instance->registers->usbintr); 356 346 357 if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) { 347 358 usb_log_debug2("Command: %X Status: %X Intr: %x\n", … … 353 364 if (frame_list != addr_to_phys(instance->frame_list)) { 354 365 usb_log_debug("Framelist address: %p vs. %p.\n", 355 frame_list, addr_to_phys(instance->frame_list)); 356 } 366 frame_list, addr_to_phys(instance->frame_list)); 367 } 368 357 369 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 358 370 usb_log_debug2("Framelist item: %d \n", frnum ); 359 371 360 queue_head_t* qh = instance->transfers_interrupt.queue_head;361 362 if ( (instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) {372 uintptr_t expected_pa = instance->frame_list[frnum] & (~0xf); 373 uintptr_t real_pa = addr_to_phys(QH(interrupt)); 374 if (expected_pa != real_pa) { 363 375 usb_log_debug("Interrupt QH: %p vs. %p.\n", 364 instance->frame_list[frnum] & (~0xf), addr_to_phys(qh)); 365 } 366 367 if ((qh->next_queue & (~0xf)) 368 != (uintptr_t)addr_to_phys(instance->transfers_control_slow.queue_head)) { 369 usb_log_debug("Control Slow QH: %p vs. %p.\n", qh->next_queue & (~0xf), 370 addr_to_phys(instance->transfers_control_slow.queue_head)); 371 } 372 qh = instance->transfers_control_slow.queue_head; 373 374 if ((qh->next_queue & (~0xf)) 375 != (uintptr_t)addr_to_phys(instance->transfers_control_full.queue_head)) { 376 usb_log_debug("Control Full QH: %p vs. %p.\n", qh->next_queue & (~0xf), 377 addr_to_phys(instance->transfers_control_full.queue_head));\ 378 } 379 qh = instance->transfers_control_full.queue_head; 380 381 if ((qh->next_queue & (~0xf)) 382 != (uintptr_t)addr_to_phys(instance->transfers_bulk_full.queue_head)) { 383 usb_log_debug("Bulk QH: %p vs. %p.\n", qh->next_queue & (~0xf), 384 addr_to_phys(instance->transfers_bulk_full.queue_head)); 385 } 386 /* 387 uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 388 cmd |= UHCI_CMD_RUN_STOP; 389 pio_write_16(&instance->registers->usbcmd, cmd); 390 */ 376 expected_pa, real_pa); 377 } 378 379 expected_pa = QH(interrupt)->next_queue & (~0xf); 380 real_pa = addr_to_phys(QH(control_slow)); 381 if (expected_pa != real_pa) { 382 usb_log_debug("Control Slow QH: %p vs. %p.\n", 383 expected_pa, real_pa); 384 } 385 386 expected_pa = QH(control_slow)->next_queue & (~0xf); 387 real_pa = addr_to_phys(QH(control_full)); 388 if (expected_pa != real_pa) { 389 usb_log_debug("Control Full QH: %p vs. %p.\n", 390 expected_pa, real_pa); 391 } 392 393 expected_pa = QH(control_full)->next_queue & (~0xf); 394 real_pa = addr_to_phys(QH(bulk_full)); 395 if (expected_pa != real_pa ) { 396 usb_log_debug("Bulk QH: %p vs. %p.\n", 397 expected_pa, real_pa); 398 } 391 399 async_usleep(UHCI_DEBUGER_TIMEOUT); 392 400 } 393 401 return 0; 402 #undef QH 394 403 } 395 404 /*----------------------------------------------------------------------------*/ 396 405 bool allowed_usb_packet( 397 406 bool low_speed, usb_transfer_type_t transfer, size_t size) 398 407 { 399 408 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 400 switch(transfer) { 401 case USB_TRANSFER_ISOCHRONOUS: 402 return (!low_speed && size < 1024); 403 case USB_TRANSFER_INTERRUPT: 404 return size <= (low_speed ? 8 : 64); 405 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 406 return (size <= (low_speed ? 8 : 64)); 407 case USB_TRANSFER_BULK: /* device specifies its own max size */ 408 return (!low_speed && size <= 64); 409 switch(transfer) 410 { 411 case USB_TRANSFER_ISOCHRONOUS: 412 return (!low_speed && size < 1024); 413 case USB_TRANSFER_INTERRUPT: 414 return size <= (low_speed ? 8 : 64); 415 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 416 return (size <= (low_speed ? 8 : 64)); 417 case USB_TRANSFER_BULK: /* device specifies its own max size */ 418 return (!low_speed && size <= 64); 409 419 } 410 420 return false; -
uspace/lib/c/include/ipc/dev_iface.h
rac8285d r4c7c251 38 38 CHAR_DEV_IFACE, 39 39 40 /** Interface provided by any PCI device. */ 41 PCI_DEV_IFACE, 42 40 43 /** Interface provided by any USB device. */ 41 44 USB_DEV_IFACE, -
uspace/lib/drv/Makefile
rac8285d r4c7c251 38 38 generic/remote_hw_res.c \ 39 39 generic/remote_usb.c \ 40 generic/remote_pci.c \ 40 41 generic/remote_usbhc.c 41 42 -
uspace/lib/drv/generic/dev_iface.c
rac8285d r4c7c251 43 43 #include "remote_usb.h" 44 44 #include "remote_usbhc.h" 45 #include "remote_pci.h" 45 46 46 47 static iface_dipatch_table_t remote_ifaces = { … … 48 49 &remote_hw_res_iface, 49 50 &remote_char_dev_iface, 51 &remote_pci_iface, 50 52 &remote_usb_iface, 51 53 &remote_usbhc_iface
Note:
See TracChangeset
for help on using the changeset viewer.