Changeset a81a1d09 in mainline for uspace/drv
- Timestamp:
- 2011-05-11T16:49:28Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 19387b61
- Parents:
- e1dbcbc (diff), 9212f8a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/drv
- Files:
-
- 57 edited
-
ehci-hcd/Makefile (modified) (1 diff)
-
ehci-hcd/ehci-hcd.ma (modified) (1 diff)
-
ehci-hcd/hc_iface.c (modified) (2 diffs)
-
ehci-hcd/main.c (modified) (1 diff)
-
ehci-hcd/pci.c (modified) (5 diffs)
-
ohci/Makefile (modified) (1 diff)
-
ohci/hc.c (modified) (12 diffs)
-
ohci/hc.h (modified) (2 diffs)
-
ohci/hw_struct/endpoint_descriptor.h (modified) (1 diff)
-
ohci/hw_struct/transfer_descriptor.c (modified) (1 diff)
-
ohci/hw_struct/transfer_descriptor.h (modified) (1 diff)
-
ohci/iface.c (modified) (2 diffs)
-
ohci/main.c (modified) (3 diffs)
-
ohci/ohci.c (modified) (9 diffs)
-
ohci/ohci.h (modified) (1 diff)
-
ohci/ohci.ma (modified) (1 diff)
-
ohci/ohci_regs.h (modified) (1 diff)
-
ohci/pci.c (modified) (4 diffs)
-
ohci/root_hub.c (modified) (50 diffs)
-
ohci/root_hub.h (modified) (1 diff)
-
uhci-hcd/Makefile (modified) (1 diff)
-
uhci-hcd/hc.c (modified) (2 diffs)
-
uhci-hcd/hc.h (modified) (1 diff)
-
uhci-hcd/hw_struct/queue_head.h (modified) (1 diff)
-
uhci-hcd/hw_struct/transfer_descriptor.c (modified) (1 diff)
-
uhci-hcd/iface.c (modified) (2 diffs)
-
uhci-hcd/main.c (modified) (2 diffs)
-
uhci-hcd/uhci.c (modified) (8 diffs)
-
uhci-hcd/uhci.h (modified) (1 diff)
-
uhci-rhd/Makefile (modified) (1 diff)
-
uhci-rhd/port.c (modified) (5 diffs)
-
usbflbk/Makefile (modified) (1 diff)
-
usbhid/Makefile (modified) (1 diff)
-
usbhid/generic/hiddev.c (modified) (2 diffs)
-
usbhid/generic/hiddev.h (modified) (1 diff)
-
usbhid/kbd/kbddev.c (modified) (7 diffs)
-
usbhid/lgtch-ultrax/keymap.c (modified) (1 diff)
-
usbhid/lgtch-ultrax/lgtch-ultrax.c (modified) (8 diffs)
-
usbhid/lgtch-ultrax/lgtch-ultrax.h (modified) (1 diff)
-
usbhid/main.c (modified) (2 diffs)
-
usbhid/mouse/mousedev.c (modified) (11 diffs)
-
usbhid/mouse/mousedev.h (modified) (1 diff)
-
usbhid/subdrivers.c (modified) (2 diffs)
-
usbhid/usbhid.c (modified) (5 diffs)
-
usbhid/usbhid.h (modified) (3 diffs)
-
usbhub/Makefile (modified) (1 diff)
-
usbhub/ports.c (modified) (4 diffs)
-
usbhub/usbhub.c (modified) (2 diffs)
-
usbkbd/Makefile (modified) (1 diff)
-
usbkbd/kbddev.c (modified) (1 diff)
-
usbmast/Makefile (modified) (1 diff)
-
usbmid/Makefile (modified) (1 diff)
-
usbmouse/Makefile (modified) (1 diff)
-
vhc/Makefile (modified) (2 diffs)
-
vhc/connhost.c (modified) (2 diffs)
-
vhc/main.c (modified) (1 diff)
-
vhc/transfer.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ehci-hcd/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBHOST_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = ehci-hcd 33 41 -
uspace/drv/ehci-hcd/ehci-hcd.ma
re1dbcbc ra81a1d09 2 2 10 pci/ven=1002&dev=4386 3 3 10 pci/ven=1002&dev=4396 4 10 pci/ven=1002&dev=4373 4 5 10 pci/ven=1022&dev=7463 5 6 10 pci/ven=1022&dev=7808 -
uspace/drv/ehci-hcd/hc_iface.c
re1dbcbc ra81a1d09 106 106 } 107 107 108 /** Find device handle by USB address. 109 * 110 * @param[in] fun DDF function that was called. 111 * @param[in] address Address in question. 112 * @param[out] handle Where to store device handle if found. 113 * @return Error code. 114 */ 115 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 116 devman_handle_t *handle) 117 { 118 UNSUPPORTED("find_by_address"); 119 120 return ENOTSUP; 121 } 122 108 123 /** Release previously requested address. 109 124 * … … 321 336 .request_address = request_address, 322 337 .bind_address = bind_address, 338 .find_by_address = find_by_address, 323 339 .release_address = release_address, 324 340 -
uspace/drv/ehci-hcd/main.c
re1dbcbc ra81a1d09 97 97 } 98 98 hc_fun->ops = &hc_ops; 99 99 100 ret = ddf_fun_bind(hc_fun); 100 101 101 CHECK_RET_RETURN(ret, 102 102 "Failed to bind EHCI function: %s.\n", 103 str_error(ret)); 104 ret = ddf_fun_add_to_class(hc_fun, USB_HC_DDF_CLASS_NAME); 105 CHECK_RET_RETURN(ret, 106 "Failed to add EHCI to HC class: %s.\n", 103 107 str_error(ret)); 104 108 -
uspace/drv/ehci-hcd/pci.c
re1dbcbc ra81a1d09 54 54 55 55 #define CMD_OFFSET 0x0 56 #define CONFIGFLAG_OFFSET 0x40 56 #define STS_OFFSET 0x4 57 #define CFG_OFFSET 0x40 57 58 58 59 #define USBCMD_RUN 1 … … 186 187 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read PCI config space.\n", 187 188 ret); 188 usb_log_info("Register space BAR at %p:%" PRIxn ".\n", (void *) address, value); 189 usb_log_info("Register space BAR at %p:%" PRIxn ".\n", 190 (void *) address, value); 189 191 190 192 /* clear lower byte, it's not part of the BASE address */ … … 263 265 * It would prevent pre-OS code from interfering. */ 264 266 ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 265 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 0); 267 IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 268 0xe0000000); 266 269 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 267 usb_log_debug("Zeroed USBLEGCTLSTS register.\n");268 270 269 271 /* Read again Legacy Support and Control register */ … … 290 292 volatile uint32_t *usbcmd = 291 293 (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET); 294 volatile uint32_t *usbsts = 295 (uint32_t*)((uint8_t*)registers + operation_offset + STS_OFFSET); 292 296 volatile uint32_t *usbconfigured = 293 (uint32_t*)((uint8_t*)registers + operation_offset 294 + CONFIGFLAG_OFFSET); 297 (uint32_t*)((uint8_t*)registers + operation_offset + CFG_OFFSET); 295 298 usb_log_debug("USBCMD value: %x.\n", *usbcmd); 296 299 if (*usbcmd & USBCMD_RUN) { 297 300 *usbcmd = 0; 301 while (!(*usbsts & (1 << 12))); /*wait until hc is halted */ 298 302 *usbconfigured = 0; 299 303 usb_log_info("EHCI turned off.\n"); … … 301 305 usb_log_info("EHCI was not running.\n"); 302 306 } 307 usb_log_debug("Registers: %x(0x00080000):%x(0x00001000):%x(0x0).\n", 308 *usbcmd, *usbsts, *usbconfigured); 303 309 304 310 async_hangup(parent_phone); -
uspace/drv/ohci/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I$(LIBUSB_PREFIX)/include \ 38 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBUSBHOST_PREFIX)/include \ 40 -I$(LIBDRV_PREFIX)/include 41 32 42 BINARY = ohci 33 43 -
uspace/drv/ohci/hc.c
re1dbcbc ra81a1d09 40 40 #include <usb/usb.h> 41 41 #include <usb/ddfiface.h> 42 #include <usb/usbdevice.h>43 42 44 43 #include "hc.h" 45 44 #include "hcd_endpoint.h" 46 45 46 #define OHCI_USED_INTERRUPTS \ 47 (I_SO | I_WDH | I_UE | I_RHSC) 47 48 static int interrupt_emulator(hc_t *instance); 48 49 static void hc_gain_control(hc_t *instance); 49 static void hc_init_hw(hc_t *instance);50 50 static int hc_init_transfer_lists(hc_t *instance); 51 51 static int hc_init_memory(hc_t *instance); … … 90 90 usb_log_error("Failed add root hub match-id.\n"); 91 91 } 92 ret = ddf_fun_bind(hub_fun); 92 93 return ret; 93 94 } 94 95 /*----------------------------------------------------------------------------*/ 95 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 96 uintptr_t regs, size_t reg_size, bool interrupts) 96 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts) 97 97 { 98 98 assert(instance); … … 109 109 ret, str_error(ret)); 110 110 111 list_initialize(&instance->pending_batches); 111 112 usb_device_keeper_init(&instance->manager); 112 113 ret = usb_endpoint_manager_init(&instance->ep_manager, … … 115 116 str_error(ret)); 116 117 117 hc_gain_control(instance);118 118 ret = hc_init_memory(instance); 119 119 CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n", 120 120 str_error(ret)); 121 hc_init_hw(instance); 121 #undef CHECK_RET_RETURN 122 123 124 // hc_init_hw(instance); 125 hc_gain_control(instance); 122 126 fibril_mutex_initialize(&instance->guard); 123 127 … … 130 134 } 131 135 132 list_initialize(&instance->pending_batches);133 #undef CHECK_RET_RETURN134 136 return EOK; 135 137 } … … 285 287 { 286 288 assert(instance); 287 if ((status & ~IS_SF) == 0) /* ignore sof status */ 289 usb_log_debug("OHCI(%p) interrupt: %x.\n", instance, status); 290 if ((status & ~I_SF) == 0) /* ignore sof status */ 288 291 return; 289 if (status & I S_RHSC)292 if (status & I_RHSC) 290 293 rh_interrupt(&instance->rh); 291 294 292 usb_log_debug("OHCI interrupt: %x.\n", status); 293 294 if (status & IS_WDH) { 295 296 if (status & I_WDH) { 295 297 fibril_mutex_lock(&instance->guard); 296 298 usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca, … … 332 334 { 333 335 assert(instance); 336 usb_log_debug("Requesting OHCI control.\n"); 334 337 /* Turn off legacy emulation */ 335 338 volatile uint32_t *ohci_emulation_reg = 336 339 (uint32_t*)((char*)instance->registers + 0x100); 337 340 usb_log_debug("OHCI legacy register %p: %x.\n", 338 ohci_emulation_reg, *ohci_emulation_reg); 339 *ohci_emulation_reg = 0; 341 ohci_emulation_reg, *ohci_emulation_reg); 342 /* Do not change A20 state */ 343 *ohci_emulation_reg &= 0x100; 344 usb_log_debug("OHCI legacy register %p: %x.\n", 345 ohci_emulation_reg, *ohci_emulation_reg); 340 346 341 347 /* Interrupt routing enabled => smm driver is active */ … … 347 353 } 348 354 usb_log_info("SMM driver: Ownership taken.\n"); 355 instance->registers->control &= (C_HCFS_RESET << C_HCFS_SHIFT); 356 async_usleep(50000); 349 357 return; 350 358 } … … 372 380 } 373 381 /*----------------------------------------------------------------------------*/ 374 void hc_ init_hw(hc_t *instance)382 void hc_start_hw(hc_t *instance) 375 383 { 376 384 /* OHCI guide page 42 */ … … 421 429 instance->registers->control); 422 430 423 /* Disable interrupts */ 424 instance->registers->interrupt_disable = I_SF | I_OC; 425 usb_log_debug2("Disabling interrupts: %x.\n", 426 instance->registers->interrupt_disable); 427 instance->registers->interrupt_disable = I_MI; 431 /* Enable interrupts */ 432 instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS; 428 433 usb_log_debug2("Enabled interrupts: %x.\n", 429 434 instance->registers->interrupt_enable); 435 instance->registers->interrupt_enable = I_MI; 430 436 431 437 /* Set periodic start to 90% */ … … 473 479 { 474 480 assert(instance); 481 482 bzero(&instance->rh, sizeof(instance->rh)); 475 483 /* Init queues */ 476 484 hc_init_transfer_lists(instance); … … 492 500 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa); 493 501 502 /* Init interrupt code */ 503 instance->interrupt_code.cmds = instance->interrupt_commands; 504 { 505 /* Read status register */ 506 instance->interrupt_commands[0].cmd = CMD_MEM_READ_32; 507 instance->interrupt_commands[0].dstarg = 1; 508 instance->interrupt_commands[0].addr = 509 (void*)&instance->registers->interrupt_status; 510 511 /* Test whether we are the interrupt cause */ 512 instance->interrupt_commands[1].cmd = CMD_BTEST; 513 instance->interrupt_commands[1].value = 514 OHCI_USED_INTERRUPTS; 515 instance->interrupt_commands[1].srcarg = 1; 516 instance->interrupt_commands[1].dstarg = 2; 517 518 /* Predicate cleaning and accepting */ 519 instance->interrupt_commands[2].cmd = CMD_PREDICATE; 520 instance->interrupt_commands[2].value = 2; 521 instance->interrupt_commands[2].srcarg = 2; 522 523 /* Write clean status register */ 524 instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32; 525 instance->interrupt_commands[3].srcarg = 1; 526 instance->interrupt_commands[3].addr = 527 (void*)&instance->registers->interrupt_status; 528 529 /* Accept interrupt */ 530 instance->interrupt_commands[4].cmd = CMD_ACCEPT; 531 532 instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS; 533 } 534 494 535 return EOK; 495 536 } -
uspace/drv/ohci/hc.h
re1dbcbc ra81a1d09 51 51 #include "hw_struct/hcca.h" 52 52 53 #define OHCI_NEEDED_IRQ_COMMANDS 5 54 53 55 typedef struct hc { 54 56 ohci_regs_t *registers; … … 65 67 fid_t interrupt_emulator; 66 68 fibril_mutex_t guard; 69 70 /** Code to be executed in kernel interrupt handler */ 71 irq_code_t interrupt_code; 72 73 /** Commands that form interrupt code */ 74 irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS]; 67 75 } hc_t; 68 76 69 77 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 70 78 71 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 72 uintptr_t regs, size_t reg_size, bool interrupts); 79 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); 80 81 void hc_start_hw(hc_t *instance); 73 82 74 83 /** Safely dispose host controller internal structures -
uspace/drv/ohci/hw_struct/endpoint_descriptor.h
re1dbcbc ra81a1d09 40 40 #include <usb/host/endpoint.h> 41 41 42 #include " utils/malloc32.h"42 #include "../utils/malloc32.h" 43 43 #include "transfer_descriptor.h" 44 44 -
uspace/drv/ohci/hw_struct/transfer_descriptor.c
re1dbcbc ra81a1d09 33 33 */ 34 34 #include <usb/usb.h> 35 #include "utils/malloc32.h"36 37 35 #include "transfer_descriptor.h" 38 36 -
uspace/drv/ohci/hw_struct/transfer_descriptor.h
re1dbcbc ra81a1d09 37 37 #include <bool.h> 38 38 #include <stdint.h> 39 #include " utils/malloc32.h"39 #include "../utils/malloc32.h" 40 40 41 41 #include "completion_codes.h" -
uspace/drv/ohci/iface.c
re1dbcbc ra81a1d09 122 122 return EOK; 123 123 } 124 125 126 /** Find device handle by address interface function. 127 * 128 * @param[in] fun DDF function that was called. 129 * @param[in] address Address in question. 130 * @param[out] handle Where to store device handle if found. 131 * @return Error code. 132 */ 133 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 134 devman_handle_t *handle) 135 { 136 assert(fun); 137 hc_t *hc = fun_to_hc(fun); 138 assert(hc); 139 bool found = 140 usb_device_keeper_find_by_address(&hc->manager, address, handle); 141 return found ? EOK : ENOENT; 142 } 143 124 144 /*----------------------------------------------------------------------------*/ 125 145 /** Release address interface function … … 402 422 .request_address = request_address, 403 423 .bind_address = bind_address, 424 .find_by_address = find_by_address, 404 425 .release_address = release_address, 405 426 -
uspace/drv/ohci/main.c
re1dbcbc ra81a1d09 43 43 #define NAME "ohci" 44 44 45 static int ohci_add_device(ddf_dev_t *device); 45 /** Initializes a new ddf driver instance of OHCI hcd. 46 * 47 * @param[in] device DDF instance of the device to initialize. 48 * @return Error code. 49 */ 50 static int ohci_add_device(ddf_dev_t *device) 51 { 52 usb_log_debug("ohci_add_device() called\n"); 53 assert(device); 54 55 int ret = device_setup_ohci(device); 56 if (ret != EOK) { 57 usb_log_error("Failed to initialize OHCI driver: %s.\n", 58 str_error(ret)); 59 return ret; 60 } 61 usb_log_info("Controlling new OHCI device '%s'.\n", device->name); 62 63 return EOK; 64 } 46 65 /*----------------------------------------------------------------------------*/ 47 66 static driver_ops_t ohci_driver_ops = { … … 53 72 .driver_ops = &ohci_driver_ops 54 73 }; 55 /*----------------------------------------------------------------------------*/56 /** Initializes a new ddf driver instance of OHCI hcd.57 *58 * @param[in] device DDF instance of the device to initialize.59 * @return Error code.60 */61 int ohci_add_device(ddf_dev_t *device)62 {63 usb_log_debug("ohci_add_device() called\n");64 assert(device);65 ohci_t *ohci = malloc(sizeof(ohci_t));66 if (ohci == NULL) {67 usb_log_error("Failed to allocate OHCI driver.\n");68 return ENOMEM;69 }70 71 int ret = ohci_init(ohci, device);72 if (ret != EOK) {73 usb_log_error("Failed to initialize OHCI driver: %s.\n",74 str_error(ret));75 return ret;76 }77 device->driver_data = ohci;78 79 usb_log_info("Controlling new OHCI device `%s'.\n", device->name);80 81 return EOK;82 }83 74 /*----------------------------------------------------------------------------*/ 84 75 /** Initializes global driver structures (NONE). … … 93 84 { 94 85 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 95 sleep(5);96 86 return ddf_driver_main(&ohci_driver); 97 87 } -
uspace/drv/ohci/ohci.c
re1dbcbc ra81a1d09 44 44 #include "iface.h" 45 45 #include "pci.h" 46 #include "hc.h" 47 #include "root_hub.h" 48 49 typedef struct ohci { 50 ddf_fun_t *hc_fun; 51 ddf_fun_t *rh_fun; 52 53 hc_t hc; 54 rh_t rh; 55 } ohci_t; 56 57 static inline ohci_t * dev_to_ohci(ddf_dev_t *dev) 58 { 59 assert(dev); 60 assert(dev->driver_data); 61 return dev->driver_data; 62 } 46 63 47 64 /** IRQ handling callback, identifies device … … 53 70 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 54 71 { 55 assert(dev); 56 hc_t *hc = &((ohci_t*)dev->driver_data)->hc; 57 uint16_t status = IPC_GET_ARG1(*call); 72 hc_t *hc = &dev_to_ohci(dev)->hc; 58 73 assert(hc); 74 const uint16_t status = IPC_GET_ARG1(*call); 59 75 hc_interrupt(hc, status); 60 76 } … … 70 86 { 71 87 assert(fun); 72 usb_device_keeper_t *manager = & ((ohci_t*)fun->dev->driver_data)->hc.manager;88 usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager; 73 89 74 90 usb_address_t addr = usb_device_keeper_find(manager, handle); … … 93 109 ddf_fun_t *fun, devman_handle_t *handle) 94 110 { 95 assert(handle); 96 ddf_fun_t *hc_fun = ((ohci_t*)fun->dev->driver_data)->hc_fun; 97 assert(hc_fun != NULL); 98 99 *handle = hc_fun->handle; 111 assert(fun); 112 ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun; 113 assert(hc_fun); 114 115 if (handle != NULL) 116 *handle = hc_fun->handle; 100 117 return EOK; 101 118 } 102 119 /*----------------------------------------------------------------------------*/ 103 /** This iface is generic for both RH and HC.*/120 /** Root hub USB interface */ 104 121 static usb_iface_t usb_iface = { 105 122 .get_hc_handle = usb_iface_get_hc_handle, … … 107 124 }; 108 125 /*----------------------------------------------------------------------------*/ 126 /** Standard USB HC options (HC interface) */ 109 127 static ddf_dev_ops_t hc_ops = { 110 128 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 111 129 }; 112 130 /*----------------------------------------------------------------------------*/ 131 /** Standard USB RH options (RH interface) */ 113 132 static ddf_dev_ops_t rh_ops = { 114 133 .interfaces[USB_DEV_IFACE] = &usb_iface, … … 117 136 /** Initialize hc and rh ddf structures and their respective drivers. 118 137 * 138 * @param[in] device DDF instance of the device to use. 119 139 * @param[in] instance OHCI structure to use. 120 * @param[in] device DDF instance of the device to use.121 140 * 122 141 * This function does all the preparatory work for hc and rh drivers: … … 126 145 * - registers interrupt handler 127 146 */ 128 int ohci_init(ohci_t *instance, ddf_dev_t *device) 129 { 130 assert(instance); 131 instance->hc_fun = NULL; 147 int device_setup_ohci(ddf_dev_t *device) 148 { 149 ohci_t *instance = malloc(sizeof(ohci_t)); 150 if (instance == NULL) { 151 usb_log_error("Failed to allocate OHCI driver.\n"); 152 return ENOMEM; 153 } 154 155 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 156 if (ret != EOK) { \ 157 if (instance->hc_fun) { \ 158 instance->hc_fun->ops = NULL; \ 159 instance->hc_fun->driver_data = NULL; \ 160 ddf_fun_destroy(instance->hc_fun); \ 161 } \ 162 if (instance->rh_fun) { \ 163 instance->rh_fun->ops = NULL; \ 164 instance->rh_fun->driver_data = NULL; \ 165 ddf_fun_destroy(instance->rh_fun); \ 166 } \ 167 free(instance); \ 168 usb_log_error(message); \ 169 return ret; \ 170 } else (void)0 171 132 172 instance->rh_fun = NULL; 133 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 134 if (ret != EOK) { \ 135 usb_log_error(message); \ 136 if (instance->hc_fun) \ 137 ddf_fun_destroy(instance->hc_fun); \ 138 if (instance->rh_fun) \ 139 ddf_fun_destroy(instance->rh_fun); \ 140 return ret; \ 141 } 142 143 uintptr_t mem_reg_base = 0; 144 size_t mem_reg_size = 0; 173 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 174 int ret = instance->hc_fun ? EOK : ENOMEM; 175 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n"); 176 instance->hc_fun->ops = &hc_ops; 177 instance->hc_fun->driver_data = &instance->hc; 178 179 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh"); 180 ret = instance->rh_fun ? EOK : ENOMEM; 181 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n"); 182 instance->rh_fun->ops = &rh_ops; 183 184 uintptr_t reg_base = 0; 185 size_t reg_size = 0; 145 186 int irq = 0; 146 187 147 int ret = 148 pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq); 149 CHECK_RET_DEST_FUN_RETURN(ret, 188 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 189 CHECK_RET_DEST_FREE_RETURN(ret, 150 190 "Failed to get memory addresses for %" PRIun ": %s.\n", 151 191 device->handle, str_error(ret)); 152 192 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 153 (void *) mem_reg_base, mem_reg_size, irq); 154 155 ret = pci_disable_legacy(device); 156 CHECK_RET_DEST_FUN_RETURN(ret, 157 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 193 (void *) reg_base, reg_size, irq); 158 194 159 195 bool interrupts = false; 160 196 #ifdef CONFIG_USBHC_NO_INTERRUPTS 161 usb_log_warning("Interrupts disabled in OS config, " \197 usb_log_warning("Interrupts disabled in OS config, " 162 198 "falling back to polling.\n"); 163 199 #else … … 166 202 usb_log_warning("Failed to enable interrupts: %s.\n", 167 203 str_error(ret)); 168 usb_log_info("HW interrupts not available, " \204 usb_log_info("HW interrupts not available, " 169 205 "falling back to polling.\n"); 170 206 } else { … … 174 210 #endif 175 211 176 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 177 ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 178 CHECK_RET_DEST_FUN_RETURN(ret, 179 "Failed(%d) to create HC function.\n", ret); 180 181 ret = hc_init(&instance->hc, instance->hc_fun, device, 182 mem_reg_base, mem_reg_size, interrupts); 183 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret); 184 instance->hc_fun->ops = &hc_ops; 185 instance->hc_fun->driver_data = &instance->hc; 212 ret = hc_init(&instance->hc, reg_base, reg_size, interrupts); 213 CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret); 214 215 #define CHECK_RET_FINI_RETURN(ret, message...) \ 216 if (ret != EOK) { \ 217 hc_fini(&instance->hc); \ 218 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 219 } else (void)0 220 221 /* It does no harm if we register this on polling */ 222 ret = register_interrupt_handler(device, irq, irq_handler, 223 &instance->hc.interrupt_code); 224 CHECK_RET_FINI_RETURN(ret, 225 "Failed(%d) to register interrupt handler.\n", ret); 226 186 227 ret = ddf_fun_bind(instance->hc_fun); 187 CHECK_RET_ DEST_FUN_RETURN(ret,228 CHECK_RET_FINI_RETURN(ret, 188 229 "Failed(%d) to bind OHCI device function: %s.\n", 189 230 ret, str_error(ret)); 190 #undef CHECK_RET_HC_RETURN 191 192 #define CHECK_RET_FINI_RETURN(ret, message...) \ 193 if (ret != EOK) { \ 194 usb_log_error(message); \ 195 if (instance->hc_fun) \ 196 ddf_fun_destroy(instance->hc_fun); \ 197 if (instance->rh_fun) \ 198 ddf_fun_destroy(instance->rh_fun); \ 199 hc_fini(&instance->hc); \ 200 return ret; \ 201 } 202 203 /* It does no harm if we register this on polling */ 204 ret = register_interrupt_handler(device, irq, irq_handler, NULL); 231 232 ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME); 205 233 CHECK_RET_FINI_RETURN(ret, 206 "Failed(%d) to register interrupt handler.\n", ret); 207 208 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh"); 209 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 210 CHECK_RET_FINI_RETURN(ret, 211 "Failed(%d) to create root hub function.\n", ret); 212 234 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 235 236 device->driver_data = instance; 237 238 hc_start_hw(&instance->hc); 213 239 hc_register_hub(&instance->hc, instance->rh_fun); 214 215 instance->rh_fun->ops = &rh_ops;216 instance->rh_fun->driver_data = NULL;217 ret = ddf_fun_bind(instance->rh_fun);218 CHECK_RET_FINI_RETURN(ret,219 "Failed(%d) to register OHCI root hub.\n", ret);220 221 240 return EOK; 241 242 #undef CHECK_RET_DEST_FUN_RETURN 222 243 #undef CHECK_RET_FINI_RETURN 223 244 } -
uspace/drv/ohci/ohci.h
re1dbcbc ra81a1d09 38 38 #include <ddf/driver.h> 39 39 40 #include "hc.h" 41 #include "root_hub.h" 42 43 typedef struct ohci { 44 ddf_fun_t *hc_fun; 45 ddf_fun_t *rh_fun; 46 47 hc_t hc; 48 rh_t rh; 49 } ohci_t; 50 51 int ohci_init(ohci_t *instance, ddf_dev_t *device); 40 int device_setup_ohci(ddf_dev_t *device); 52 41 53 42 #endif -
uspace/drv/ohci/ohci.ma
re1dbcbc ra81a1d09 1 1 10 pci/ven=106b&dev=003f 2 2 10 pci/ven=10de&dev=0aa5 3 10 pci/ven=10de&dev=0aa5 3 4 10 pci/ven=1002&dev=4374 5 10 pci/ven=1002&dev=4375 6 7 10 pci/ven=1002&dev=4387 8 10 pci/ven=1002&dev=4388 9 10 pci/ven=1002&dev=4389 10 10 pci/ven=1002&dev=438a 11 10 pci/ven=1002&dev=438b -
uspace/drv/ohci/ohci_regs.h
re1dbcbc ra81a1d09 72 72 #define CS_SOC_SHIFT (16) 73 73 74 /** Interupt enable/disable/status, 75 * reads give the same value, 76 * writing causes enable/disable, 77 * status is write-clean (writing 1 clears the bit*/ 74 78 volatile uint32_t interrupt_status; 75 #define IS_SO (1 << 0) /* Scheduling overrun */76 #define IS_WDH (1 << 1) /* Write-back done head */77 #define IS_SF (1 << 2) /* Start of frame */78 #define IS_RD (1 << 3) /* Resume detected */79 #define IS_UE (1 << 4) /* Unrecoverable error */80 #define IS_FNO (1 << 5) /* Frame number overflow */81 #define IS_RHSC (1 << 6) /* Root hub status change */82 #define IS_OC (1 << 30) /* Ownership change */83 84 /** Interupt enable/disable, reads give the same value, writing causes85 * enable/disable */86 79 volatile uint32_t interrupt_enable; 87 80 volatile uint32_t interrupt_disable; -
uspace/drv/ohci/pci.c
re1dbcbc ra81a1d09 47 47 #include "pci.h" 48 48 49 #define PAGE_SIZE_MASK 0xfffff00050 51 #define HCC_PARAMS_OFFSET 0x852 #define HCC_PARAMS_EECP_MASK 0xff53 #define HCC_PARAMS_EECP_OFFSET 854 55 #define CMD_OFFSET 0x056 #define CONFIGFLAG_OFFSET 0x4057 58 #define USBCMD_RUN 159 60 #define USBLEGSUP_OFFSET 061 #define USBLEGSUP_BIOS_CONTROL (1 << 16)62 #define USBLEGSUP_OS_CONTROL (1 << 24)63 #define USBLEGCTLSTS_OFFSET 464 65 #define DEFAULT_WAIT 1000066 #define WAIT_STEP 1067 68 49 /** Get address of registers and IRQ for given device. 69 50 * … … 77 58 uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no) 78 59 { 79 assert(dev != NULL); 60 assert(dev); 61 assert(mem_reg_address); 62 assert(mem_reg_size); 63 assert(irq_no); 80 64 81 65 int parent_phone = devman_parent_device_connect(dev->handle, … … 146 130 int pci_enable_interrupts(ddf_dev_t *device) 147 131 { 148 return ENOTSUP;149 132 int parent_phone = 150 133 devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING); … … 156 139 return enabled ? EOK : EIO; 157 140 } 158 /*----------------------------------------------------------------------------*/159 /** Implements BIOS handoff routine as decribed in OHCI spec160 *161 * @param[in] device Device asking for interrupts162 * @return Error code.163 */164 int pci_disable_legacy(ddf_dev_t *device)165 {166 /* TODO: implement */167 return EOK;168 }169 /*----------------------------------------------------------------------------*/170 141 /** 171 142 * @} -
uspace/drv/ohci/root_hub.c
re1dbcbc ra81a1d09 45 45 46 46 /** 47 * standart device descriptor for ohci root hub47 * standart device descriptor for ohci root hub 48 48 */ 49 49 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = { … … 69 69 */ 70 70 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = { 71 /// \TODO some values are default or guessed72 71 .attributes = 1 << 7, 73 72 .configuration_number = 1, … … 87 86 .endpoint_count = 1, 88 87 .interface_class = USB_CLASS_HUB, 89 /// \TODO is this correct?90 88 .interface_number = 1, 91 89 .interface_protocol = 0, … … 107 105 }; 108 106 107 /** 108 * bitmask of hub features that are valid to be cleared 109 */ 109 110 static const uint32_t hub_clear_feature_valid_mask = 110 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) |111 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) | 111 112 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 112 113 114 /** 115 * bitmask of hub features that are cleared by writing 1 (and not 0) 116 */ 113 117 static const uint32_t hub_clear_feature_by_writing_one_mask = 114 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 115 118 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 119 120 /** 121 * bitmask of hub features that are valid to be set 122 */ 116 123 static const uint32_t hub_set_feature_valid_mask = 117 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) |124 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) | 118 125 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 119 126 120 127 /** 128 * bitmask of hub features that are set by writing 1 and cleared by writing 0 129 */ 121 130 static const uint32_t hub_set_feature_direct_mask = 122 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 123 131 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 132 133 /** 134 * bitmask of port features that are valid to be set 135 */ 124 136 static const uint32_t port_set_feature_valid_mask = 125 (1 << USB_HUB_FEATURE_PORT_ENABLE) |137 (1 << USB_HUB_FEATURE_PORT_ENABLE) | 126 138 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 127 139 (1 << USB_HUB_FEATURE_PORT_RESET) | 128 140 (1 << USB_HUB_FEATURE_PORT_POWER); 129 141 142 /** 143 * bitmask of port features that can be cleared 144 */ 130 145 static const uint32_t port_clear_feature_valid_mask = 131 (1 << USB_HUB_FEATURE_PORT_CONNECTION) |146 (1 << USB_HUB_FEATURE_PORT_CONNECTION) | 132 147 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 133 148 (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) | … … 141 156 //USB_HUB_FEATURE_PORT_LOW_SPEED 142 157 158 /** 159 * bitmask with port status changes 160 */ 143 161 static const uint32_t port_status_change_mask = 144 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) |145 (1 << USB_HUB_FEATURE_C_PORT_ENABLE) |146 (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) |147 (1 << USB_HUB_FEATURE_C_PORT_RESET) |148 (1 << USB_HUB_FEATURE_C_PORT_SUSPEND);162 (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) | 163 (1 << USB_HUB_FEATURE_C_PORT_ENABLE) | 164 (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) | 165 (1 << USB_HUB_FEATURE_C_PORT_RESET) | 166 (1 << USB_HUB_FEATURE_C_PORT_SUSPEND); 149 167 150 168 … … 154 172 155 173 static int process_get_port_status_request(rh_t *instance, uint16_t port, 156 usb_transfer_batch_t * request);174 usb_transfer_batch_t * request); 157 175 158 176 static int process_get_hub_status_request(rh_t *instance, 159 usb_transfer_batch_t * request);177 usb_transfer_batch_t * request); 160 178 161 179 static int process_get_status_request(rh_t *instance, 162 usb_transfer_batch_t * request);180 usb_transfer_batch_t * request); 163 181 164 182 static void create_interrupt_mask_in_instance(rh_t *instance); 165 183 166 184 static int process_get_descriptor_request(rh_t *instance, 167 usb_transfer_batch_t *request);185 usb_transfer_batch_t *request); 168 186 169 187 static int process_get_configuration_request(rh_t *instance, 170 usb_transfer_batch_t *request);188 usb_transfer_batch_t *request); 171 189 172 190 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 173 191 174 192 static int process_hub_feature_clear_request(rh_t *instance, 175 uint16_t feature);193 uint16_t feature); 176 194 177 195 static int process_port_feature_set_request(rh_t *instance, 178 uint16_t feature, uint16_t port);196 uint16_t feature, uint16_t port); 179 197 180 198 static int process_port_feature_clear_request(rh_t *instance, 181 uint16_t feature, uint16_t port);199 uint16_t feature, uint16_t port); 182 200 183 201 static int process_address_set_request(rh_t *instance, 184 uint16_t address);202 uint16_t address); 185 203 186 204 static int process_request_with_output(rh_t *instance, 187 usb_transfer_batch_t *request);205 usb_transfer_batch_t *request); 188 206 189 207 static int process_request_with_input(rh_t *instance, 190 usb_transfer_batch_t *request);208 usb_transfer_batch_t *request); 191 209 192 210 static int process_request_without_data(rh_t *instance, 193 usb_transfer_batch_t *request);211 usb_transfer_batch_t *request); 194 212 195 213 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); … … 198 216 199 217 static bool is_zeros(void * buffer, size_t size); 200 201 202 218 203 219 /** Root hub initialization … … 210 226 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 211 227 int opResult = rh_init_descriptors(instance); 212 if (opResult != EOK){228 if (opResult != EOK) { 213 229 return opResult; 214 230 } … … 216 232 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 217 233 instance->unfinished_interrupt_transfer = NULL; 218 instance->interrupt_mask_size = (instance->port_count + 8) /8;234 instance->interrupt_mask_size = (instance->port_count + 8) / 8; 219 235 instance->interrupt_buffer = malloc(instance->interrupt_mask_size); 220 if (!instance->interrupt_buffer)236 if (!instance->interrupt_buffer) 221 237 return ENOMEM; 222 223 224 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 238 239 usb_log_info("OHCI root hub with %zu ports initialized.\n", 240 instance->port_count); 241 225 242 return EOK; 226 243 } … … 245 262 usb_log_info("Root hub got INTERRUPT packet\n"); 246 263 create_interrupt_mask_in_instance(instance); 247 if (is_zeros(instance->interrupt_buffer,248 instance->interrupt_mask_size)) {264 if (is_zeros(instance->interrupt_buffer, 265 instance->interrupt_mask_size)) { 249 266 usb_log_debug("no changes..\n"); 250 267 instance->unfinished_interrupt_transfer = request; 251 268 //will be finished later 252 } else{269 } else { 253 270 usb_log_debug("processing changes..\n"); 254 271 process_interrupt_mask_in_instance(instance, request); … … 256 273 opResult = EOK; 257 274 } else { 275 258 276 opResult = EINVAL; 259 277 usb_transfer_batch_finish_error(request, opResult); … … 271 289 */ 272 290 void rh_interrupt(rh_t *instance) { 273 if (!instance->unfinished_interrupt_transfer){291 if (!instance->unfinished_interrupt_transfer) { 274 292 return; 275 293 } … … 292 310 static int create_serialized_hub_descriptor(rh_t *instance) { 293 311 size_t size = 7 + 294 ((instance->port_count + 7 )/ 8) * 2;295 size_t var_size = (instance->port_count + 7 )/ 8;312 ((instance->port_count + 7) / 8) * 2; 313 size_t var_size = (instance->port_count + 7) / 8; 296 314 uint8_t * result = (uint8_t*) malloc(size); 297 if (!result) return ENOMEM;315 if (!result) return ENOMEM; 298 316 299 317 bzero(result, size); … … 305 323 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 306 324 result[3] = 307 ((hub_desc_reg >> 8) % 2) +308 (((hub_desc_reg >> 9) % 2) << 1) +309 (((hub_desc_reg >> 10) % 2) << 2) +310 (((hub_desc_reg >> 11) % 2) << 3) +311 (((hub_desc_reg >> 12) % 2) << 4);325 ((hub_desc_reg >> 8) % 2) + 326 (((hub_desc_reg >> 9) % 2) << 1) + 327 (((hub_desc_reg >> 10) % 2) << 2) + 328 (((hub_desc_reg >> 11) % 2) << 3) + 329 (((hub_desc_reg >> 12) % 2) << 4); 312 330 result[4] = 0; 313 331 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 314 332 result[6] = 50; 315 333 316 int port;334 size_t port; 317 335 for (port = 1; port <= instance->port_count; ++port) { 318 336 uint8_t is_non_removable = 319 instance->registers->rh_desc_b >> port % 2;337 instance->registers->rh_desc_b >> port % 2; 320 338 result[7 + port / 8] += 321 is_non_removable << (port % 8);339 is_non_removable << (port % 8); 322 340 } 323 341 size_t i; … … 327 345 instance->hub_descriptor = result; 328 346 instance->descriptor_size = size; 347 329 348 return EOK; 330 349 } … … 340 359 static int rh_init_descriptors(rh_t *instance) { 341 360 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 342 sizeof (ohci_rh_device_descriptor)343 );361 sizeof (ohci_rh_device_descriptor) 362 ); 344 363 usb_standard_configuration_descriptor_t descriptor; 345 364 memcpy(&descriptor, &ohci_rh_conf_descriptor, 346 sizeof (ohci_rh_conf_descriptor));365 sizeof (ohci_rh_conf_descriptor)); 347 366 348 367 int opResult = create_serialized_hub_descriptor(instance); 349 if (opResult != EOK){368 if (opResult != EOK) { 350 369 return opResult; 351 370 } 352 371 descriptor.total_length = 353 sizeof (usb_standard_configuration_descriptor_t) +354 sizeof (usb_standard_endpoint_descriptor_t) +355 sizeof (usb_standard_interface_descriptor_t) +356 instance->descriptor_size;372 sizeof (usb_standard_configuration_descriptor_t) + 373 sizeof (usb_standard_endpoint_descriptor_t) + 374 sizeof (usb_standard_interface_descriptor_t) + 375 instance->descriptor_size; 357 376 358 377 uint8_t * full_config_descriptor = 359 (uint8_t*) malloc(descriptor.total_length);360 if (!full_config_descriptor){378 (uint8_t*) malloc(descriptor.total_length); 379 if (!full_config_descriptor) { 361 380 return ENOMEM; 362 381 } 363 382 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor)); 364 383 memcpy(full_config_descriptor + sizeof (descriptor), 365 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor));384 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor)); 366 385 memcpy(full_config_descriptor + sizeof (descriptor) + 367 sizeof (ohci_rh_iface_descriptor),368 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor));386 sizeof (ohci_rh_iface_descriptor), 387 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor)); 369 388 memcpy(full_config_descriptor + sizeof (descriptor) + 370 sizeof (ohci_rh_iface_descriptor) +371 sizeof (ohci_rh_ep_descriptor),372 instance->hub_descriptor, instance->descriptor_size);373 389 sizeof (ohci_rh_iface_descriptor) + 390 sizeof (ohci_rh_ep_descriptor), 391 instance->hub_descriptor, instance->descriptor_size); 392 374 393 instance->descriptors.configuration = full_config_descriptor; 375 394 instance->descriptors.configuration_size = descriptor.total_length; 395 376 396 return EOK; 377 397 } … … 389 409 */ 390 410 static int process_get_port_status_request(rh_t *instance, uint16_t port, 391 usb_transfer_batch_t * request) {411 usb_transfer_batch_t * request) { 392 412 if (port < 1 || port > instance->port_count) 393 413 return EINVAL; … … 398 418 int i; 399 419 for (i = 0; i < instance->port_count; ++i) { 420 400 421 usb_log_debug("port status %d,x%x\n", 401 instance->registers->rh_port_status[i],402 instance->registers->rh_port_status[i]);422 instance->registers->rh_port_status[i], 423 instance->registers->rh_port_status[i]); 403 424 } 404 425 #endif … … 417 438 */ 418 439 static int process_get_hub_status_request(rh_t *instance, 419 usb_transfer_batch_t * request) {440 usb_transfer_batch_t * request) { 420 441 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer; 421 442 request->transfered_size = 4; … … 423 444 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 424 445 uint32_buffer[0] = mask & instance->registers->rh_status; 446 425 447 return EOK; 426 448 } … … 437 459 */ 438 460 static int process_get_status_request(rh_t *instance, 439 usb_transfer_batch_t * request) {461 usb_transfer_batch_t * request) { 440 462 size_t buffer_size = request->buffer_size; 441 463 usb_device_request_setup_packet_t * request_packet = 442 (usb_device_request_setup_packet_t*)443 request->setup_buffer;464 (usb_device_request_setup_packet_t*) 465 request->setup_buffer; 444 466 445 467 usb_hub_bm_request_type_t request_type = request_packet->request_type; … … 453 475 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 454 476 return process_get_port_status_request(instance, 455 request_packet->index, 456 request); 477 request_packet->index, 478 request); 479 457 480 return ENOTSUP; 458 481 } … … 472 495 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer); 473 496 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 474 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16));497 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 475 498 bzero(bitmap, instance->interrupt_mask_size); 476 499 if (instance->registers->rh_status & mask) { 477 500 bitmap[0] = 1; 478 501 } 479 int port;502 size_t port; 480 503 mask = port_status_change_mask; 481 504 for (port = 1; port <= instance->port_count; ++port) { 482 505 if (mask & instance->registers->rh_port_status[port - 1]) { 506 483 507 bitmap[(port) / 8] += 1 << (port % 8); 484 508 } … … 497 521 */ 498 522 static int process_get_descriptor_request(rh_t *instance, 499 usb_transfer_batch_t *request) {523 usb_transfer_batch_t *request) { 500 524 usb_device_request_setup_packet_t * setup_request = 501 (usb_device_request_setup_packet_t*) request->setup_buffer;525 (usb_device_request_setup_packet_t*) request->setup_buffer; 502 526 size_t size; 503 527 const void * result_descriptor = NULL; … … 543 567 { 544 568 usb_log_debug("USB_DESCTYPE_EINVAL %d \n", 545 setup_request->value);569 setup_request->value); 546 570 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue " 547 "%d\n\tindex %d\n\tlen %d\n ",548 setup_request->request_type,549 setup_request->request,550 setup_request_value,551 setup_request->index,552 setup_request->length553 );571 "%d\n\tindex %d\n\tlen %d\n ", 572 setup_request->request_type, 573 setup_request->request, 574 setup_request_value, 575 setup_request->index, 576 setup_request->length 577 ); 554 578 return EINVAL; 555 579 } … … 560 584 request->transfered_size = size; 561 585 memcpy(request->data_buffer, result_descriptor, size); 586 562 587 return EOK; 563 588 } … … 573 598 */ 574 599 static int process_get_configuration_request(rh_t *instance, 575 usb_transfer_batch_t *request) {600 usb_transfer_batch_t *request) { 576 601 //set and get configuration requests do not have any meaning, only dummy 577 602 //values are returned … … 580 605 request->data_buffer[0] = 1; 581 606 request->transfered_size = 1; 607 582 608 return EOK; 583 609 } … … 592 618 */ 593 619 static int process_hub_feature_set_request(rh_t *instance, 594 uint16_t feature) {620 uint16_t feature) { 595 621 if (!((1 << feature) & hub_set_feature_valid_mask)) 596 622 return EINVAL; 597 if (feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER)623 if (feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER) 598 624 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16; 599 625 instance->registers->rh_status = 600 (instance->registers->rh_status | (1 << feature)) 601 & (~hub_clear_feature_by_writing_one_mask); 626 (instance->registers->rh_status | (1 << feature)) 627 & (~hub_clear_feature_by_writing_one_mask); 628 602 629 return EOK; 603 630 } … … 612 639 */ 613 640 static int process_hub_feature_clear_request(rh_t *instance, 614 uint16_t feature) {641 uint16_t feature) { 615 642 if (!((1 << feature) & hub_clear_feature_valid_mask)) 616 643 return EINVAL; … … 618 645 if ((1 << feature) & hub_set_feature_direct_mask) { 619 646 instance->registers->rh_status = 620 (instance->registers->rh_status & (~(1 << feature)))621 & (~hub_clear_feature_by_writing_one_mask);647 (instance->registers->rh_status & (~(1 << feature))) 648 & (~hub_clear_feature_by_writing_one_mask); 622 649 } else {//the feature is cleared by writing '1' 650 623 651 instance->registers->rh_status = 624 (instance->registers->rh_status625 & (~hub_clear_feature_by_writing_one_mask))626 | (1 << feature);652 (instance->registers->rh_status 653 & (~hub_clear_feature_by_writing_one_mask)) 654 | (1 << feature); 627 655 } 628 656 return EOK; … … 640 668 */ 641 669 static int process_port_feature_set_request(rh_t *instance, 642 uint16_t feature, uint16_t port) {670 uint16_t feature, uint16_t port) { 643 671 if (!((1 << feature) & port_set_feature_valid_mask)) 644 672 return EINVAL; … … 646 674 return EINVAL; 647 675 instance->registers->rh_port_status[port - 1] = 648 (instance->registers->rh_port_status[port - 1] | (1 << feature))649 & (~port_clear_feature_valid_mask);676 (instance->registers->rh_port_status[port - 1] | (1 << feature)) 677 & (~port_clear_feature_valid_mask); 650 678 /// \TODO any error? 679 651 680 return EOK; 652 681 } … … 663 692 */ 664 693 static int process_port_feature_clear_request(rh_t *instance, 665 uint16_t feature, uint16_t port) {694 uint16_t feature, uint16_t port) { 666 695 if (!((1 << feature) & port_clear_feature_valid_mask)) 667 696 return EINVAL; … … 673 702 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 674 703 instance->registers->rh_port_status[port - 1] = 675 (instance->registers->rh_port_status[port - 1]676 & (~port_clear_feature_valid_mask))677 | (1 << feature);704 (instance->registers->rh_port_status[port - 1] 705 & (~port_clear_feature_valid_mask)) 706 | (1 << feature); 678 707 /// \TODO any error? 708 679 709 return EOK; 680 710 } … … 689 719 */ 690 720 static int process_address_set_request(rh_t *instance, 691 uint16_t address) {721 uint16_t address) { 692 722 instance->address = address; 723 693 724 return EOK; 694 725 } … … 705 736 */ 706 737 static int process_request_with_output(rh_t *instance, 707 usb_transfer_batch_t *request) {738 usb_transfer_batch_t *request) { 708 739 usb_device_request_setup_packet_t * setup_request = 709 (usb_device_request_setup_packet_t*) request->setup_buffer;740 (usb_device_request_setup_packet_t*) request->setup_buffer; 710 741 if (setup_request->request == USB_DEVREQ_GET_STATUS) { 711 742 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); … … 718 749 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) { 719 750 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 751 720 752 return process_get_configuration_request(instance, request); 721 753 } … … 734 766 */ 735 767 static int process_request_with_input(rh_t *instance, 736 usb_transfer_batch_t *request) {768 usb_transfer_batch_t *request) { 737 769 usb_device_request_setup_packet_t * setup_request = 738 (usb_device_request_setup_packet_t*) request->setup_buffer;770 (usb_device_request_setup_packet_t*) request->setup_buffer; 739 771 request->transfered_size = 0; 740 772 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) { … … 744 776 //set and get configuration requests do not have any meaning, 745 777 //only dummy values are returned 778 746 779 return EOK; 747 780 } … … 760 793 */ 761 794 static int process_request_without_data(rh_t *instance, 762 usb_transfer_batch_t *request) {795 usb_transfer_batch_t *request) { 763 796 usb_device_request_setup_packet_t * setup_request = 764 (usb_device_request_setup_packet_t*) request->setup_buffer;797 (usb_device_request_setup_packet_t*) request->setup_buffer; 765 798 request->transfered_size = 0; 766 799 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) { … … 768 801 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 769 802 return process_hub_feature_clear_request(instance, 770 setup_request->value);803 setup_request->value); 771 804 } 772 805 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 773 806 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 774 807 return process_port_feature_clear_request(instance, 775 setup_request->value,776 setup_request->index);808 setup_request->value, 809 setup_request->index); 777 810 } 778 811 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 779 setup_request->request_type);812 setup_request->request_type); 780 813 return EINVAL; 781 814 } … … 784 817 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 785 818 return process_hub_feature_set_request(instance, 786 setup_request->value);819 setup_request->value); 787 820 } 788 821 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 789 822 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 790 823 return process_port_feature_set_request(instance, 791 setup_request->value,792 setup_request->index);824 setup_request->value, 825 setup_request->index); 793 826 } 794 827 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 795 setup_request->request_type);828 setup_request->request_type); 796 829 return EINVAL; 797 830 } … … 799 832 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 800 833 return process_address_set_request(instance, 801 setup_request->value);834 setup_request->value); 802 835 } 803 836 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 804 setup_request->request_type); 837 setup_request->request_type); 838 805 839 return ENOTSUP; 806 840 } … … 836 870 } 837 871 usb_log_info("CTRL packet: %s.\n", 838 usb_debug_str_buffer(839 (const uint8_t *) request->setup_buffer, 8, 8));872 usb_debug_str_buffer( 873 (const uint8_t *) request->setup_buffer, 8, 8)); 840 874 usb_device_request_setup_packet_t * setup_request = 841 (usb_device_request_setup_packet_t*)842 request->setup_buffer;875 (usb_device_request_setup_packet_t*) 876 request->setup_buffer; 843 877 switch (setup_request->request) { 844 878 case USB_DEVREQ_GET_STATUS: … … 847 881 usb_log_debug("processing request with output\n"); 848 882 opResult = process_request_with_output( 849 instance, request);883 instance, request); 850 884 break; 851 885 case USB_DEVREQ_CLEAR_FEATURE: … … 853 887 case USB_DEVREQ_SET_ADDRESS: 854 888 usb_log_debug("processing request without " 855 "additional data\n");889 "additional data\n"); 856 890 opResult = process_request_without_data( 857 instance, request);891 instance, request); 858 892 break; 859 893 case USB_DEVREQ_SET_DESCRIPTOR: 860 894 case USB_DEVREQ_SET_CONFIGURATION: 861 895 usb_log_debug("processing request with " 862 "input\n");896 "input\n"); 863 897 opResult = process_request_with_input( 864 instance, request); 898 instance, request); 899 865 900 break; 866 901 default: 867 902 usb_log_warning("received unsuported request: " 868 "%d\n",869 setup_request->request870 );903 "%d\n", 904 setup_request->request 905 ); 871 906 opResult = ENOTSUP; 872 907 } … … 888 923 * @return 889 924 */ 890 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request) {925 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request) { 891 926 memcpy(request->data_buffer, instance->interrupt_buffer, 892 927 instance->interrupt_mask_size); … … 894 929 instance->unfinished_interrupt_transfer = NULL; 895 930 usb_transfer_batch_finish_error(request, EOK); 931 896 932 return EOK; 897 933 } … … 907 943 * @return 908 944 */ 909 static bool is_zeros(void * buffer, size_t size) {910 if (!buffer) return true;911 if (!size) return true;945 static bool is_zeros(void * buffer, size_t size) { 946 if (!buffer) return true; 947 if (!size) return true; 912 948 size_t i; 913 for (i=0;i<size;++i){914 if (((char*)buffer)[i])949 for (i = 0; i < size; ++i) { 950 if (((char*) buffer)[i]) 915 951 return false; 916 952 } -
uspace/drv/ohci/root_hub.h
re1dbcbc ra81a1d09 51 51 usb_address_t address; 52 52 /** hub port count */ 53 int port_count;53 size_t port_count; 54 54 /** hubs descriptors */ 55 55 usb_device_descriptors_t descriptors; -
uspace/drv/uhci-hcd/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBHOST_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = uhci-hcd 33 41 -
uspace/drv/uhci-hcd/hc.c
re1dbcbc ra81a1d09 60 60 * 61 61 * @param[in] instance Memory place to initialize. 62 * @param[in] fun DDF function.63 62 * @param[in] regs Address of I/O control registers. 64 63 * @param[in] size Size of I/O control registers. … … 69 68 * interrupt fibrils. 70 69 */ 71 int hc_init(hc_t *instance, ddf_fun_t *fun, 72 void *regs, size_t reg_size, bool interrupts) 70 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts) 73 71 { 74 72 assert(reg_size >= sizeof(regs_t)); -
uspace/drv/uhci-hcd/hc.h
re1dbcbc ra81a1d09 136 136 } hc_t; 137 137 138 int hc_init(hc_t *instance, ddf_fun_t *fun, 139 void *regs, size_t reg_size, bool interupts); 138 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts); 140 139 141 140 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); -
uspace/drv/uhci-hcd/hw_struct/queue_head.h
re1dbcbc ra81a1d09 38 38 #include "link_pointer.h" 39 39 #include "transfer_descriptor.h" 40 #include " utils/malloc32.h"40 #include "../utils/malloc32.h" 41 41 42 42 /** This structure is defined in UHCI design guide p. 31 */ -
uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c
re1dbcbc ra81a1d09 36 36 37 37 #include "transfer_descriptor.h" 38 #include " utils/malloc32.h"38 #include "../utils/malloc32.h" 39 39 40 40 /** Initialize Transfer Descriptor -
uspace/drv/uhci-hcd/iface.c
re1dbcbc ra81a1d09 122 122 return EOK; 123 123 } 124 125 /** Find device handle by address interface function. 126 * 127 * @param[in] fun DDF function that was called. 128 * @param[in] address Address in question. 129 * @param[out] handle Where to store device handle if found. 130 * @return Error code. 131 */ 132 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 133 devman_handle_t *handle) 134 { 135 assert(fun); 136 hc_t *hc = fun_to_hc(fun); 137 assert(hc); 138 bool found = 139 usb_device_keeper_find_by_address(&hc->manager, address, handle); 140 return found ? EOK : ENOENT; 141 } 142 124 143 /*----------------------------------------------------------------------------*/ 125 144 /** Release address interface function … … 352 371 .request_address = request_address, 353 372 .bind_address = bind_address, 373 .find_by_address = find_by_address, 354 374 .release_address = release_address, 355 375 -
uspace/drv/uhci-hcd/main.c
re1dbcbc ra81a1d09 64 64 assert(device); 65 65 66 uhci_t *uhci = malloc(sizeof(uhci_t)); 67 if (uhci == NULL) { 68 usb_log_error("Failed to allocate UHCI driver.\n"); 69 return ENOMEM; 70 } 71 72 int ret = uhci_init(uhci, device); 66 int ret = device_setup_uhci(device); 73 67 if (ret != EOK) { 74 68 usb_log_error("Failed to initialize UHCI driver: %s.\n", … … 76 70 return ret; 77 71 } 78 device->driver_data = uhci;79 80 72 usb_log_info("Controlling new UHCI device '%s'.\n", device->name); 81 73 -
uspace/drv/uhci-hcd/uhci.c
re1dbcbc ra81a1d09 44 44 #include "pci.h" 45 45 46 #include "hc.h" 47 #include "root_hub.h" 48 49 /** Structure representing both functions of UHCI hc, USB host controller 50 * and USB root hub */ 51 typedef struct uhci { 52 /** Pointer to DDF represenation of UHCI host controller */ 53 ddf_fun_t *hc_fun; 54 /** Pointer to DDF represenation of UHCI root hub */ 55 ddf_fun_t *rh_fun; 56 57 /** Internal driver's represenation of UHCI host controller */ 58 hc_t hc; 59 /** Internal driver's represenation of UHCI root hub */ 60 rh_t rh; 61 } uhci_t; 62 63 static inline uhci_t * dev_to_uhci(ddf_dev_t *dev) 64 { 65 assert(dev); 66 assert(dev->driver_data); 67 return dev->driver_data; 68 } 69 /*----------------------------------------------------------------------------*/ 46 70 /** IRQ handling callback, forward status from call to diver structure. 47 71 * … … 69 93 { 70 94 assert(fun); 71 usb_device_keeper_t *manager = 72 &((uhci_t*)fun->dev->driver_data)->hc.manager; 73 95 usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager; 74 96 usb_address_t addr = usb_device_keeper_find(manager, handle); 97 75 98 if (addr < 0) { 76 99 return addr; … … 93 116 ddf_fun_t *fun, devman_handle_t *handle) 94 117 { 95 assert(handle); 96 ddf_fun_t *hc_fun = ((uhci_t*)fun->dev->driver_data)->hc_fun; 97 assert(hc_fun != NULL); 98 99 *handle = hc_fun->handle; 118 assert(fun); 119 ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun; 120 assert(hc_fun); 121 122 if (handle != NULL) 123 *handle = hc_fun->handle; 100 124 return EOK; 101 125 } … … 126 150 static hw_res_ops_t hw_res_iface = { 127 151 .get_resource_list = get_resource_list, 128 .enable_interrupt = NULL 152 .enable_interrupt = NULL, 129 153 }; 130 154 /*----------------------------------------------------------------------------*/ … … 146 170 * - registers interrupt handler 147 171 */ 148 int uhci_init(uhci_t *instance, ddf_dev_t *device) 149 { 150 assert(instance); 151 instance->hc_fun = NULL; 172 int device_setup_uhci(ddf_dev_t *device) 173 { 174 assert(device); 175 uhci_t *instance = malloc(sizeof(uhci_t)); 176 if (instance == NULL) { 177 usb_log_error("Failed to allocate OHCI driver.\n"); 178 return ENOMEM; 179 } 180 181 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 182 if (ret != EOK) { \ 183 if (instance->hc_fun) \ 184 instance->hc_fun->ops = NULL; \ 185 instance->hc_fun->driver_data = NULL; \ 186 ddf_fun_destroy(instance->hc_fun); \ 187 if (instance->rh_fun) {\ 188 instance->rh_fun->ops = NULL; \ 189 instance->rh_fun->driver_data = NULL; \ 190 ddf_fun_destroy(instance->rh_fun); \ 191 } \ 192 free(instance); \ 193 usb_log_error(message); \ 194 return ret; \ 195 } else (void)0 196 152 197 instance->rh_fun = NULL; 153 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 154 if (ret != EOK) { \ 155 usb_log_error(message); \ 156 if (instance->hc_fun) \ 157 ddf_fun_destroy(instance->hc_fun); \ 158 if (instance->rh_fun) \ 159 ddf_fun_destroy(instance->rh_fun); \ 160 return ret; \ 161 } 162 163 uintptr_t io_reg_base = 0; 164 size_t io_reg_size = 0; 198 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc"); 199 int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 200 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n"); 201 instance->hc_fun->ops = &hc_ops; 202 instance->hc_fun->driver_data = &instance->hc; 203 204 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh"); 205 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 206 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n"); 207 instance->rh_fun->ops = &rh_ops; 208 instance->rh_fun->driver_data = &instance->rh; 209 210 uintptr_t reg_base = 0; 211 size_t reg_size = 0; 165 212 int irq = 0; 166 213 167 int ret = 168 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 169 CHECK_RET_DEST_FUN_RETURN(ret, 214 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 215 CHECK_RET_DEST_FREE_RETURN(ret, 170 216 "Failed to get I/O addresses for %" PRIun ": %s.\n", 171 217 device->handle, str_error(ret)); 172 218 usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n", 173 (void *) io_reg_base, io_reg_size, irq);219 (void *) reg_base, reg_size, irq); 174 220 175 221 ret = pci_disable_legacy(device); 176 CHECK_RET_DEST_F UN_RETURN(ret,222 CHECK_RET_DEST_FREE_RETURN(ret, 177 223 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 178 224 … … 194 240 #endif 195 241 196 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc"); 197 ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 198 CHECK_RET_DEST_FUN_RETURN(ret, 199 "Failed(%d) to create HC function: %s.\n", ret, str_error(ret)); 200 201 ret = hc_init(&instance->hc, instance->hc_fun, 202 (void*)io_reg_base, io_reg_size, interrupts); 203 CHECK_RET_DEST_FUN_RETURN(ret, 242 243 ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts); 244 CHECK_RET_DEST_FREE_RETURN(ret, 204 245 "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret)); 205 206 instance->hc_fun->ops = &hc_ops;207 instance->hc_fun->driver_data = &instance->hc;208 ret = ddf_fun_bind(instance->hc_fun);209 CHECK_RET_DEST_FUN_RETURN(ret,210 "Failed(%d) to bind UHCI device function: %s.\n",211 ret, str_error(ret));212 #undef CHECK_RET_HC_RETURN213 246 214 247 #define CHECK_RET_FINI_RETURN(ret, message...) \ 215 248 if (ret != EOK) { \ 216 usb_log_error(message); \217 if (instance->hc_fun) \218 ddf_fun_destroy(instance->hc_fun); \219 if (instance->rh_fun) \220 ddf_fun_destroy(instance->rh_fun); \221 249 hc_fini(&instance->hc); \ 250 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 222 251 return ret; \ 223 } 252 } else (void)0 224 253 225 254 /* It does no harm if we register this on polling */ … … 230 259 ret, str_error(ret)); 231 260 232 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh"); 233 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 234 CHECK_RET_FINI_RETURN(ret, 235 "Failed(%d) to create root hub function: %s.\n", 261 ret = ddf_fun_bind(instance->hc_fun); 262 CHECK_RET_FINI_RETURN(ret, 263 "Failed(%d) to bind UHCI device function: %s.\n", 236 264 ret, str_error(ret)); 265 266 ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME); 267 CHECK_RET_FINI_RETURN(ret, 268 "Failed to add UHCI to HC class: %s.\n", str_error(ret)); 237 269 238 270 ret = rh_init(&instance->rh, instance->rh_fun, … … 241 273 "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret)); 242 274 243 instance->rh_fun->ops = &rh_ops;244 instance->rh_fun->driver_data = &instance->rh;245 275 ret = ddf_fun_bind(instance->rh_fun); 246 276 CHECK_RET_FINI_RETURN(ret, 247 277 "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret)); 248 278 279 device->driver_data = instance; 249 280 return EOK; 250 281 #undef CHECK_RET_FINI_RETURN -
uspace/drv/uhci-hcd/uhci.h
re1dbcbc ra81a1d09 38 38 #include <ddf/driver.h> 39 39 40 #include "hc.h" 41 #include "root_hub.h" 42 43 /** Structure representing both functions of UHCI hc, USB host controller 44 * and USB root hub */ 45 typedef struct uhci { 46 /** Pointer to DDF represenation of UHCI host controller */ 47 ddf_fun_t *hc_fun; 48 /** Pointer to DDF represenation of UHCI root hub */ 49 ddf_fun_t *rh_fun; 50 51 /** Internal driver's represenation of UHCI host controller */ 52 hc_t hc; 53 /** Internal driver's represenation of UHCI root hub */ 54 rh_t rh; 55 } uhci_t; 56 57 int uhci_init(uhci_t *instance, ddf_dev_t *device); 40 int device_setup_uhci(ddf_dev_t *device); 58 41 #endif 59 42 /** -
uspace/drv/uhci-rhd/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = uhci-rhd 33 41 -
uspace/drv/uhci-rhd/port.c
re1dbcbc ra81a1d09 32 32 * @brief UHCI root hub port routines 33 33 */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 35 #include <fibril_synch.h> /* async_usleep */ 35 36 #include <errno.h> 36 37 #include <str_error.h> 37 #include <fibril_synch.h>38 38 39 39 #include <usb/usb.h> /* usb_address_t */ 40 #include <usb/hub.h> 40 #include <usb/hub.h> /* usb_hc_new_device_wrapper */ 41 41 #include <usb/debug.h> 42 42 … … 212 212 213 213 /* 214 * The host then waits for at least 100 ms to allow completion of 215 * an insertion process and for power at the device to become stable. 216 */ 217 async_usleep(100000); 218 219 /* 220 * Resets from root ports should be nominally 50ms 214 * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3) 221 215 */ 222 216 { … … 229 223 port_status &= ~STATUS_IN_RESET; 230 224 uhci_port_write_status(port, port_status); 231 usb_log_debug("%s: Reset Signal stop.\n", port->id_string);232 }233 234 /* the reset recovery time 10ms */235 async_usleep(10000);236 225 while (uhci_port_read_status(port) & STATUS_IN_RESET); 226 // TODO: find a better way to waste time (it should be less than 227 // 10ms, if we reschedule it takes too much time (random 228 // interrupts can be solved by multiple attempts). 229 usb_log_debug2("%s: Reset Signal stop.\n", port->id_string); 230 } 237 231 /* Enable the port. */ 238 232 uhci_port_set_enabled(port, true); 233 234 /* Reset recovery period, 235 * devices do not have to respond during this period 236 */ 237 async_usleep(10000); 239 238 return EOK; 240 239 } … … 255 254 usb_log_debug("%s: Detected new device.\n", port->id_string); 256 255 256 int ret, count = 0; 257 257 usb_address_t dev_addr; 258 int ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 259 speed, uhci_port_reset_enable, port->number, port, 260 &dev_addr, &port->attached_device, NULL, NULL, NULL); 258 do { 259 ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 260 speed, uhci_port_reset_enable, port->number, port, 261 &dev_addr, &port->attached_device, NULL, NULL, NULL); 262 } while (ret != EOK && ++count < 4); 261 263 262 264 if (ret != EOK) { … … 313 315 /* Wait for port to become enabled */ 314 316 do { 315 async_usleep(1000);316 317 port_status = uhci_port_read_status(port); 317 318 } while ((port_status & STATUS_CONNECTED) && -
uspace/drv/usbflbk/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbflbk 33 41 -
uspace/drv/usbhid/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHID_PREFIX)/libusbhid.a \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I. \ 38 -I$(LIBUSB_PREFIX)/include \ 39 -I$(LIBUSBDEV_PREFIX)/include \ 40 -I$(LIBUSBHID_PREFIX)/include \ 41 -I$(LIBDRV_PREFIX)/include 42 32 43 BINARY = usbhid 33 44 -
uspace/drv/usbhid/generic/hiddev.c
re1dbcbc ra81a1d09 37 37 #include <usb/debug.h> 38 38 #include <usb/classes/classes.h> 39 #include <errno.h> 40 #include <str_error.h> 41 #include <bool.h> 42 43 #include <usbhid_iface.h> 39 44 40 45 #include "hiddev.h" … … 55 60 /*----------------------------------------------------------------------------*/ 56 61 62 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun); 63 64 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 65 size_t size, size_t *act_size, unsigned int flags); 66 67 static int usb_generic_hid_client_connected(ddf_fun_t *fun); 68 69 /*----------------------------------------------------------------------------*/ 70 71 static usbhid_iface_t usb_generic_iface = { 72 .get_event = usb_generic_hid_get_event, 73 .get_event_length = usb_generic_hid_get_event_length 74 }; 75 76 static ddf_dev_ops_t usb_generic_hid_ops = { 77 .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface, 78 .open = usb_generic_hid_client_connected 79 }; 80 81 /*----------------------------------------------------------------------------*/ 82 83 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun) 84 { 85 if (fun == NULL || fun->driver_data) { 86 return 0; 87 } 88 89 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 90 91 return hid_dev->input_report_size; 92 } 93 94 /*----------------------------------------------------------------------------*/ 95 96 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 97 size_t size, size_t *act_size, unsigned int flags) 98 { 99 if (fun == NULL || fun->driver_data) { 100 return EINVAL; 101 } 102 103 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 104 105 if (hid_dev->input_report_size > size) { 106 return EINVAL; // TODO: other error code 107 } 108 109 /*! @todo This should probably be atomic. */ 110 if (usb_hid_report_ready()) { 111 memcpy(buffer, hid_dev->input_report, 112 hid_dev->input_report_size); 113 *act_size = hid_dev->input_report_size; 114 usb_hid_report_received(); 115 } 116 117 // clear the buffer so that it will not be received twice 118 //memset(hid_dev->input_report, 0, hid_dev->input_report_size); 119 120 // note that we already received this report 121 // report_received = true; 122 123 return EOK; 124 } 125 126 /*----------------------------------------------------------------------------*/ 127 128 static int usb_generic_hid_client_connected(ddf_fun_t *fun) 129 { 130 usb_hid_report_received(); 131 return EOK; 132 } 133 134 /*----------------------------------------------------------------------------*/ 135 136 static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev) 137 { 138 /* Create the function exposed under /dev/devices. */ 139 /** @todo Generate numbers for the devices? */ 140 usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME); 141 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 142 HID_GENERIC_FUN_NAME); 143 if (fun == NULL) { 144 usb_log_error("Could not create DDF function node.\n"); 145 return ENOMEM; 146 } 147 148 int rc = ddf_fun_bind(fun); 149 if (rc != EOK) { 150 usb_log_error("Could not bind DDF function: %s.\n", 151 str_error(rc)); 152 ddf_fun_destroy(fun); 153 return rc; 154 } 155 156 fun->ops = &usb_generic_hid_ops; 157 fun->driver_data = hid_dev; 158 159 return EOK; 160 } 161 162 /*----------------------------------------------------------------------------*/ 163 164 int usb_generic_hid_init(usb_hid_dev_t *hid_dev) 165 { 166 if (hid_dev == NULL) { 167 return EINVAL; 168 } 169 170 return usb_generic_hid_create_function(hid_dev); 171 } 172 173 /*----------------------------------------------------------------------------*/ 174 57 175 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, 58 176 uint8_t *buffer, size_t buffer_size) -
uspace/drv/usbhid/generic/hiddev.h
re1dbcbc ra81a1d09 46 46 const char *HID_GENERIC_CLASS_NAME; 47 47 48 /*----------------------------------------------------------------------------*/ 49 50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev); 51 48 52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, 49 53 uint8_t *buffer, size_t buffer_size); -
uspace/drv/usbhid/kbd/kbddev.c
re1dbcbc ra81a1d09 255 255 256 256 if (hid_dev == NULL || hid_dev->data == NULL) { 257 usb_log_debug("default_connection_handler: " 258 "Missing parameter.\n"); 257 259 async_answer_0(icallid, EINVAL); 258 260 return; … … 267 269 268 270 if (kbd_dev->console_phone != -1) { 271 usb_log_debug("default_connection_handler: " 272 "console phone already set\n"); 269 273 async_answer_0(icallid, ELIMIT); 270 274 return; … … 272 276 273 277 kbd_dev->console_phone = callback; 278 279 usb_log_debug("default_connection_handler: OK\n"); 274 280 async_answer_0(icallid, EOK); 275 281 return; 276 282 } 277 283 284 usb_log_debug("default_connection_handler: Wrong function.\n"); 278 285 async_answer_0(icallid, EINVAL); 279 286 } … … 555 562 usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 556 563 kbd_dev->keys[i]); 557 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);558 564 if (!usb_kbd_is_lock(key)) { 559 565 usb_kbd_repeat_start(kbd_dev, key); 560 566 } 567 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key); 561 568 } else { 562 569 // found, nothing happens … … 766 773 767 774 /*----------------------------------------------------------------------------*/ 775 776 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev) 777 { 778 assert(hid_dev != NULL); 779 assert(hid_dev->usb_dev != NULL); 780 781 /* Create the function exposed under /dev/devices. */ 782 usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME); 783 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 784 HID_KBD_FUN_NAME); 785 if (fun == NULL) { 786 usb_log_error("Could not create DDF function node.\n"); 787 return ENOMEM; 788 } 789 790 /* 791 * Store the initialized HID device and HID ops 792 * to the DDF function. 793 */ 794 fun->ops = &hid_dev->ops; 795 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 796 797 int rc = ddf_fun_bind(fun); 798 if (rc != EOK) { 799 usb_log_error("Could not bind DDF function: %s.\n", 800 str_error(rc)); 801 ddf_fun_destroy(fun); 802 return rc; 803 } 804 805 usb_log_debug("Adding DDF function to class %s...\n", 806 HID_KBD_CLASS_NAME); 807 rc = ddf_fun_add_to_class(fun, HID_KBD_CLASS_NAME); 808 if (rc != EOK) { 809 usb_log_error( 810 "Could not add DDF function to class %s: %s.\n", 811 HID_KBD_CLASS_NAME, str_error(rc)); 812 ddf_fun_destroy(fun); 813 return rc; 814 } 815 816 return EOK; 817 } 818 819 /*----------------------------------------------------------------------------*/ 768 820 /* API functions */ 769 821 /*----------------------------------------------------------------------------*/ … … 930 982 usb_log_debug("HID/KBD device structure initialized.\n"); 931 983 984 usb_log_debug("Creating KBD function...\n"); 985 int rc = usb_kbd_create_function(hid_dev); 986 if (rc != EOK) { 987 usb_kbd_free(&kbd_dev); 988 return rc; 989 } 990 932 991 return EOK; 933 992 } … … 993 1052 if ((*kbd_dev)->led_data != NULL) { 994 1053 free((*kbd_dev)->led_data); 995 }996 if ((*kbd_dev)->output_buffer != NULL) {997 free((*kbd_dev)->output_buffer);998 1054 } 999 1055 if ((*kbd_dev)->led_path != NULL) { -
uspace/drv/usbhid/lgtch-ultrax/keymap.c
re1dbcbc ra81a1d09 55 55 [0xc] = KC_F6, /* Just for testing purposes */ 56 56 57 [0xb5] = 0, /* Scan Next Track */58 [0xb6] = 0, /* Scan Previous Track */59 [0xb7] = 0, /* Stop */60 [0xb8] = 0, /* Eject */61 [0xcd] = KC_F2, /* Play/Pause */62 [0xe2] = KC_F3, /* Mute */63 [0xe9] = KC_F5, /* Volume Increment */64 [0xea] = KC_F4, /* Volume Decrement */65 [0x183] = 0, /* AL Consumer Control Configuration */66 [0x18a] = 0, /* AL Email Reader */67 [0x192] = 0, /* AL Calculator */68 [0x221] = 0, /* AC Search */69 [0x223] = 0, /* AC Home */70 [0x224] = 0, /* AC Back */71 [0x225] = 0, /* AC Forward */72 [0x226] = 0, /* AC Stop */73 [0x227] = KC_F1, /* AC Refresh */74 [0x22a] = KC_F6 /* AC Bookmarks */57 [0xb5] = 0, /* Scan Next Track */ 58 [0xb6] = 0, /* Scan Previous Track */ 59 [0xb7] = 0, /* Stop */ 60 [0xb8] = 0, /* Eject */ 61 [0xcd] = KC_F2, /* Play/Pause */ 62 [0xe2] = KC_F3, /* Mute */ 63 [0xe9] = KC_F5, /* Volume Increment */ 64 [0xea] = KC_F4, /* Volume Decrement */ 65 [0x183] = 0, /* AL Consumer Control Configuration */ 66 [0x18a] = 0, /* AL Email Reader */ 67 [0x192] = 0, /* AL Calculator */ 68 [0x221] = 0, /* AC Search */ 69 [0x223] = 0, /* AC Home */ 70 [0x224] = 0, /* AC Back */ 71 [0x225] = 0, /* AC Forward */ 72 [0x226] = 0, /* AC Stop */ 73 [0x227] = KC_F1, /* AC Refresh */ 74 [0x22a] = KC_F6 /* AC Bookmarks */ 75 75 }; 76 76 -
uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c
re1dbcbc ra81a1d09 58 58 } usb_lgtch_flags; 59 59 60 /*----------------------------------------------------------------------------*/ 61 /** 62 * Logitech UltraX device type. 63 */ 64 typedef struct usb_lgtch_ultrax_t { 65 /** Previously pressed keys (not translated to key codes). */ 66 int32_t *keys_old; 67 /** Currently pressed keys (not translated to key codes). */ 68 int32_t *keys; 69 /** Count of stored keys (i.e. number of keys in the report). */ 70 size_t key_count; 71 72 /** IPC phone to the console device (for sending key events). */ 73 int console_phone; 74 75 /** Information for auto-repeat of keys. */ 76 // usb_kbd_repeat_t repeat; 77 78 /** Mutex for accessing the information about auto-repeat. */ 79 // fibril_mutex_t *repeat_mtx; 80 81 /** State of the structure (for checking before use). 82 * 83 * 0 - not initialized 84 * 1 - initialized 85 * -1 - ready for destroying 86 */ 87 int initialized; 88 } usb_lgtch_ultrax_t; 89 60 90 61 91 /*----------------------------------------------------------------------------*/ … … 208 238 /*----------------------------------------------------------------------------*/ 209 239 210 int usb_lgtch_init(struct usb_hid_dev *hid_dev) 211 { 212 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 213 return EINVAL; /*! @todo Other return code? */ 214 } 215 216 usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n"); 217 218 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc( 219 sizeof(usb_lgtch_ultrax_t)); 220 if (lgtch_dev == NULL) { 221 return ENOMEM; 222 } 223 224 lgtch_dev->console_phone = -1; 225 226 usb_hid_report_path_t *path = usb_hid_report_path(); 227 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 228 229 usb_hid_report_path_set_report_id(path, 1); 230 231 lgtch_dev->key_count = usb_hid_report_input_length( 232 hid_dev->report, path, 233 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 234 usb_hid_report_path_free(path); 235 236 usb_log_debug(NAME " Size of the input report: %zu\n", 237 lgtch_dev->key_count); 238 239 lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count, 240 sizeof(int32_t)); 241 242 if (lgtch_dev->keys == NULL) { 243 usb_log_fatal("No memory!\n"); 244 free(lgtch_dev); 245 return ENOMEM; 246 } 247 248 lgtch_dev->keys_old = 249 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t)); 250 251 if (lgtch_dev->keys_old == NULL) { 252 usb_log_fatal("No memory!\n"); 253 free(lgtch_dev->keys); 254 free(lgtch_dev); 255 return ENOMEM; 256 } 257 258 /*! @todo Autorepeat */ 259 260 // save the KBD device structure into the HID device structure 261 hid_dev->data = lgtch_dev; 262 240 static int usb_lgtch_create_function(usb_hid_dev_t *hid_dev) 241 { 263 242 /* Create the function exposed under /dev/devices. */ 264 243 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, … … 269 248 } 270 249 271 lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;272 usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");273 274 250 /* 275 251 * Store the initialized HID device and HID ops … … 279 255 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 280 256 281 /*282 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da283 * do nej.284 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi285 * vyplnenu strukturu usbhid_iface_t.286 * 3) klientska aplikacia - musi si rucne vytvorit telefon287 * (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az288 * k tej fcii.289 * pouzit usb/classes/hid/iface.h - prvy int je telefon290 */291 292 257 int rc = ddf_fun_bind(fun); 293 258 if (rc != EOK) { … … 296 261 // TODO: Can / should I destroy the DDF function? 297 262 ddf_fun_destroy(fun); 298 usb_lgtch_free(&lgtch_dev);299 263 return rc; 300 264 } … … 307 271 // TODO: Can / should I destroy the DDF function? 308 272 ddf_fun_destroy(fun); 273 return rc; 274 } 275 276 return EOK; 277 } 278 279 /*----------------------------------------------------------------------------*/ 280 281 int usb_lgtch_init(struct usb_hid_dev *hid_dev) 282 { 283 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 284 return EINVAL; /*! @todo Other return code? */ 285 } 286 287 usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n"); 288 289 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc( 290 sizeof(usb_lgtch_ultrax_t)); 291 if (lgtch_dev == NULL) { 292 return ENOMEM; 293 } 294 295 lgtch_dev->console_phone = -1; 296 297 usb_hid_report_path_t *path = usb_hid_report_path(); 298 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 299 300 usb_hid_report_path_set_report_id(path, 1); 301 302 lgtch_dev->key_count = usb_hid_report_input_length( 303 hid_dev->report, path, 304 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 305 usb_hid_report_path_free(path); 306 307 usb_log_debug(NAME " Size of the input report: %zu\n", 308 lgtch_dev->key_count); 309 310 lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count, 311 sizeof(int32_t)); 312 313 if (lgtch_dev->keys == NULL) { 314 usb_log_fatal("No memory!\n"); 315 free(lgtch_dev); 316 return ENOMEM; 317 } 318 319 lgtch_dev->keys_old = 320 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t)); 321 322 if (lgtch_dev->keys_old == NULL) { 323 usb_log_fatal("No memory!\n"); 324 free(lgtch_dev->keys); 325 free(lgtch_dev); 326 return ENOMEM; 327 } 328 329 /*! @todo Autorepeat */ 330 331 // save the KBD device structure into the HID device structure 332 hid_dev->data = lgtch_dev; 333 334 lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED; 335 usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n"); 336 337 int rc = usb_lgtch_create_function(hid_dev); 338 if (rc != EOK) { 309 339 usb_lgtch_free(&lgtch_dev); 310 340 return rc; … … 356 386 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 357 387 &report_id); 388 389 if (rc != EOK) { 390 usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 391 str_error(rc)); 392 return true; 393 } 394 358 395 usb_hid_report_path_set_report_id(path, report_id); 359 396 … … 383 420 usb_hid_report_path_free(path); 384 421 385 if (rc != EOK) {386 usb_log_warning(NAME "Error in usb_hid_boot_keyboard_input_report():"387 "%s\n", str_error(rc));388 }389 390 422 return true; 391 423 } -
uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h
re1dbcbc ra81a1d09 42 42 43 43 /*----------------------------------------------------------------------------*/ 44 /**45 * USB/HID keyboard device type.46 *47 * Holds a reference to generic USB/HID device structure and keyboard-specific48 * data, such as currently pressed keys, modifiers and lock keys.49 *50 * Also holds a IPC phone to the console (since there is now no other way to51 * communicate with it).52 *53 * @note Storing active lock keys in this structure results in their setting54 * being device-specific.55 */56 typedef struct usb_lgtch_ultrax_t {57 /** Previously pressed keys (not translated to key codes). */58 int32_t *keys_old;59 /** Currently pressed keys (not translated to key codes). */60 int32_t *keys;61 /** Count of stored keys (i.e. number of keys in the report). */62 size_t key_count;63 64 /** IPC phone to the console device (for sending key events). */65 int console_phone;66 67 /** Information for auto-repeat of keys. */68 // usb_kbd_repeat_t repeat;69 70 /** Mutex for accessing the information about auto-repeat. */71 // fibril_mutex_t *repeat_mtx;72 73 /** State of the structure (for checking before use).74 *75 * 0 - not initialized76 * 1 - initialized77 * -1 - ready for destroying78 */79 int initialized;80 } usb_lgtch_ultrax_t;81 82 /*----------------------------------------------------------------------------*/83 44 84 45 int usb_lgtch_init(struct usb_hid_dev *hid_dev); -
uspace/drv/usbhid/main.c
re1dbcbc ra81a1d09 99 99 usb_log_debug("USB/HID device structure initialized.\n"); 100 100 101 /* Create the function exposed under /dev/devices. */102 ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,103 usb_hid_get_function_name(hid_dev));104 if (hid_fun == NULL) {105 usb_log_error("Could not create DDF function node.\n");106 usb_hid_free(&hid_dev);107 return ENOMEM;108 }109 110 /*111 * Store the initialized HID device and HID ops112 * to the DDF function.113 */114 hid_fun->ops = &hid_dev->ops;115 hid_fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data116 117 101 /* 118 102 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da … … 125 109 * pouzit usb/classes/hid/iface.h - prvy int je telefon 126 110 */ 127 128 rc = ddf_fun_bind(hid_fun);129 if (rc != EOK) {130 usb_log_error("Could not bind DDF function: %s.\n",131 str_error(rc));132 // TODO: Can / should I destroy the DDF function?133 ddf_fun_destroy(hid_fun);134 usb_hid_free(&hid_dev);135 return rc;136 }137 138 rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev));139 if (rc != EOK) {140 usb_log_error(141 "Could not add DDF function to class 'hid': %s.\n",142 str_error(rc));143 // TODO: Can / should I destroy the DDF function?144 ddf_fun_destroy(hid_fun);145 usb_hid_free(&hid_dev);146 return rc;147 }148 111 149 112 /* Start automated polling function. -
uspace/drv/usbhid/mouse/mousedev.c
re1dbcbc ra81a1d09 39 39 #include <usb/classes/hid.h> 40 40 #include <usb/classes/hidreq.h> 41 #include <usb/classes/hidut.h> 41 42 #include <errno.h> 42 43 #include <str_error.h> 43 44 #include <ipc/mouse.h> 45 #include <io/console.h> 46 47 #include <ipc/kbd.h> 48 #include <io/keycode.h> 44 49 45 50 #include "mousedev.h" 46 51 #include "../usbhid.h" 52 53 #define NAME "mouse" 47 54 48 55 /*----------------------------------------------------------------------------*/ … … 58 65 59 66 const char *HID_MOUSE_FUN_NAME = "mouse"; 67 const char *HID_MOUSE_WHEEL_FUN_NAME = "mouse-wheel"; 60 68 const char *HID_MOUSE_CLASS_NAME = "mouse"; 69 const char *HID_MOUSE_WHEEL_CLASS_NAME = "keyboard"; 61 70 62 71 /** Default idle rate for mouses. */ 63 72 static const uint8_t IDLE_RATE = 0; 73 static const size_t USB_MOUSE_BUTTON_COUNT = 3; 64 74 65 75 /*----------------------------------------------------------------------------*/ … … 115 125 116 126 if (hid_dev == NULL || hid_dev->data == NULL) { 127 usb_log_debug("default_connection_handler: Missing " 128 "parameters.\n"); 117 129 async_answer_0(icallid, EINVAL); 118 130 return; … … 123 135 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 124 136 137 int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) 138 ? &mouse_dev->mouse_phone : &mouse_dev->wheel_phone; 139 125 140 if (method == IPC_M_CONNECT_TO_ME) { 126 141 int callback = IPC_GET_ARG5(*icall); 127 142 128 if (mouse_dev->console_phone != -1) { 143 if (*phone != -1) { 144 usb_log_debug("default_connection_handler: Console " 145 "phone to mouse already set.\n"); 129 146 async_answer_0(icallid, ELIMIT); 147 //async_answer_0(icallid, EOK); 130 148 return; 131 149 } 132 150 133 mouse_dev->console_phone = callback;151 *phone = callback; 134 152 usb_log_debug("Console phone to mouse set ok (%d).\n", callback); 135 153 async_answer_0(icallid, EOK); … … 137 155 } 138 156 157 usb_log_debug("default_connection_handler: Invalid function.\n"); 139 158 async_answer_0(icallid, EINVAL); 140 159 } … … 148 167 return NULL; 149 168 } 150 mouse->console_phone = -1; 169 mouse->mouse_phone = -1; 170 mouse->wheel_phone = -1; 151 171 152 172 return mouse; … … 160 180 161 181 // hangup phone to the console 162 if ((*mouse_dev)->console_phone >= 0) { 163 async_hangup((*mouse_dev)->console_phone); 182 if ((*mouse_dev)->mouse_phone >= 0) { 183 async_hangup((*mouse_dev)->mouse_phone); 184 } 185 186 if ((*mouse_dev)->wheel_phone >= 0) { 187 async_hangup((*mouse_dev)->wheel_phone); 164 188 } 165 189 … … 170 194 /*----------------------------------------------------------------------------*/ 171 195 172 static bool usb_mouse_process_boot_report(usb_mouse_t *mouse_dev, 173 uint8_t *buffer, size_t buffer_size) 174 { 196 static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel) 197 { 198 console_event_t ev; 199 200 ev.type = KEY_PRESS; 201 ev.key = (wheel > 0) ? KC_UP : (wheel < 0) ? KC_DOWN : 0; 202 ev.mods = 0; 203 ev.c = 0; 204 205 if (mouse_dev->wheel_phone < 0) { 206 usb_log_warning( 207 "Connection to console not ready, key discarded.\n"); 208 return; 209 } 210 211 int count = (wheel < 0) ? -wheel : wheel; 212 int i; 213 214 for (i = 0; i < count * 3; ++i) { 215 usb_log_debug2("Sending key %d to the console\n", ev.key); 216 async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, ev.type, 217 ev.key, ev.mods, ev.c); 218 // send key release right away 219 async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, KEY_RELEASE, 220 ev.key, ev.mods, ev.c); 221 } 222 } 223 224 /*----------------------------------------------------------------------------*/ 225 226 static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, uint8_t *buffer, 227 size_t buffer_size) 228 { 229 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 230 175 231 usb_log_debug2("got buffer: %s.\n", 176 232 usb_debug_str_buffer(buffer, buffer_size, 0)); 177 178 uint8_t butt = buffer[0]; 179 char str_buttons[4] = { 180 butt & 1 ? '#' : '.', 181 butt & 2 ? '#' : '.', 182 butt & 4 ? '#' : '.', 183 0 184 }; 185 186 int shift_x = ((int) buffer[1]) - 127; 187 int shift_y = ((int) buffer[2]) - 127; 188 int wheel = ((int) buffer[3]) - 127; 189 190 if (buffer[1] == 0) { 191 shift_x = 0; 192 } 193 if (buffer[2] == 0) { 194 shift_y = 0; 195 } 196 if (buffer[3] == 0) { 197 wheel = 0; 198 } 199 200 if (mouse_dev->console_phone >= 0) { 201 usb_log_debug("Console phone: %d\n", mouse_dev->console_phone); 202 if ((shift_x != 0) || (shift_y != 0)) { 203 /* FIXME: guessed for QEMU */ 204 async_req_2_0(mouse_dev->console_phone, 205 MEVENT_MOVE, 206 - shift_x / 10, - shift_y / 10); 207 } else { 208 usb_log_error("No move reported\n"); 209 } 210 if (butt) { 211 /* FIXME: proper button clicking. */ 212 async_req_2_0(mouse_dev->console_phone, 213 MEVENT_BUTTON, 1, 1); 214 async_req_2_0(mouse_dev->console_phone, 215 MEVENT_BUTTON, 1, 0); 216 } 217 } else { 218 usb_log_error("No console phone in mouse!!\n"); 219 } 220 221 usb_log_debug("buttons=%s dX=%+3d dY=%+3d wheel=%+3d\n", 222 str_buttons, shift_x, shift_y, wheel); 223 224 /* Guess. */ 225 //async_usleep(1000); 226 // no sleep right now 233 234 if (mouse_dev->mouse_phone < 0) { 235 usb_log_error(NAME " No console phone.\n"); 236 return false; // ?? 237 } 238 239 /* 240 * parse the input report 241 */ 242 243 usb_log_debug(NAME " Calling usb_hid_parse_report() with " 244 "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0)); 245 246 uint8_t report_id; 247 248 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 249 &report_id); 250 251 if (rc != EOK) { 252 usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 253 str_error(rc)); 254 return true; 255 } 256 257 /* 258 * X 259 */ 260 int shift_x = 0; 261 262 usb_hid_report_path_t *path = usb_hid_report_path(); 263 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 264 USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 265 266 usb_hid_report_path_set_report_id(path, report_id); 267 268 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 269 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 270 USB_HID_REPORT_TYPE_INPUT); 271 272 if (field != NULL) { 273 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 274 field->usage); 275 shift_x = field->value; 276 } 277 278 usb_hid_report_path_free(path); 279 280 /* 281 * Y 282 */ 283 int shift_y = 0; 284 285 path = usb_hid_report_path(); 286 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 287 USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 288 289 usb_hid_report_path_set_report_id(path, report_id); 290 291 field = usb_hid_report_get_sibling( 292 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 293 USB_HID_REPORT_TYPE_INPUT); 294 295 if (field != NULL) { 296 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 297 field->usage); 298 shift_y = field->value; 299 } 300 301 usb_hid_report_path_free(path); 302 303 if ((shift_x != 0) || (shift_y != 0)) { 304 async_req_2_0(mouse_dev->mouse_phone, 305 MEVENT_MOVE, shift_x, shift_y); 306 } 307 308 /* 309 * Wheel 310 */ 311 int wheel = 0; 312 313 path = usb_hid_report_path(); 314 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 315 USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 316 317 usb_hid_report_path_set_report_id(path, report_id); 318 319 field = usb_hid_report_get_sibling( 320 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 321 USB_HID_REPORT_TYPE_INPUT); 322 323 if (field != NULL) { 324 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 325 field->usage); 326 wheel = field->value; 327 } 328 329 usb_hid_report_path_free(path); 330 331 // send arrow up for positive direction and arrow down for negative 332 // direction; three arrows for difference of 1 333 usb_mouse_send_wheel(mouse_dev, wheel); 334 335 336 /* 337 * Buttons 338 */ 339 path = usb_hid_report_path(); 340 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 341 usb_hid_report_path_set_report_id(path, report_id); 342 343 field = usb_hid_report_get_sibling( 344 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 345 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 346 USB_HID_REPORT_TYPE_INPUT); 347 348 while (field != NULL) { 349 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 350 field->usage); 351 352 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0 353 && field->value != 0) { 354 async_req_2_0(mouse_dev->mouse_phone, 355 MEVENT_BUTTON, field->usage, 1); 356 mouse_dev->buttons[field->usage - field->usage_minimum] 357 = field->value; 358 } else if ( 359 mouse_dev->buttons[field->usage - field->usage_minimum] != 0 360 && field->value == 0) { 361 async_req_2_0(mouse_dev->mouse_phone, 362 MEVENT_BUTTON, field->usage, 0); 363 mouse_dev->buttons[field->usage - field->usage_minimum] 364 = field->value; 365 } 366 367 field = usb_hid_report_get_sibling( 368 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 369 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 370 USB_HID_REPORT_TYPE_INPUT); 371 } 372 373 usb_hid_report_path_free(path); 227 374 228 375 return true; 376 } 377 378 /*----------------------------------------------------------------------------*/ 379 380 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev) 381 { 382 /* Create the function exposed under /dev/devices. */ 383 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); 384 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 385 HID_MOUSE_FUN_NAME); 386 if (fun == NULL) { 387 usb_log_error("Could not create DDF function node.\n"); 388 return ENOMEM; 389 } 390 391 /* 392 * Store the initialized HID device and HID ops 393 * to the DDF function. 394 */ 395 fun->ops = &hid_dev->ops; 396 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 397 398 int rc = ddf_fun_bind(fun); 399 if (rc != EOK) { 400 usb_log_error("Could not bind DDF function: %s.\n", 401 str_error(rc)); 402 ddf_fun_destroy(fun); 403 return rc; 404 } 405 406 usb_log_debug("Adding DDF function to class %s...\n", 407 HID_MOUSE_CLASS_NAME); 408 rc = ddf_fun_add_to_class(fun, HID_MOUSE_CLASS_NAME); 409 if (rc != EOK) { 410 usb_log_error( 411 "Could not add DDF function to class %s: %s.\n", 412 HID_MOUSE_CLASS_NAME, str_error(rc)); 413 ddf_fun_destroy(fun); 414 return rc; 415 } 416 417 /* 418 * Special function for acting as keyboard (wheel) 419 */ 420 usb_log_debug("Creating DDF function %s...\n", 421 HID_MOUSE_WHEEL_FUN_NAME); 422 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 423 HID_MOUSE_WHEEL_FUN_NAME); 424 if (fun == NULL) { 425 usb_log_error("Could not create DDF function node.\n"); 426 return ENOMEM; 427 } 428 429 /* 430 * Store the initialized HID device and HID ops 431 * to the DDF function. 432 */ 433 fun->ops = &hid_dev->ops; 434 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 435 436 rc = ddf_fun_bind(fun); 437 if (rc != EOK) { 438 usb_log_error("Could not bind DDF function: %s.\n", 439 str_error(rc)); 440 ddf_fun_destroy(fun); 441 return rc; 442 } 443 444 usb_log_debug("Adding DDF function to class %s...\n", 445 HID_MOUSE_WHEEL_CLASS_NAME); 446 rc = ddf_fun_add_to_class(fun, HID_MOUSE_WHEEL_CLASS_NAME); 447 if (rc != EOK) { 448 usb_log_error( 449 "Could not add DDF function to class %s: %s.\n", 450 HID_MOUSE_WHEEL_CLASS_NAME, str_error(rc)); 451 ddf_fun_destroy(fun); 452 return rc; 453 } 454 455 return EOK; 229 456 } 230 457 … … 248 475 } 249 476 477 mouse_dev->buttons = (int32_t *)calloc(USB_MOUSE_BUTTON_COUNT, 478 sizeof(int32_t)); 479 480 if (mouse_dev->buttons == NULL) { 481 usb_log_fatal("No memory!\n"); 482 free(mouse_dev); 483 return ENOMEM; 484 } 485 250 486 // save the Mouse device structure into the HID device structure 251 487 hid_dev->data = mouse_dev; … … 255 491 256 492 // TODO: how to know if the device supports the request??? 257 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 258 hid_dev->usb_dev->interface_no, IDLE_RATE); 493 // usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 494 // hid_dev->usb_dev->interface_no, IDLE_RATE); 495 496 int rc = usb_mouse_create_function(hid_dev); 497 if (rc != EOK) { 498 usb_mouse_free(&mouse_dev); 499 return rc; 500 } 259 501 260 502 return EOK; … … 280 522 return false; 281 523 } 282 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 283 284 return usb_mouse_process_boot_report(mouse_dev, buffer, buffer_size); 524 525 return usb_mouse_process_report(hid_dev, buffer, buffer_size); 285 526 } 286 527 -
uspace/drv/usbhid/mouse/mousedev.h
re1dbcbc ra81a1d09 48 48 //suseconds_t poll_interval_us; 49 49 /** IPC phone to console (consumer). */ 50 int console_phone; 50 int mouse_phone; 51 int wheel_phone; 52 53 int32_t *buttons; 51 54 } usb_mouse_t; 52 55 -
uspace/drv/usbhid/subdrivers.c
re1dbcbc ra81a1d09 36 36 #include "subdrivers.h" 37 37 #include "usb/classes/hidut.h" 38 #include "usb/classes/hidpath.h" 38 39 39 40 #include "lgtch-ultrax/lgtch-ultrax.h" 41 #include "mouse/mousedev.h" 40 42 41 43 static usb_hid_subdriver_usage_t path_kbd[] = { 42 44 {USB_HIDUT_PAGE_KEYBOARD, 0}, 45 {0, 0} 46 }; 47 48 static usb_hid_subdriver_usage_t path_mouse2[] = { 49 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_X}, 43 50 {0, 0} 44 51 }; … … 79 86 } 80 87 }, 88 { 89 path_mouse2, 90 -1, 91 USB_HID_PATH_COMPARE_END 92 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 93 -1, 94 -1, 95 { 96 .init = usb_mouse_init, 97 .deinit = usb_mouse_deinit, 98 .poll = usb_mouse_polling_callback, 99 .poll_end = NULL 100 } 101 }, 81 102 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}} 82 103 }; -
uspace/drv/usbhid/usbhid.c
re1dbcbc ra81a1d09 63 63 static const int USB_HID_MAX_SUBDRIVERS = 10; 64 64 65 static fibril_local bool report_received; 66 65 67 /*----------------------------------------------------------------------------*/ 66 68 … … 136 138 137 139 // set the init callback 138 hid_dev->subdrivers[0].init = NULL;140 hid_dev->subdrivers[0].init = usb_generic_hid_init; 139 141 140 142 // set the polling callback … … 412 414 } 413 415 414 // TODO: remove the mouse hack 415 if (hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO || 416 fallback) { 416 if (fallback) { 417 417 // fall back to boot protocol 418 418 switch (hid_dev->poll_pipe_index) { … … 490 490 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 491 491 492 int allocated = (hid_dev->input_report != NULL); 493 494 if (!allocated 495 || hid_dev->input_report_size < buffer_size) { 496 uint8_t *input_old = hid_dev->input_report; 497 uint8_t *input_new = (uint8_t *)malloc(buffer_size); 498 499 if (input_new == NULL) { 500 usb_log_error("Failed to allocate space for input " 501 "buffer. This event may not be reported\n"); 502 memset(hid_dev->input_report, 0, 503 hid_dev->input_report_size); 504 } else { 505 memcpy(input_new, input_old, 506 hid_dev->input_report_size); 507 hid_dev->input_report = input_new; 508 if (allocated) { 509 free(input_old); 510 } 511 usb_hid_new_report(); 512 } 513 } 514 515 /*! @todo This should probably be atomic. */ 516 memcpy(hid_dev->input_report, buffer, buffer_size); 517 hid_dev->input_report_size = buffer_size; 518 492 519 bool cont = false; 493 520 … … 528 555 /*----------------------------------------------------------------------------*/ 529 556 530 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev) 531 { 532 switch (hid_dev->poll_pipe_index) { 533 case USB_HID_KBD_POLL_EP_NO: 534 return HID_KBD_FUN_NAME; 535 break; 536 case USB_HID_MOUSE_POLL_EP_NO: 537 return HID_MOUSE_FUN_NAME; 538 break; 539 default: 540 return HID_GENERIC_FUN_NAME; 541 } 542 } 543 544 /*----------------------------------------------------------------------------*/ 545 546 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev) 547 { 548 // this means that only boot protocol keyboards will be connected 549 // to the console; there is probably no better way to do this 550 551 switch (hid_dev->poll_pipe_index) { 552 case USB_HID_KBD_POLL_EP_NO: 553 return HID_KBD_CLASS_NAME; 554 break; 555 case USB_HID_MOUSE_POLL_EP_NO: 556 return HID_MOUSE_CLASS_NAME; 557 break; 558 default: 559 return HID_GENERIC_CLASS_NAME; 560 } 557 //const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev) 558 //{ 559 // switch (hid_dev->poll_pipe_index) { 560 // case USB_HID_KBD_POLL_EP_NO: 561 // return HID_KBD_FUN_NAME; 562 // break; 563 // case USB_HID_MOUSE_POLL_EP_NO: 564 // return HID_MOUSE_FUN_NAME; 565 // break; 566 // default: 567 // return HID_GENERIC_FUN_NAME; 568 // } 569 //} 570 571 /*----------------------------------------------------------------------------*/ 572 573 //const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev) 574 //{ 575 // // this means that only boot protocol keyboards will be connected 576 // // to the console; there is probably no better way to do this 577 578 // switch (hid_dev->poll_pipe_index) { 579 // case USB_HID_KBD_POLL_EP_NO: 580 // return HID_KBD_CLASS_NAME; 581 // break; 582 // case USB_HID_MOUSE_POLL_EP_NO: 583 // return HID_MOUSE_CLASS_NAME; 584 // break; 585 // default: 586 // return HID_GENERIC_CLASS_NAME; 587 // } 588 //} 589 590 /*----------------------------------------------------------------------------*/ 591 592 void usb_hid_new_report(void) 593 { 594 report_received = false; 595 } 596 597 /*----------------------------------------------------------------------------*/ 598 599 void usb_hid_report_received(void) 600 { 601 report_received = true; 602 } 603 604 /*----------------------------------------------------------------------------*/ 605 606 bool usb_hid_report_ready(void) 607 { 608 return !report_received; 561 609 } 562 610 -
uspace/drv/usbhid/usbhid.h
re1dbcbc ra81a1d09 44 44 #include <usb/devdrv.h> 45 45 #include <usb/classes/hid.h> 46 #include <bool.h> 46 47 47 48 struct usb_hid_dev; … … 93 94 usb_hid_report_t *report; 94 95 96 uint8_t *input_report; 97 98 size_t input_report_size; 99 95 100 /** Arbitrary data (e.g. a special structure for handling keyboard). */ 96 101 void *data; … … 120 125 void *arg); 121 126 122 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);127 //const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev); 123 128 124 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev); 129 //const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev); 130 131 void usb_hid_new_report(void); 132 133 void usb_hid_report_received(void); 134 135 bool usb_hid_report_ready(void); 125 136 126 137 void usb_hid_free(usb_hid_dev_t **hid_dev); -
uspace/drv/usbhub/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbhub 33 41 -
uspace/drv/usbhub/ports.c
re1dbcbc ra81a1d09 53 53 size_t port; 54 54 usb_speed_t speed; 55 }; 56 57 /** 58 * count of port status changes that are not explicitly handled by 59 * any function here and must be cleared by hand 60 */ 61 static const unsigned int non_handled_changes_count = 2; 62 63 /** 64 * port status changes that are not explicitly handled by 65 * any function here and must be cleared by hand 66 */ 67 static const int non_handled_changes[] = { 68 USB_HUB_FEATURE_C_PORT_ENABLE, 69 USB_HUB_FEATURE_C_PORT_SUSPEND 55 70 }; 56 71 … … 131 146 &status, USB_HUB_FEATURE_C_PORT_CONNECTION,false); 132 147 usb_port_status_set_bit( 133 &status, USB_HUB_FEATURE_PORT_RESET,false);134 usb_port_status_set_bit(135 148 &status, USB_HUB_FEATURE_C_PORT_RESET,false); 136 149 usb_port_status_set_bit( 137 150 &status, USB_HUB_FEATURE_C_PORT_OVER_CURRENT,false); 138 /// \TODO what about port power change? 139 if (status >> 16) { 140 usb_log_info("there was unsupported change on port %d: %X\n", 141 port, status); 142 151 152 //clearing not yet handled changes 153 unsigned int feature_idx; 154 for(feature_idx = 0;feature_idx<non_handled_changes_count; 155 ++feature_idx){ 156 unsigned int bit_idx = non_handled_changes[feature_idx]; 157 if(status & (1<<bit_idx)){ 158 usb_log_info( 159 "there was not yet handled change on port %d: %d" 160 ";clearing it\n", 161 port, bit_idx); 162 int opResult = usb_hub_clear_port_feature( 163 hub->control_pipe, 164 port, bit_idx); 165 if (opResult != EOK) { 166 usb_log_warning( 167 "could not clear port flag %d: %d\n", 168 bit_idx, opResult 169 ); 170 } 171 usb_port_status_set_bit( 172 &status, bit_idx,false); 173 } 174 } 175 if(status>>16){ 176 usb_log_info("there is still some unhandled change %X\n", 177 status); 143 178 } 144 179 } … … 222 257 "Port %zu reset complete but port not enabled.\n", 223 258 (size_t) port); 259 } 260 /* Clear the port reset change. */ 261 int rc = usb_hub_clear_port_feature(hub->control_pipe, 262 port, USB_HUB_FEATURE_C_PORT_RESET); 263 if (rc != EOK) { 264 usb_log_error("Failed to clear port %d reset feature: %s.\n", 265 port, str_error(rc)); 224 266 } 225 267 } … … 319 361 fibril_mutex_unlock(&my_port->reset_mutex); 320 362 321 /* Clear the port reset change. */322 rc = usb_hub_clear_port_feature(hub->control_pipe,323 port_no, USB_HUB_FEATURE_C_PORT_RESET);324 if (rc != EOK) {325 usb_log_error("Failed to clear port %d reset feature: %s.\n",326 port_no, str_error(rc));327 return rc;328 }329 330 363 if (my_port->reset_okay) { 331 364 return EOK; -
uspace/drv/usbhub/usbhub.c
re1dbcbc ra81a1d09 411 411 static int usb_process_hub_power_change(usb_hub_info_t * hub_info, 412 412 usb_hub_status_t status) { 413 int opResult ;413 int opResult = EOK; 414 414 if (!usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) { 415 415 //restart power on hub … … 431 431 } 432 432 } 433 opResult = usb_hub_clear_feature(hub_info->control_pipe, 434 USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 433 } 434 if(opResult!=EOK){ 435 return opResult;//no feature clearing 436 } 437 opResult = usb_hub_clear_feature(hub_info->control_pipe, 438 USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 435 439 if (opResult != EOK) { 436 usb_log_error("cannnot clear hub power change flag: " 437 "%d\n", 438 opResult); 439 } 440 usb_log_error("cannnot clear hub power change flag: " 441 "%d\n", 442 opResult); 440 443 } 441 444 return opResult; -
uspace/drv/usbkbd/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHID_PREFIX)/libusbhid.a \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I. \ 38 -I$(LIBUSB_PREFIX)/include \ 39 -I$(LIBUSBDEV_PREFIX)/include \ 40 -I$(LIBUSBHID_PREFIX)/include \ 41 -I$(LIBDRV_PREFIX)/include 42 32 43 BINARY = usbkbd 33 44 -
uspace/drv/usbkbd/kbddev.c
re1dbcbc ra81a1d09 294 294 usb_log_debug("Creating output report.\n"); 295 295 296 usb_hid_report_output_set_data(kbd_dev->parser, kbd_dev->led_path,297 USB_HID_PATH_COMPARE_END , kbd_dev->led_data,298 kbd_dev->led_output_size);296 //usb_hid_report_output_set_data(kbd_dev->parser, kbd_dev->led_path, 297 // USB_HID_PATH_COMPARE_END , kbd_dev->led_data, 298 // kbd_dev->led_output_size); 299 299 int rc = usb_hid_report_output_translate(kbd_dev->parser, 0, 300 300 kbd_dev->output_buffer, kbd_dev->output_size); -
uspace/drv/usbmast/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbmast 33 41 -
uspace/drv/usbmid/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 30 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 35 EXTRA_CFLAGS += \ 36 -I$(LIBUSB_PREFIX)/include \ 37 -I$(LIBUSBDEV_PREFIX)/include \ 38 -I$(LIBDRV_PREFIX)/include 39 32 40 BINARY = usbmid 33 41 -
uspace/drv/usbmouse/Makefile
re1dbcbc ra81a1d09 28 28 29 29 USPACE_PREFIX = ../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 30 31 LIBS = \ 32 $(LIBUSBHID_PREFIX)/libusbhid.a \ 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 $(LIBUSB_PREFIX)/libusb.a \ 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I$(LIBUSB_PREFIX)/include \ 38 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBUSBHID_PREFIX)/include \ 40 -I$(LIBDRV_PREFIX)/include 32 41 33 42 BINARY = usbmouse -
uspace/drv/vhc/Makefile
re1dbcbc ra81a1d09 29 29 USPACE_PREFIX = ../.. 30 30 LIBS = \ 31 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 31 33 $(LIBUSB_PREFIX)/libusb.a \ 32 34 $(LIBUSBVIRT_PREFIX)/libusbvirt.a \ … … 34 36 EXTRA_CFLAGS += \ 35 37 -I$(LIBUSBVIRT_PREFIX)/include \ 38 -I$(LIBUSBDEV_PREFIX)/include \ 39 -I$(LIBUSBHOST_PREFIX)/include \ 36 40 -I$(LIBUSB_PREFIX)/include \ 37 41 -I$(LIBDRV_PREFIX)/include -
uspace/drv/vhc/connhost.c
re1dbcbc ra81a1d09 94 94 } 95 95 96 /** Find device handle by address interface function. 97 * 98 * @param[in] fun DDF function that was called. 99 * @param[in] address Address in question. 100 * @param[out] handle Where to store device handle if found. 101 * @return Error code. 102 */ 103 static int find_by_address(ddf_fun_t *fun, usb_address_t address, 104 devman_handle_t *handle) 105 { 106 VHC_DATA(vhc, fun); 107 bool found = 108 usb_device_keeper_find_by_address(&vhc->dev_keeper, address, handle); 109 return found ? EOK : ENOENT; 110 } 111 96 112 /** Release previously requested address. 97 113 * … … 444 460 .request_address = request_address, 445 461 .bind_address = bind_address, 462 .find_by_address = find_by_address, 446 463 .release_address = release_address, 447 464 -
uspace/drv/vhc/main.c
re1dbcbc ra81a1d09 104 104 } 105 105 106 ddf_fun_add_to_class(hc, "usbhc"); 106 rc = ddf_fun_add_to_class(hc, USB_HC_DDF_CLASS_NAME); 107 if (rc != EOK) { 108 usb_log_fatal("Failed to add function to HC class: %s.\n", 109 str_error(rc)); 110 free(data); 111 return rc; 112 } 107 113 108 114 virtual_hub_device_init(hc); -
uspace/drv/vhc/transfer.c
re1dbcbc ra81a1d09 135 135 if (transfer->direction == USB_DIRECTION_IN) { 136 136 rc = usbvirt_ipc_send_control_read(phone, 137 transfer->endpoint,138 137 transfer->setup_buffer, transfer->setup_buffer_size, 139 138 transfer->data_buffer, transfer->data_buffer_size, … … 142 141 assert(transfer->direction == USB_DIRECTION_OUT); 143 142 rc = usbvirt_ipc_send_control_write(phone, 144 transfer->endpoint,145 143 transfer->setup_buffer, transfer->setup_buffer_size, 146 144 transfer->data_buffer, transfer->data_buffer_size);
Note:
See TracChangeset
for help on using the changeset viewer.
