Changeset 8e9becf6 in mainline
- Timestamp:
- 2011-03-08T20:00:47Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 021351c
- Parents:
- 0588062e (diff), d2fc1c2 (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. - Files:
-
- 4 added
- 2 deleted
- 61 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r0588062e r8e9becf6 84 84 ./uspace/drv/test1/test1 85 85 ./uspace/drv/test2/test2 86 ./uspace/drv/ehci-hcd/ehci-hcd 86 87 ./uspace/drv/uhci-hcd/uhci-hcd 87 88 ./uspace/drv/uhci-rhd/uhci-rhd -
boot/arch/amd64/Makefile.inc
r0588062e r8e9becf6 43 43 isa \ 44 44 ns8250 \ 45 ehci-hcd \ 45 46 uhci-hcd \ 46 47 uhci-rhd \ -
boot/arch/mips32/src/asm.S
r0588062e r8e9becf6 41 41 42 42 start: 43 /* Setup CPU map (on msim this code 44 is executed in parallel on all CPUs, 45 but it not an issue) */ 43 /* 44 * Setup the CP0 configuration 45 * - Disable 64-bit kernel addressing mode 46 * - DIsable 64-bit supervisor adressing mode 47 * - Disable 64-bit user addressing mode 48 */ 49 mfc0 $a0, $status 50 la $a1, 0xffffff1f 51 and $a0, $a1, $a0 52 mtc0 $a0, $status 53 54 /* 55 * Setup CPU map (on msim this code 56 * is executed in parallel on all CPUs, 57 * but it not an issue). 58 */ 46 59 la $a0, PA2KA(CPUMAP_OFFSET) 47 60 … … 94 107 lw $k1, ($k0) 95 108 96 /* If we are not running on BSP 97 then end in an infinite loop */ 109 /* 110 * If we are not running on BSP 111 * then end in an infinite loop. 112 */ 98 113 beq $k1, $zero, bsp 99 114 nop … … 127 142 128 143 jump_to_kernel: 129 # 130 # TODO: 131 # Make sure that the I-cache, D-cache and memory are mutually coherent 132 # before passing control to the copied code. 133 # 144 /* 145 * TODO: 146 * 147 * Make sure that the I-cache, D-cache and memory are mutually 148 * coherent before passing control to the copied code. 149 */ 134 150 j $a0 135 151 nop -
uspace/Makefile
r0588062e r8e9becf6 117 117 srv/hw/irc/apic \ 118 118 srv/hw/irc/i8259 \ 119 drv/ehci-hcd \ 119 120 drv/uhci-hcd \ 120 121 drv/uhci-rhd \ … … 134 135 srv/hw/irc/apic \ 135 136 srv/hw/irc/i8259 \ 137 drv/ehci-hcd \ 136 138 drv/uhci-hcd \ 137 139 drv/uhci-rhd \ -
uspace/app/bdsh/cmds/modules/mkfile/mkfile.c
r0588062e r8e9becf6 125 125 126 126 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 127 c = getopt_long(argc, argv, " pvhVfm:", long_options, &opt_ind);127 c = getopt_long(argc, argv, "s:h", long_options, &opt_ind); 128 128 switch (c) { 129 129 case 'h': -
uspace/doc/doxygroups.h
r0588062e r8e9becf6 256 256 */ 257 257 258 /** 259 * @defgroup drvusbehci EHCI driver 260 * @ingroup usb 261 * @brief Driver for EHCI host controller. 262 */ 263 264 -
uspace/drv/ehci-hcd/pci.h
r0588062e r8e9becf6 1 1 /* 2 * Copyright (c) 201 0Vojtech Horky2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libusb29 /** @addtogroup drvusbehci 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief Common definitions for both HC driver and hubdriver.33 * PCI related functions needed by EHCI driver. 34 34 */ 35 #ifndef LIBUSB_HCDHUBD_PRIVATE_H_36 #define LIBUSB_HCDHUBD_PRIVATE_H_35 #ifndef DRV_EHCI_PCI_H 36 #define DRV_EHCI_PCI_H 37 37 38 #define USB_HUB_DEVICE_NAME "usbhub" 39 #define USB_KBD_DEVICE_NAME "hid" 38 #include <ddf/driver.h> 40 39 41 extern link_t hc_list; 42 extern usb_hc_driver_t *hc_driver; 43 44 extern usbhc_iface_t usbhc_interface; 45 46 usb_address_t usb_get_address_by_handle(devman_handle_t); 47 int usb_add_hc_device(device_t *); 48 49 /** lowest allowed usb address */ 50 extern int usb_lowest_address; 51 52 /** highest allowed usb address */ 53 extern int usb_highest_address; 54 55 /** 56 * @brief initialize address list of given hcd 57 * 58 * This function should be used only for hcd initialization. 59 * It creates interval list of free addresses, thus it is initialized as 60 * list with one interval with whole address space. Using an address shrinks 61 * the interval, freeing an address extends an interval or creates a 62 * new one. 63 * 64 * @param hcd 65 * @return 66 */ 67 void usb_create_address_list(usb_hc_device_t * hcd); 68 69 70 71 72 40 int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 int pci_enable_interrupts(ddf_dev_t *); 42 int pci_disable_legacy(ddf_dev_t *); 73 43 74 44 #endif … … 76 46 * @} 77 47 */ 48 -
uspace/drv/pciintel/pci.c
r0588062e r8e9becf6 94 94 sysarg_t apic; 95 95 sysarg_t i8259; 96 96 97 int irc_phone = -1; 97 98 int irc_service = 0; … … 103 104 } 104 105 105 if (irc_service) { 106 while (irc_phone < 0) 107 irc_phone = service_connect_blocking(irc_service, 0, 0); 108 } else { 106 if (irc_service == 0) 109 107 return false; 110 } 108 109 irc_phone = service_connect_blocking(irc_service, 0, 0); 110 if (irc_phone < 0) 111 return false; 111 112 112 113 size_t i; … … 114 115 if (dev_data->hw_resources.resources[i].type == INTERRUPT) { 115 116 int irq = dev_data->hw_resources.resources[i].res.interrupt.irq; 116 async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq); 117 int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq); 118 if (rc != EOK) { 119 async_hangup(irc_phone); 120 return false; 121 } 117 122 } 118 123 } … … 122 127 } 123 128 124 static int pci_config_space_write_16(ddf_fun_t *fun, uint32_t address, uint16_t data) 129 static int pci_config_space_write_32( 130 ddf_fun_t *fun, uint32_t address, uint32_t data) 131 { 132 if (address > 252) 133 return EINVAL; 134 pci_conf_write_32(PCI_FUN(fun), address, data); 135 return EOK; 136 } 137 138 static int pci_config_space_write_16( 139 ddf_fun_t *fun, uint32_t address, uint16_t data) 125 140 { 126 141 if (address > 254) … … 130 145 } 131 146 147 static int pci_config_space_write_8( 148 ddf_fun_t *fun, uint32_t address, uint8_t data) 149 { 150 if (address > 255) 151 return EINVAL; 152 pci_conf_write_8(PCI_FUN(fun), address, data); 153 return EOK; 154 } 155 156 static int pci_config_space_read_32( 157 ddf_fun_t *fun, uint32_t address, uint32_t *data) 158 { 159 if (address > 252) 160 return EINVAL; 161 *data = pci_conf_read_32(PCI_FUN(fun), address); 162 return EOK; 163 } 164 165 static int pci_config_space_read_16( 166 ddf_fun_t *fun, uint32_t address, uint16_t *data) 167 { 168 if (address > 254) 169 return EINVAL; 170 *data = pci_conf_read_16(PCI_FUN(fun), address); 171 return EOK; 172 } 173 174 static int pci_config_space_read_8( 175 ddf_fun_t *fun, uint32_t address, uint8_t *data) 176 { 177 if (address > 255) 178 return EINVAL; 179 *data = pci_conf_read_8(PCI_FUN(fun), address); 180 return EOK; 181 } 132 182 133 183 static hw_res_ops_t pciintel_hw_res_ops = { … … 137 187 138 188 static pci_dev_iface_t pci_dev_ops = { 139 .config_space_read_8 = NULL,140 .config_space_read_16 = NULL,141 .config_space_read_32 = NULL,142 .config_space_write_8 = NULL,189 .config_space_read_8 = &pci_config_space_read_8, 190 .config_space_read_16 = &pci_config_space_read_16, 191 .config_space_read_32 = &pci_config_space_read_32, 192 .config_space_write_8 = &pci_config_space_write_8, 143 193 .config_space_write_16 = &pci_config_space_write_16, 144 .config_space_write_32 = NULL194 .config_space_write_32 = &pci_config_space_write_32 145 195 }; 146 196 -
uspace/drv/uhci-hcd/batch.c
r0588062e r8e9becf6 35 35 #include <str_error.h> 36 36 37 #include <usb/usb.h> 37 38 #include <usb/debug.h> 38 39 … … 46 47 static int batch_schedule(batch_t *instance); 47 48 49 static void batch_control(batch_t *instance, 50 usb_packet_id data_stage, usb_packet_id status_stage); 51 static void batch_data(batch_t *instance, usb_packet_id pid); 48 52 static void batch_call_in(batch_t *instance); 49 53 static void batch_call_out(batch_t *instance); 50 54 static void batch_call_in_and_dispose(batch_t *instance); 51 55 static void batch_call_out_and_dispose(batch_t *instance); 52 53 56 static void batch_dispose(batch_t *instance); 57 58 59 /** Allocates memory and initializes internal data structures. 60 * 61 * @param[in] fun DDF function to pass to callback. 62 * @param[in] target Device and endpoint target of the transaction. 63 * @param[in] transfer_type Interrupt, Control or Bulk. 64 * @param[in] max_packet_size maximum allowed size of data packets. 65 * @param[in] speed Speed of the transaction. 66 * @param[in] buffer Data source/destination. 67 * @param[in] size Size of the buffer. 68 * @param[in] setup_buffer Setup data source (if not NULL) 69 * @param[in] setup_size Size of setup_buffer (should be always 8) 70 * @param[in] func_in function to call on inbound transaction completion 71 * @param[in] func_out function to call on outbound transaction completion 72 * @param[in] arg additional parameter to func_in or func_out 73 * @param[in] manager Pointer to toggle management structure. 74 * @return False, if there is an active TD, true otherwise. 75 */ 54 76 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target, 55 77 usb_transfer_type_t transfer_type, size_t max_packet_size, … … 57 79 char* setup_buffer, size_t setup_size, 58 80 usbhc_iface_transfer_in_callback_t func_in, 59 usbhc_iface_transfer_out_callback_t func_out, void *arg) 81 usbhc_iface_transfer_out_callback_t func_out, void *arg, 82 device_keeper_t *manager 83 ) 60 84 { 61 85 assert(func_in == NULL || func_out == NULL); 62 86 assert(func_in != NULL || func_out != NULL); 63 87 88 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \ 89 if (ptr == NULL) { \ 90 usb_log_error(message); \ 91 if (instance) { \ 92 batch_dispose(instance); \ 93 } \ 94 return NULL; \ 95 } else (void)0 96 64 97 batch_t *instance = malloc(sizeof(batch_t)); 65 if (instance == NULL) { 66 usb_log_error("Failed to allocate batch instance.\n"); 67 return NULL; 68 } 69 70 instance->qh = queue_head_get(); 71 if (instance->qh == NULL) { 72 usb_log_error("Failed to allocate queue head.\n"); 73 free(instance); 74 return NULL; 75 } 98 CHECK_NULL_DISPOSE_RETURN(instance, 99 "Failed to allocate batch instance.\n"); 100 bzero(instance, sizeof(batch_t)); 101 102 instance->qh = malloc32(sizeof(queue_head_t)); 103 CHECK_NULL_DISPOSE_RETURN(instance->qh, 104 "Failed to allocate batch queue head.\n"); 105 queue_head_init(instance->qh); 76 106 77 107 instance->packets = (size + max_packet_size - 1) / max_packet_size; … … 80 110 } 81 111 82 instance->tds = malloc32(sizeof(transfer_descriptor_t) * instance->packets); 83 if (instance->tds == NULL) { 84 usb_log_error("Failed to allocate transfer descriptors.\n"); 85 queue_head_dispose(instance->qh); 86 free(instance); 87 return NULL; 88 } 89 bzero(instance->tds, sizeof(transfer_descriptor_t) * instance->packets); 90 91 const size_t transport_size = max_packet_size * instance->packets; 92 93 instance->transport_buffer = 94 (size > 0) ? malloc32(transport_size) : NULL; 95 if ((size > 0) && (instance->transport_buffer == NULL)) { 96 usb_log_error("Failed to allocate device accessible buffer.\n"); 97 queue_head_dispose(instance->qh); 98 free32(instance->tds); 99 free(instance); 100 return NULL; 101 } 102 103 instance->setup_buffer = setup_buffer ? malloc32(setup_size) : NULL; 104 if ((setup_size > 0) && (instance->setup_buffer == NULL)) { 105 usb_log_error("Failed to allocate device accessible setup buffer.\n"); 106 queue_head_dispose(instance->qh); 107 free32(instance->tds); 108 free32(instance->transport_buffer); 109 free(instance); 110 return NULL; 111 } 112 if (instance->setup_buffer) { 112 instance->tds = malloc32(sizeof(td_t) * instance->packets); 113 CHECK_NULL_DISPOSE_RETURN( 114 instance->tds, "Failed to allocate transfer descriptors.\n"); 115 bzero(instance->tds, sizeof(td_t) * instance->packets); 116 117 // const size_t transport_size = max_packet_size * instance->packets; 118 119 if (size > 0) { 120 instance->transport_buffer = malloc32(size); 121 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer, 122 "Failed to allocate device accessible buffer.\n"); 123 } 124 125 if (setup_size > 0) { 126 instance->setup_buffer = malloc32(setup_size); 127 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer, 128 "Failed to allocate device accessible setup buffer.\n"); 113 129 memcpy(instance->setup_buffer, setup_buffer, setup_size); 114 130 } 115 131 132 133 link_initialize(&instance->link); 134 116 135 instance->max_packet_size = max_packet_size; 117 118 link_initialize(&instance->link);119 120 136 instance->target = target; 121 137 instance->transfer_type = transfer_type; 122 123 if (func_out)124 instance->callback_out = func_out;125 if (func_in)126 instance->callback_in = func_in;127 128 138 instance->buffer = buffer; 129 139 instance->buffer_size = size; … … 132 142 instance->arg = arg; 133 143 instance->speed = speed; 134 135 queue_head_element_td(instance->qh, addr_to_phys(instance->tds)); 144 instance->manager = manager; 145 146 if (func_out) 147 instance->callback_out = func_out; 148 if (func_in) 149 instance->callback_in = func_in; 150 151 queue_head_set_element_td(instance->qh, addr_to_phys(instance->tds)); 152 136 153 usb_log_debug("Batch(%p) %d:%d memory structures ready.\n", 137 154 instance, target.address, target.endpoint); … … 139 156 } 140 157 /*----------------------------------------------------------------------------*/ 158 /** Checks batch TDs for activity. 159 * 160 * @param[in] instance Batch structure to use. 161 * @return False, if there is an active TD, true otherwise. 162 */ 141 163 bool batch_is_complete(batch_t *instance) 142 164 { … … 147 169 size_t i = 0; 148 170 for (;i < instance->packets; ++i) { 149 if (t ransfer_descriptor_is_active(&instance->tds[i])) {171 if (td_is_active(&instance->tds[i])) { 150 172 return false; 151 173 } 152 instance->error = transfer_descriptor_status(&instance->tds[i]); 174 175 instance->error = td_status(&instance->tds[i]); 153 176 if (instance->error != EOK) { 177 usb_log_debug("Batch(%p) found error TD(%d):%x.\n", 178 instance, i, instance->tds[i].status); 179 180 device_keeper_set_toggle(instance->manager, 181 instance->target, td_toggle(&instance->tds[i])); 154 182 if (i > 0) 155 instance->transfered_size -= instance->setup_size; 156 usb_log_debug("Batch(%p) found error TD(%d):%x.\n", 157 instance, i, instance->tds[i].status); 183 goto substract_ret; 158 184 return true; 159 185 } 160 instance->transfered_size += 161 transfer_descriptor_actual_size(&instance->tds[i]); 162 } 186 187 instance->transfered_size += td_act_size(&instance->tds[i]); 188 if (td_is_short(&instance->tds[i])) 189 goto substract_ret; 190 } 191 substract_ret: 163 192 instance->transfered_size -= instance->setup_size; 164 193 return true; 165 194 } 166 195 /*----------------------------------------------------------------------------*/ 196 /** Prepares control write transaction. 197 * 198 * @param[in] instance Batch structure to use. 199 */ 167 200 void batch_control_write(batch_t *instance) 168 201 { 169 202 assert(instance); 170 203 /* we are data out, we are supposed to provide data */ 204 memcpy(instance->transport_buffer, instance->buffer, 205 instance->buffer_size); 206 batch_control(instance, USB_PID_OUT, USB_PID_IN); 207 instance->next_step = batch_call_out_and_dispose; 208 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 209 batch_schedule(instance); 210 } 211 /*----------------------------------------------------------------------------*/ 212 /** Prepares control read transaction. 213 * 214 * @param[in] instance Batch structure to use. 215 */ 216 void batch_control_read(batch_t *instance) 217 { 218 assert(instance); 219 batch_control(instance, USB_PID_IN, USB_PID_OUT); 220 instance->next_step = batch_call_in_and_dispose; 221 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 222 batch_schedule(instance); 223 } 224 /*----------------------------------------------------------------------------*/ 225 /** Prepares interrupt in transaction. 226 * 227 * @param[in] instance Batch structure to use. 228 */ 229 void batch_interrupt_in(batch_t *instance) 230 { 231 assert(instance); 232 batch_data(instance, USB_PID_IN); 233 instance->next_step = batch_call_in_and_dispose; 234 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 235 batch_schedule(instance); 236 } 237 /*----------------------------------------------------------------------------*/ 238 /** Prepares interrupt out transaction. 239 * 240 * @param[in] instance Batch structure to use. 241 */ 242 void batch_interrupt_out(batch_t *instance) 243 { 244 assert(instance); 171 245 /* we are data out, we are supposed to provide data */ 172 246 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 247 batch_data(instance, USB_PID_OUT); 248 instance->next_step = batch_call_out_and_dispose; 249 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 250 batch_schedule(instance); 251 } 252 /*----------------------------------------------------------------------------*/ 253 /** Prepares bulk in transaction. 254 * 255 * @param[in] instance Batch structure to use. 256 */ 257 void batch_bulk_in(batch_t *instance) 258 { 259 assert(instance); 260 batch_data(instance, USB_PID_IN); 261 instance->next_step = batch_call_in_and_dispose; 262 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 263 batch_schedule(instance); 264 } 265 /*----------------------------------------------------------------------------*/ 266 /** Prepares bulk out transaction. 267 * 268 * @param[in] instance Batch structure to use. 269 */ 270 void batch_bulk_out(batch_t *instance) 271 { 272 assert(instance); 273 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 274 batch_data(instance, USB_PID_OUT); 275 instance->next_step = batch_call_out_and_dispose; 276 usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance); 277 batch_schedule(instance); 278 } 279 /*----------------------------------------------------------------------------*/ 280 /** Prepares generic data transaction 281 * 282 * @param[in] instance Batch structure to use. 283 * @param[in] pid to use for data packets. 284 */ 285 void batch_data(batch_t *instance, usb_packet_id pid) 286 { 287 assert(instance); 288 const bool low_speed = instance->speed == USB_SPEED_LOW; 289 int toggle = 290 device_keeper_get_toggle(instance->manager, instance->target); 291 assert(toggle == 0 || toggle == 1); 292 293 size_t packet = 0; 294 size_t remain_size = instance->buffer_size; 295 while (remain_size > 0) { 296 char *data = 297 instance->transport_buffer + instance->buffer_size 298 - remain_size; 299 300 const size_t packet_size = 301 (instance->max_packet_size > remain_size) ? 302 remain_size : instance->max_packet_size; 303 304 td_t *next_packet = (packet + 1 < instance->packets) 305 ? &instance->tds[packet + 1] : NULL; 306 307 assert(packet < instance->packets); 308 assert(packet_size <= remain_size); 309 310 td_init( 311 &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size, 312 toggle, false, low_speed, instance->target, pid, data, 313 next_packet); 314 315 316 toggle = 1 - toggle; 317 remain_size -= packet_size; 318 ++packet; 319 } 320 device_keeper_set_toggle(instance->manager, instance->target, toggle); 321 } 322 /*----------------------------------------------------------------------------*/ 323 /** Prepares generic control transaction 324 * 325 * @param[in] instance Batch structure to use. 326 * @param[in] data_stage to use for data packets. 327 * @param[in] status_stage to use for data packets. 328 */ 329 void batch_control(batch_t *instance, 330 usb_packet_id data_stage, usb_packet_id status_stage) 331 { 332 assert(instance); 173 333 174 334 const bool low_speed = instance->speed == USB_SPEED_LOW; 175 335 int toggle = 0; 176 336 /* setup stage */ 177 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 178 instance->setup_size, toggle, false, low_speed, 179 instance->target, USB_PID_SETUP, instance->setup_buffer, 180 &instance->tds[1]); 181 182 /* data stage */ 183 size_t i = 1; 184 for (;i < instance->packets - 1; ++i) { 185 char *data = 186 instance->transport_buffer + ((i - 1) * instance->max_packet_size); 187 toggle = 1 - toggle; 188 189 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 190 instance->max_packet_size, toggle++, false, low_speed, 191 instance->target, USB_PID_OUT, data, &instance->tds[i + 1]); 192 } 193 194 /* status stage */ 195 i = instance->packets - 1; 196 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 197 0, 1, false, low_speed, instance->target, USB_PID_IN, NULL, NULL); 198 199 instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 200 usb_log_debug2("Control write last TD status: %x.\n", 201 instance->tds[i].status); 202 203 instance->next_step = batch_call_out_and_dispose; 204 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 205 batch_schedule(instance); 206 } 207 /*----------------------------------------------------------------------------*/ 208 void batch_control_read(batch_t *instance) 209 { 210 assert(instance); 211 212 const bool low_speed = instance->speed == USB_SPEED_LOW; 213 int toggle = 0; 214 /* setup stage */ 215 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 337 td_init(instance->tds, DEFAULT_ERROR_COUNT, 216 338 instance->setup_size, toggle, false, low_speed, instance->target, 217 339 USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]); 218 340 219 341 /* data stage */ 220 size_t i = 1; 221 for (;i < instance->packets - 1; ++i) { 342 size_t packet = 1; 343 size_t remain_size = instance->buffer_size; 344 while (remain_size > 0) { 222 345 char *data = 223 instance->transport_buffer + ((i - 1) * instance->max_packet_size); 346 instance->transport_buffer + instance->buffer_size 347 - remain_size; 348 224 349 toggle = 1 - toggle; 225 350 226 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 227 instance->max_packet_size, toggle, false, low_speed, 228 instance->target, USB_PID_IN, data, &instance->tds[i + 1]); 351 const size_t packet_size = 352 (instance->max_packet_size > remain_size) ? 353 remain_size : instance->max_packet_size; 354 355 td_init( 356 &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size, 357 toggle, false, low_speed, instance->target, data_stage, 358 data, &instance->tds[packet + 1]); 359 360 ++packet; 361 assert(packet < instance->packets); 362 assert(packet_size <= remain_size); 363 remain_size -= packet_size; 229 364 } 230 365 231 366 /* status stage */ 232 i = instance->packets - 1; 233 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 234 0, 1, false, low_speed, instance->target, USB_PID_OUT, NULL, NULL); 235 236 instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 237 usb_log_debug2("Control read last TD status: %x.\n", 238 instance->tds[i].status); 239 240 instance->next_step = batch_call_in_and_dispose; 241 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 242 batch_schedule(instance); 243 } 244 /*----------------------------------------------------------------------------*/ 245 void batch_interrupt_in(batch_t *instance) 246 { 247 assert(instance); 248 249 const bool low_speed = instance->speed == USB_SPEED_LOW; 250 int toggle = 1; 251 size_t i = 0; 252 for (;i < instance->packets; ++i) { 253 char *data = 254 instance->transport_buffer + (i * instance->max_packet_size); 255 transfer_descriptor_t *next = (i + 1) < instance->packets ? 256 &instance->tds[i + 1] : NULL; 257 toggle = 1 - toggle; 258 259 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 260 instance->max_packet_size, toggle, false, low_speed, 261 instance->target, USB_PID_IN, data, next); 262 } 263 264 instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 265 266 instance->next_step = batch_call_in_and_dispose; 267 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 268 batch_schedule(instance); 269 } 270 /*----------------------------------------------------------------------------*/ 271 void batch_interrupt_out(batch_t *instance) 272 { 273 assert(instance); 274 275 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 276 277 const bool low_speed = instance->speed == USB_SPEED_LOW; 278 int toggle = 1; 279 size_t i = 0; 280 for (;i < instance->packets; ++i) { 281 char *data = 282 instance->transport_buffer + (i * instance->max_packet_size); 283 transfer_descriptor_t *next = (i + 1) < instance->packets ? 284 &instance->tds[i + 1] : NULL; 285 toggle = 1 - toggle; 286 287 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 288 instance->max_packet_size, toggle++, false, low_speed, 289 instance->target, USB_PID_OUT, data, next); 290 } 291 292 instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 293 294 instance->next_step = batch_call_out_and_dispose; 295 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 296 batch_schedule(instance); 297 } 298 /*----------------------------------------------------------------------------*/ 367 assert(packet == instance->packets - 1); 368 td_init(&instance->tds[packet], DEFAULT_ERROR_COUNT, 369 0, 1, false, low_speed, instance->target, status_stage, NULL, NULL); 370 371 372 instance->tds[packet].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 373 usb_log_debug2("Control last TD status: %x.\n", 374 instance->tds[packet].status); 375 } 376 /*----------------------------------------------------------------------------*/ 377 /** Prepares data, gets error status and calls callback in. 378 * 379 * @param[in] instance Batch structure to use. 380 */ 299 381 void batch_call_in(batch_t *instance) 300 382 { … … 302 384 assert(instance->callback_in); 303 385 304 memcpy(instance->buffer, instance->transport_buffer, instance->buffer_size); 386 /* we are data in, we need data */ 387 memcpy(instance->buffer, instance->transport_buffer, 388 instance->buffer_size); 305 389 306 390 int err = instance->error; … … 309 393 instance->transfered_size); 310 394 311 instance->callback_in(instance->fun, 312 err, instance->transfered_size, 313 instance->arg); 314 } 315 /*----------------------------------------------------------------------------*/ 395 instance->callback_in( 396 instance->fun, err, instance->transfered_size, instance->arg); 397 } 398 /*----------------------------------------------------------------------------*/ 399 /** Gets error status and calls callback out. 400 * 401 * @param[in] instance Batch structure to use. 402 */ 316 403 void batch_call_out(batch_t *instance) 317 404 { … … 326 413 } 327 414 /*----------------------------------------------------------------------------*/ 415 /** Prepares data, gets error status, calls callback in and dispose. 416 * 417 * @param[in] instance Batch structure to use. 418 */ 328 419 void batch_call_in_and_dispose(batch_t *instance) 329 420 { 330 421 assert(instance); 331 422 batch_call_in(instance); 423 batch_dispose(instance); 424 } 425 /*----------------------------------------------------------------------------*/ 426 /** Gets error status, calls callback out and dispose. 427 * 428 * @param[in] instance Batch structure to use. 429 */ 430 void batch_call_out_and_dispose(batch_t *instance) 431 { 432 assert(instance); 433 batch_call_out(instance); 434 batch_dispose(instance); 435 } 436 /*----------------------------------------------------------------------------*/ 437 /** Correctly disposes all used data structures. 438 * 439 * @param[in] instance Batch structure to use. 440 */ 441 void batch_dispose(batch_t *instance) 442 { 443 assert(instance); 332 444 usb_log_debug("Batch(%p) disposing.\n", instance); 445 /* free32 is NULL safe */ 333 446 free32(instance->tds); 334 447 free32(instance->qh); … … 338 451 } 339 452 /*----------------------------------------------------------------------------*/ 340 void batch_call_out_and_dispose(batch_t *instance)341 {342 assert(instance);343 batch_call_out(instance);344 usb_log_debug("Batch(%p) disposing.\n", instance);345 free32(instance->tds);346 free32(instance->qh);347 free32(instance->setup_buffer);348 free32(instance->transport_buffer);349 free(instance);350 }351 /*----------------------------------------------------------------------------*/352 453 int batch_schedule(batch_t *instance) 353 454 { -
uspace/drv/uhci-hcd/batch.h
r0588062e r8e9becf6 42 42 #include "uhci_struct/transfer_descriptor.h" 43 43 #include "uhci_struct/queue_head.h" 44 #include "utils/device_keeper.h" 44 45 45 46 typedef struct batch … … 65 66 ddf_fun_t *fun; 66 67 queue_head_t *qh; 67 t ransfer_descriptor_t *tds;68 td_t *tds; 68 69 void (*next_step)(struct batch*); 70 device_keeper_t *manager; 69 71 } batch_t; 70 72 … … 74 76 char *setup_buffer, size_t setup_size, 75 77 usbhc_iface_transfer_in_callback_t func_in, 76 usbhc_iface_transfer_out_callback_t func_out, void *arg); 78 usbhc_iface_transfer_out_callback_t func_out, void *arg, 79 device_keeper_t *manager 80 ); 77 81 78 82 bool batch_is_complete(batch_t *instance); … … 86 90 void batch_interrupt_out(batch_t *instance); 87 91 88 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */ 89 void batch_control_setup_old(batch_t *instance); 92 void batch_bulk_in(batch_t *instance); 90 93 91 void batch_control_write_data_old(batch_t *instance); 92 93 void batch_control_read_data_old(batch_t *instance); 94 95 void batch_control_write_status_old(batch_t *instance); 96 97 void batch_control_read_status_old(batch_t *instance); 94 void batch_bulk_out(batch_t *instance); 98 95 #endif 99 96 /** -
uspace/drv/uhci-hcd/iface.c
r0588062e r8e9becf6 43 43 #include "utils/device_keeper.h" 44 44 45 /** Reserve default address interface function 46 * 47 * @param[in] fun DDF function that was called. 48 * @param[in] speed Speed to associate with the new default address. 49 * @return Error code. 50 */ 45 51 /*----------------------------------------------------------------------------*/ 46 52 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) … … 54 60 } 55 61 /*----------------------------------------------------------------------------*/ 62 /** Release default address interface function 63 * 64 * @param[in] fun DDF function that was called. 65 * @return Error code. 66 */ 56 67 static int release_default_address(ddf_fun_t *fun) 57 68 { … … 64 75 } 65 76 /*----------------------------------------------------------------------------*/ 77 /** Request address interface function 78 * 79 * @param[in] fun DDF function that was called. 80 * @param[in] speed Speed to associate with the new default address. 81 * @param[out] address Place to write a new address. 82 * @return Error code. 83 */ 66 84 static int request_address(ddf_fun_t *fun, usb_speed_t speed, 67 85 usb_address_t *address) … … 80 98 } 81 99 /*----------------------------------------------------------------------------*/ 100 /** Bind address interface function 101 * 102 * @param[in] fun DDF function that was called. 103 * @param[in] address Address of the device 104 * @param[in] handle Devman handle of the device driver. 105 * @return Error code. 106 */ 82 107 static int bind_address( 83 108 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) … … 91 116 } 92 117 /*----------------------------------------------------------------------------*/ 118 /** Release address interface function 119 * 120 * @param[in] fun DDF function that was called. 121 * @param[in] address USB address to be released. 122 * @return Error code. 123 */ 93 124 static int release_address(ddf_fun_t *fun, usb_address_t address) 94 125 { … … 101 132 } 102 133 /*----------------------------------------------------------------------------*/ 134 /** Interrupt out transaction interface function 135 * 136 * @param[in] fun DDF function that was called. 137 * @param[in] target USB device to write to. 138 * @param[in] max_packet_size maximum size of data packet the device accepts 139 * @param[in] data Source of data. 140 * @param[in] size Size of data source. 141 * @param[in] callback Function to call on transaction completion 142 * @param[in] arg Additional for callback function. 143 * @return Error code. 144 */ 103 145 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 104 146 size_t max_packet_size, void *data, size_t size, … … 114 156 115 157 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 116 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg); 158 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 159 &hc->device_manager); 117 160 if (!batch) 118 161 return ENOMEM; … … 121 164 } 122 165 /*----------------------------------------------------------------------------*/ 166 /** Interrupt in transaction interface function 167 * 168 * @param[in] fun DDF function that was called. 169 * @param[in] target USB device to write to. 170 * @param[in] max_packet_size maximum size of data packet the device accepts 171 * @param[out] data Data destination. 172 * @param[in] size Size of data source. 173 * @param[in] callback Function to call on transaction completion 174 * @param[in] arg Additional for callback function. 175 * @return Error code. 176 */ 123 177 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 124 178 size_t max_packet_size, void *data, size_t size, … … 133 187 134 188 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 135 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg); 189 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 190 &hc->device_manager); 136 191 if (!batch) 137 192 return ENOMEM; … … 140 195 } 141 196 /*----------------------------------------------------------------------------*/ 197 /** Bulk out transaction interface function 198 * 199 * @param[in] fun DDF function that was called. 200 * @param[in] target USB device to write to. 201 * @param[in] max_packet_size maximum size of data packet the device accepts 202 * @param[in] data Source of data. 203 * @param[in] size Size of data source. 204 * @param[in] callback Function to call on transaction completion 205 * @param[in] arg Additional for callback function. 206 * @return Error code. 207 */ 208 static int bulk_out(ddf_fun_t *fun, usb_target_t target, 209 size_t max_packet_size, void *data, size_t size, 210 usbhc_iface_transfer_out_callback_t callback, void *arg) 211 { 212 assert(fun); 213 uhci_t *hc = fun_to_uhci(fun); 214 assert(hc); 215 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 216 217 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 218 target.address, target.endpoint, size, max_packet_size); 219 220 batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 221 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 222 &hc->device_manager); 223 if (!batch) 224 return ENOMEM; 225 batch_bulk_out(batch); 226 return EOK; 227 } 228 /*----------------------------------------------------------------------------*/ 229 /** Bulk in transaction interface function 230 * 231 * @param[in] fun DDF function that was called. 232 * @param[in] target USB device to write to. 233 * @param[in] max_packet_size maximum size of data packet the device accepts 234 * @param[out] data Data destination. 235 * @param[in] size Size of data source. 236 * @param[in] callback Function to call on transaction completion 237 * @param[in] arg Additional for callback function. 238 * @return Error code. 239 */ 240 static int bulk_in(ddf_fun_t *fun, usb_target_t target, 241 size_t max_packet_size, void *data, size_t size, 242 usbhc_iface_transfer_in_callback_t callback, void *arg) 243 { 244 assert(fun); 245 uhci_t *hc = fun_to_uhci(fun); 246 assert(hc); 247 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 248 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 249 target.address, target.endpoint, size, max_packet_size); 250 251 batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 252 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 253 &hc->device_manager); 254 if (!batch) 255 return ENOMEM; 256 batch_bulk_in(batch); 257 return EOK; 258 } 259 /*----------------------------------------------------------------------------*/ 260 /** Control write transaction interface function 261 * 262 * @param[in] fun DDF function that was called. 263 * @param[in] target USB device to write to. 264 * @param[in] max_packet_size maximum size of data packet the device accepts. 265 * @param[in] setup_data Data to send with SETUP packet. 266 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B). 267 * @param[in] data Source of data. 268 * @param[in] size Size of data source. 269 * @param[in] callback Function to call on transaction completion. 270 * @param[in] arg Additional for callback function. 271 * @return Error code. 272 */ 142 273 static int control_write(ddf_fun_t *fun, usb_target_t target, 143 274 size_t max_packet_size, … … 152 283 target.address, target.endpoint, size, max_packet_size); 153 284 285 if (setup_size != 8) 286 return EINVAL; 287 154 288 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 155 289 max_packet_size, speed, data, size, setup_data, setup_size, 156 NULL, callback, arg); 157 if (!batch) 158 return ENOMEM; 290 NULL, callback, arg, &hc->device_manager); 291 if (!batch) 292 return ENOMEM; 293 device_keeper_reset_if_need(&hc->device_manager, target, setup_data); 159 294 batch_control_write(batch); 160 295 return EOK; 161 296 } 162 297 /*----------------------------------------------------------------------------*/ 298 /** Control read transaction interface function 299 * 300 * @param[in] fun DDF function that was called. 301 * @param[in] target USB device to write to. 302 * @param[in] max_packet_size maximum size of data packet the device accepts. 303 * @param[in] setup_data Data to send with SETUP packet. 304 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B). 305 * @param[out] data Source of data. 306 * @param[in] size Size of data source. 307 * @param[in] callback Function to call on transaction completion. 308 * @param[in] arg Additional for callback function. 309 * @return Error code. 310 */ 163 311 static int control_read(ddf_fun_t *fun, usb_target_t target, 164 312 size_t max_packet_size, … … 175 323 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 176 324 max_packet_size, speed, data, size, setup_data, setup_size, callback, 177 NULL, arg );325 NULL, arg, &hc->device_manager); 178 326 if (!batch) 179 327 return ENOMEM; … … 181 329 return EOK; 182 330 } 183 184 185 331 /*----------------------------------------------------------------------------*/ 186 332 usbhc_iface_t uhci_iface = { … … 194 340 .interrupt_in = interrupt_in, 195 341 342 .bulk_in = bulk_in, 343 .bulk_out = bulk_out, 344 196 345 .control_read = control_read, 197 346 .control_write = control_write, -
uspace/drv/uhci-hcd/main.c
r0588062e r8e9becf6 60 60 }; 61 61 /*----------------------------------------------------------------------------*/ 62 /** IRQ handling callback, identifies devic 63 * 64 * @param[in] dev DDF instance of the device to use. 65 * @param[in] iid (Unused). 66 * @param[in] call Pointer to the call that represents interrupt. 67 */ 62 68 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 63 69 { … … 69 75 } 70 76 /*----------------------------------------------------------------------------*/ 71 static int uhci_add_device(ddf_dev_t *device) 77 /** Initializes a new ddf driver instance of UHCI hcd. 78 * 79 * @param[in] device DDF instance of the device to initialize. 80 * @return Error code. 81 * 82 * Gets and initialies hardware resources, disables any legacy support, 83 * and reports root hub device. 84 */ 85 int uhci_add_device(ddf_dev_t *device) 72 86 { 73 87 assert(device); … … 96 110 ret = pci_disable_legacy(device); 97 111 CHECK_RET_FREE_HC_RETURN(ret, 98 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));112 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 99 113 100 114 #if 0 … … 113 127 114 128 ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size); 115 CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", 116 ret); 129 CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret); 117 130 #undef CHECK_RET_FREE_HC_RETURN 118 131 … … 155 168 } 156 169 /*----------------------------------------------------------------------------*/ 170 /** Initializes global driver structures (NONE). 171 * 172 * @param[in] argc Nmber of arguments in argv vector (ignored). 173 * @param[in] argv Cmdline argument vector (ignored). 174 * @return Error code. 175 * 176 * Driver debug level is set here. 177 */ 157 178 int main(int argc, char *argv[]) 158 179 { -
uspace/drv/uhci-hcd/pci.c
r0588062e r8e9becf6 65 65 66 66 int rc; 67 68 67 hw_resource_list_t hw_resources; 69 68 rc = hw_res_get_resource_list(parent_phone, &hw_resources); … … 82 81 for (i = 0; i < hw_resources.count; i++) { 83 82 hw_resource_t *res = &hw_resources.resources[i]; 84 switch (res->type) { 85 case INTERRUPT: 86 irq = res->res.interrupt.irq; 87 irq_found = true; 88 usb_log_debug2("Found interrupt: %d.\n", irq); 89 break; 90 case IO_RANGE: 91 io_address = res->res.io_range.address; 92 io_size = res->res.io_range.size; 93 usb_log_debug2("Found io: %llx %zu.\n", 94 res->res.io_range.address, res->res.io_range.size); 95 io_found = true; 96 break; 97 default: 98 break; 83 switch (res->type) 84 { 85 case INTERRUPT: 86 irq = res->res.interrupt.irq; 87 irq_found = true; 88 usb_log_debug2("Found interrupt: %d.\n", irq); 89 break; 90 91 case IO_RANGE: 92 io_address = res->res.io_range.address; 93 io_size = res->res.io_range.size; 94 usb_log_debug2("Found io: %llx %zu.\n", 95 res->res.io_range.address, res->res.io_range.size); 96 io_found = true; 97 98 default: 99 break; 99 100 } 100 101 } 101 102 102 if (!io_found) { 103 rc = ENOENT; 104 goto leave; 105 } 106 107 if (!irq_found) { 103 if (!io_found || !irq_found) { 108 104 rc = ENOENT; 109 105 goto leave; … … 121 117 } 122 118 /*----------------------------------------------------------------------------*/ 119 /** Calls the PCI driver with a request to enable interrupts 120 * 121 * @param[in] device Device asking for interrupts 122 * @return Error code. 123 */ 123 124 int pci_enable_interrupts(ddf_dev_t *device) 124 125 { … … 130 131 } 131 132 /*----------------------------------------------------------------------------*/ 133 /** Calls the PCI driver with a request to clear legacy support register 134 * 135 * @param[in] device Device asking to disable interrupts 136 * @return Error code. 137 */ 132 138 int pci_disable_legacy(ddf_dev_t *device) 133 139 { 134 140 assert(device); 135 int parent_phone = devman_parent_device_connect(device->handle,136 141 int parent_phone = 142 devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING); 137 143 if (parent_phone < 0) { 138 144 return parent_phone; … … 144 150 sysarg_t value = 0x8f00; 145 151 146 152 int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 147 153 IPC_M_CONFIG_SPACE_WRITE_16, address, value); 148 154 async_hangup(parent_phone); 149 155 150 156 return rc; 151 157 } 152 158 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/root_hub.c
r0588062e r8e9becf6 45 45 46 46 /*----------------------------------------------------------------------------*/ 47 static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun, 48 devman_handle_t *handle) 47 /** Gets handle of the respective hc (parent device). 48 * 49 * @param[in] root_hub_fun Root hub function seeking hc handle. 50 * @param[out] handle Place to write the handle. 51 * @return Error code. 52 */ 53 static int usb_iface_get_hc_handle_rh_impl( 54 ddf_fun_t *root_hub_fun, devman_handle_t *handle) 49 55 { 56 /* TODO: Can't this use parent pointer? */ 50 57 ddf_fun_t *hc_fun = root_hub_fun->driver_data; 51 58 assert(hc_fun != NULL); … … 56 63 } 57 64 /*----------------------------------------------------------------------------*/ 58 static int usb_iface_get_address_rh_impl(ddf_fun_t *fun, devman_handle_t handle, 59 usb_address_t *address) 65 /** Gets USB address of the calling device. 66 * 67 * @param[in] fun Root hub function. 68 * @param[in] handle Handle of the device seeking address. 69 * @param[out] address Place to store found address. 70 * @return Error code. 71 */ 72 static int usb_iface_get_address_rh_impl( 73 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address) 60 74 { 75 /* TODO: What does this do? Is it neccessary? Can't it use implemented 76 * hc function?*/ 61 77 assert(fun); 62 78 ddf_fun_t *hc_fun = fun->driver_data; … … 65 81 assert(hc); 66 82 67 usb_address_t addr = device_keeper_find(&hc->device_manager, 68 handle); 83 usb_address_t addr = device_keeper_find(&hc->device_manager, handle); 69 84 if (addr < 0) { 70 85 return addr; … … 83 98 }; 84 99 /*----------------------------------------------------------------------------*/ 100 /** Gets root hub hw resources. 101 * 102 * @param[in] fun Root hub function. 103 * @return Pointer to the resource list used by the root hub. 104 */ 85 105 static hw_resource_list_t *get_resource_list(ddf_fun_t *dev) 86 106 { … … 91 111 assert(hc); 92 112 93 / /TODO: fix memory leak113 /* TODO: fix memory leak */ 94 114 hw_resource_list_t *resource_list = malloc(sizeof(hw_resource_list_t)); 95 115 assert(resource_list); -
uspace/drv/uhci-hcd/transfer_list.c
r0588062e r8e9becf6 38 38 #include "transfer_list.h" 39 39 40 static void transfer_list_remove_batch( 41 transfer_list_t *instance, batch_t *batch); 42 /*----------------------------------------------------------------------------*/ 43 /** Initializes transfer list structures. 44 * 45 * @param[in] instance Memory place to use. 46 * @param[in] name Name of te new list. 47 * @return Error code 48 * 49 * Allocates memory for internat queue_head_t structure. 50 */ 40 51 int transfer_list_init(transfer_list_t *instance, const char *name) 41 52 { … … 43 54 instance->next = NULL; 44 55 instance->name = name; 45 instance->queue_head = queue_head_get();56 instance->queue_head = malloc32(sizeof(queue_head_t)); 46 57 if (!instance->queue_head) { 47 58 usb_log_error("Failed to allocate queue head.\n"); 48 59 return ENOMEM; 49 60 } 50 instance->queue_head_pa = (uintptr_t)addr_to_phys(instance->queue_head);61 instance->queue_head_pa = addr_to_phys(instance->queue_head); 51 62 52 63 queue_head_init(instance->queue_head); … … 56 67 } 57 68 /*----------------------------------------------------------------------------*/ 69 /** Set the next list in chain. 70 * 71 * @param[in] instance List to lead. 72 * @param[in] next List to append. 73 * @return Error code 74 */ 58 75 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next) 59 76 { … … 66 83 } 67 84 /*----------------------------------------------------------------------------*/ 85 /** Submits a new transfer batch to list and queue. 86 * 87 * @param[in] instance List to use. 88 * @param[in] batch Transfer batch to submit. 89 * @return Error code 90 */ 68 91 void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch) 69 92 { 70 93 assert(instance); 71 94 assert(batch); 72 usb_log_debug2("Adding batch(%p) to queue %s.\n", batch, instance->name); 95 usb_log_debug2( 96 "Adding batch(%p) to queue %s.\n", batch, instance->name); 73 97 74 98 uint32_t pa = (uintptr_t)addr_to_phys(batch->qh); … … 97 121 queue_head_append_qh(last->qh, pa); 98 122 list_append(&batch->link, &instance->batch_list); 123 99 124 usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n", 100 batch, instance->name, first 125 batch, instance->name, first); 101 126 fibril_mutex_unlock(&instance->guard); 102 127 } 103 128 /*----------------------------------------------------------------------------*/ 104 static void transfer_list_remove_batch( 105 transfer_list_t *instance, batch_t *batch) 129 /** Removes a transfer batch from list and queue. 130 * 131 * @param[in] instance List to use. 132 * @param[in] batch Transfer batch to remove. 133 * @return Error code 134 */ 135 void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch) 106 136 { 107 137 assert(instance); … … 109 139 assert(instance->queue_head); 110 140 assert(batch->qh); 111 usb_log_debug2("Removing batch(%p) from queue %s.\n", batch, instance->name); 141 usb_log_debug2( 142 "Removing batch(%p) from queue %s.\n", batch, instance->name); 112 143 113 /* I'm the first one here */114 144 if (batch->link.prev == &instance->batch_list) { 115 usb_log_debug("Batch(%p) removed (FIRST) from queue %s, next element %x.\n", 116 batch, instance->name, batch->qh->next_queue); 145 /* I'm the first one here */ 146 usb_log_debug( 147 "Batch(%p) removed (FIRST) from %s, next element %x.\n", 148 batch, instance->name, batch->qh->next_queue); 117 149 instance->queue_head->element = batch->qh->next_queue; 118 150 } else { 119 usb_log_debug("Batch(%p) removed (NOT FIRST) from queue, next element %x.\n", 120 batch, instance->name, batch->qh->next_queue); 121 batch_t *prev = list_get_instance(batch->link.prev, batch_t, link); 151 usb_log_debug( 152 "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n", 153 batch, instance->name, batch->qh->next_queue); 154 batch_t *prev = 155 list_get_instance(batch->link.prev, batch_t, link); 122 156 prev->qh->next_queue = batch->qh->next_queue; 123 157 } … … 125 159 } 126 160 /*----------------------------------------------------------------------------*/ 161 /** Checks list for finished transfers. 162 * 163 * @param[in] instance List to use. 164 * @return Error code 165 */ 127 166 void transfer_list_remove_finished(transfer_list_t *instance) 128 167 { -
uspace/drv/uhci-hcd/transfer_list.h
r0588062e r8e9becf6 58 58 { 59 59 assert(instance); 60 queue_head_dispose(instance->queue_head);60 free32(instance->queue_head); 61 61 } 62 62 void transfer_list_remove_finished(transfer_list_t *instance); -
uspace/drv/uhci-hcd/uhci.c
r0588062e r8e9becf6 61 61 }; 62 62 63 static int usb_iface_get_address(ddf_fun_t *fun, devman_handle_t handle, 64 usb_address_t *address) 63 /** Gets USB address of the calling device. 64 * 65 * @param[in] fun UHCI hc function. 66 * @param[in] handle Handle of the device seeking address. 67 * @param[out] address Place to store found address. 68 * @return Error code. 69 */ 70 static int usb_iface_get_address( 71 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address) 65 72 { 66 73 assert(fun); … … 99 106 100 107 static bool allowed_usb_packet( 101 bool low_speed, usb_transfer_type_t, size_t size); 102 103 108 bool low_speed, usb_transfer_type_t transfer, size_t size); 109 /*----------------------------------------------------------------------------*/ 110 /** Initializes UHCI hcd driver structure 111 * 112 * @param[in] instance Memory place to initialize. 113 * @param[in] dev DDF device. 114 * @param[in] regs Address of I/O control registers. 115 * @param[in] size Size of I/O control registers. 116 * @return Error code. 117 * @note Should be called only once on any structure. 118 */ 104 119 int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size) 105 120 { … … 156 171 } 157 172 /*----------------------------------------------------------------------------*/ 173 /** Initializes UHCI hcd hw resources. 174 * 175 * @param[in] instance UHCI structure to use. 176 */ 158 177 void uhci_init_hw(uhci_t *instance) 159 178 { 160 179 assert(instance); 161 162 /* reset everything, who knows what touched it before us */ 163 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET); 180 regs_t *registers = instance->registers; 181 182 /* Reset everything, who knows what touched it before us */ 183 pio_write_16(®isters->usbcmd, UHCI_CMD_GLOBAL_RESET); 164 184 async_usleep(10000); /* 10ms according to USB spec */ 165 pio_write_16(& instance->registers->usbcmd, 0);166 167 /* reset hc, all states and counters */168 pio_write_16(& instance->registers->usbcmd, UHCI_CMD_HCRESET);169 while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)170 { async_usleep(10); }171 172 /* set framelist pointer */185 pio_write_16(®isters->usbcmd, 0); 186 187 /* Reset hc, all states and counters */ 188 pio_write_16(®isters->usbcmd, UHCI_CMD_HCRESET); 189 do { async_usleep(10); } 190 while ((pio_read_16(®isters->usbcmd) & UHCI_CMD_HCRESET) != 0); 191 192 /* Set framelist pointer */ 173 193 const uint32_t pa = addr_to_phys(instance->frame_list); 174 pio_write_32(&instance->registers->flbaseadd, pa); 175 176 /* enable all interrupts, but resume interrupt */ 177 pio_write_16(&instance->registers->usbintr, 178 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 194 pio_write_32(®isters->flbaseadd, pa); 195 196 /* Enable all interrupts, but resume interrupt */ 197 // pio_write_16(&instance->registers->usbintr, 198 // UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 199 200 uint16_t status = pio_read_16(®isters->usbcmd); 201 if (status != 0) 202 usb_log_warning("Previous command value: %x.\n", status); 179 203 180 204 /* Start the hc with large(64B) packet FSBR */ 181 pio_write_16(& instance->registers->usbcmd,205 pio_write_16(®isters->usbcmd, 182 206 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE); 183 207 } 184 208 /*----------------------------------------------------------------------------*/ 209 /** Initializes UHCI hcd memory structures. 210 * 211 * @param[in] instance UHCI structure to use. 212 * @return Error code 213 * @note Should be called only once on any structure. 214 */ 185 215 int uhci_init_mem_structures(uhci_t *instance) 186 216 { … … 194 224 } else (void) 0 195 225 196 /* init interrupt code */226 /* Init interrupt code */ 197 227 instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds)); 198 228 int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK; 199 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to allocate interrupt cmds space.\n"); 229 CHECK_RET_DEST_CMDS_RETURN(ret, 230 "Failed to allocate interrupt cmds space.\n"); 200 231 201 232 { 202 233 irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds; 203 234 memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds)); 204 interrupt_commands[0].addr = (void*)&instance->registers->usbsts; 205 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 235 interrupt_commands[0].addr = 236 (void*)&instance->registers->usbsts; 237 interrupt_commands[1].addr = 238 (void*)&instance->registers->usbsts; 206 239 instance->interrupt_code.cmdcount = 207 240 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 208 241 } 209 242 210 /* init transfer lists */243 /* Init transfer lists */ 211 244 ret = uhci_init_transfer_lists(instance); 212 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init ializetransfer lists.\n");245 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n"); 213 246 usb_log_debug("Initialized transfer lists.\n"); 214 247 215 /* frame list initialization*/248 /* Init USB frame list page*/ 216 249 instance->frame_list = get_page(); 217 250 ret = instance ? EOK : ENOMEM; … … 219 252 usb_log_debug("Initialized frame list.\n"); 220 253 221 /* initializeall frames to point to the first queue head */254 /* Set all frames to point to the first queue head */ 222 255 const uint32_t queue = 223 256 instance->transfers_interrupt.queue_head_pa … … 229 262 } 230 263 231 /* init address keeper(libusb)*/264 /* Init device keeper*/ 232 265 device_keeper_init(&instance->device_manager); 233 266 usb_log_debug("Initialized device manager.\n"); … … 237 270 } 238 271 /*----------------------------------------------------------------------------*/ 272 /** Initializes UHCI hcd transfer lists. 273 * 274 * @param[in] instance UHCI structure to use. 275 * @return Error code 276 * @note Should be called only once on any structure. 277 */ 239 278 int uhci_init_transfer_lists(uhci_t *instance) 240 279 { … … 255 294 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 256 295 257 ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL"); 296 ret = transfer_list_init( 297 &instance->transfers_control_full, "CONTROL_FULL"); 258 298 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 259 299 260 ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW"); 300 ret = transfer_list_init( 301 &instance->transfers_control_slow, "CONTROL_SLOW"); 261 302 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 262 303 … … 277 318 #endif 278 319 279 instance->transfers[0][USB_TRANSFER_INTERRUPT] = 320 /* Assign pointers to be used during scheduling */ 321 instance->transfers[USB_SPEED_FULL][USB_TRANSFER_INTERRUPT] = 280 322 &instance->transfers_interrupt; 281 instance->transfers[ 1][USB_TRANSFER_INTERRUPT] =323 instance->transfers[USB_SPEED_LOW][USB_TRANSFER_INTERRUPT] = 282 324 &instance->transfers_interrupt; 283 instance->transfers[ 0][USB_TRANSFER_CONTROL] =325 instance->transfers[USB_SPEED_FULL][USB_TRANSFER_CONTROL] = 284 326 &instance->transfers_control_full; 285 instance->transfers[ 1][USB_TRANSFER_CONTROL] =327 instance->transfers[USB_SPEED_LOW][USB_TRANSFER_CONTROL] = 286 328 &instance->transfers_control_slow; 287 instance->transfers[ 0][USB_TRANSFER_BULK] =329 instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] = 288 330 &instance->transfers_bulk_full; 289 331 … … 292 334 } 293 335 /*----------------------------------------------------------------------------*/ 336 /** Schedules batch for execution. 337 * 338 * @param[in] instance UHCI structure to use. 339 * @param[in] batch Transfer batch to schedule. 340 * @return Error code 341 */ 294 342 int uhci_schedule(uhci_t *instance, batch_t *batch) 295 343 { … … 299 347 if (!allowed_usb_packet( 300 348 low_speed, batch->transfer_type, batch->max_packet_size)) { 301 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 349 usb_log_warning( 350 "Invalid USB packet specified %s SPEED %d %zu.\n", 302 351 low_speed ? "LOW" : "FULL" , batch->transfer_type, 303 352 batch->max_packet_size); … … 314 363 } 315 364 /*----------------------------------------------------------------------------*/ 365 /** Takes action based on the interrupt cause. 366 * 367 * @param[in] instance UHCI structure to use. 368 * @param[in] status Value of the stsatus regiser at the time of interrupt. 369 */ 316 370 void uhci_interrupt(uhci_t *instance, uint16_t status) 317 371 { 318 372 assert(instance); 373 /* TODO: Check interrupt cause here */ 319 374 transfer_list_remove_finished(&instance->transfers_interrupt); 320 375 transfer_list_remove_finished(&instance->transfers_control_slow); … … 323 378 } 324 379 /*----------------------------------------------------------------------------*/ 380 /** Polling function, emulates interrupts. 381 * 382 * @param[in] arg UHCI structure to use. 383 * @return EOK 384 */ 325 385 int uhci_interrupt_emulator(void* arg) 326 386 { … … 336 396 uhci_interrupt(instance, status); 337 397 pio_write_16(&instance->registers->usbsts, 0x1f); 338 async_usleep(UHCI_CLEANER_TIMEOUT * 5);398 async_usleep(UHCI_CLEANER_TIMEOUT); 339 399 } 340 400 return EOK; 341 401 } 342 402 /*---------------------------------------------------------------------------*/ 403 /** Debug function, checks consistency of memory structures. 404 * 405 * @param[in] arg UHCI structure to use. 406 * @return EOK 407 */ 343 408 int uhci_debug_checker(void *arg) 344 409 { … … 399 464 async_usleep(UHCI_DEBUGER_TIMEOUT); 400 465 } 401 return 0;466 return EOK; 402 467 #undef QH 403 468 } 404 469 /*----------------------------------------------------------------------------*/ 470 /** Checks transfer packets, for USB validity 471 * 472 * @param[in] low_speed Transfer speed. 473 * @param[in] transfer Transer type 474 * @param[in] size Maximum size of used packets 475 * @return EOK 476 */ 405 477 bool allowed_usb_packet( 406 478 bool low_speed, usb_transfer_type_t transfer, size_t size) -
uspace/drv/uhci-hcd/uhci.h
r0588062e r8e9becf6 84 84 device_keeper_t device_manager; 85 85 86 volatileregs_t *registers;86 regs_t *registers; 87 87 88 88 link_pointer_t *frame_list; -
uspace/drv/uhci-hcd/uhci_struct/queue_head.h
r0588062e r8e9becf6 71 71 } 72 72 73 static inline void queue_head_ element_td(queue_head_t *instance, uint32_t pa)73 static inline void queue_head_set_element_td(queue_head_t *instance, uint32_t pa) 74 74 { 75 75 if (pa) { … … 78 78 } 79 79 80 static inline queue_head_t * queue_head_get() {81 queue_head_t *ret = malloc32(sizeof(queue_head_t));82 if (ret)83 queue_head_init(ret);84 return ret;85 }86 87 static inline void queue_head_dispose(queue_head_t *head)88 { free32(head); }89 90 91 80 #endif 92 81 /** -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
r0588062e r8e9becf6 38 38 #include "utils/malloc32.h" 39 39 40 void transfer_descriptor_init(transfer_descriptor_t *instance, 41 int error_count, size_t size, bool toggle, bool isochronous, bool low_speed, 42 usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next) 40 /** Initializes Transfer Descriptor 41 * 42 * @param[in] instance Memory place to initialize. 43 * @param[in] err_count Number of retries hc should attempt. 44 * @param[in] size Size of data source. 45 * @param[in] toggle Value of toggle bit. 46 * @param[in] iso True if TD is for Isochronous transfer. 47 * @param[in] low_speed Target device's speed. 48 * @param[in] target Address and endpoint receiving the transfer. 49 * @param[in] pid Packet identification (SETUP, IN or OUT). 50 * @param[in] buffer Source of data. 51 * @param[in] next Net TD in transaction. 52 * @return Error code. 53 */ 54 void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso, 55 bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, 56 td_t *next) 43 57 { 44 58 assert(instance); 59 assert(size < 1024); 60 assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN) 61 || (pid == USB_PID_OUT)); 45 62 46 63 instance->next = 0 … … 49 66 50 67 instance->status = 0 51 | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS) 52 | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0) 53 | TD_STATUS_ERROR_ACTIVE; 68 | ((err_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS) 69 | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0) 70 | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0) 71 | TD_STATUS_ERROR_ACTIVE; 54 72 55 assert(size < 1024); 73 if (pid == USB_PID_IN && !iso) { 74 instance->status |= TD_STATUS_SPD_FLAG; 75 } 76 56 77 instance->device = 0 57 58 59 60 61 78 | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS) 79 | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0) 80 | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS) 81 | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS) 82 | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS); 62 83 63 84 instance->buffer_ptr = 0; … … 68 89 69 90 usb_log_debug2("Created TD: %X:%X:%X:%X(%p).\n", 70 instance->next, instance->status, instance->device, 71 instance->buffer_ptr, buffer); 91 instance->next, instance->status, instance->device, 92 instance->buffer_ptr, buffer); 93 if (pid == USB_PID_SETUP) { 94 usb_log_debug("SETUP BUFFER: %s\n", 95 usb_debug_str_buffer(buffer, 8, 8)); 96 } 72 97 } 73 98 /*----------------------------------------------------------------------------*/ 74 int transfer_descriptor_status(transfer_descriptor_t *instance) 99 /** Converts TD status into standard error code 100 * 101 * @param[in] instance TD structure to use. 102 * @return Error code. 103 */ 104 int td_status(td_t *instance) 75 105 { 76 106 assert(instance); -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
r0588062e r8e9becf6 88 88 * we don't use it anyway 89 89 */ 90 } __attribute__((packed)) t ransfer_descriptor_t;90 } __attribute__((packed)) td_t; 91 91 92 92 93 void t ransfer_descriptor_init(transfer_descriptor_t *instance,94 int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,95 usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next);93 void td_init(td_t *instance, int error_count, size_t size, bool toggle, bool iso, 94 bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, 95 td_t *next); 96 96 97 int t ransfer_descriptor_status(transfer_descriptor_t *instance);97 int td_status(td_t *instance); 98 98 99 static inline size_t transfer_descriptor_actual_size( 100 transfer_descriptor_t *instance) 99 static inline size_t td_act_size(td_t *instance) 101 100 { 102 101 assert(instance); 103 102 return 104 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK; 103 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) 104 & TD_STATUS_ACTLEN_MASK; 105 105 } 106 106 107 static inline bool transfer_descriptor_is_active( 108 transfer_descriptor_t *instance) 107 static inline bool td_is_short(td_t *instance) 108 { 109 const size_t act_size = td_act_size(instance); 110 const size_t max_size = 111 ((instance->device >> TD_DEVICE_MAXLEN_POS) + 1) 112 & TD_DEVICE_MAXLEN_MASK; 113 return 114 (instance->status | TD_STATUS_SPD_FLAG) && act_size < max_size; 115 } 116 117 static inline int td_toggle(td_t *instance) 118 { 119 assert(instance); 120 return ((instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) != 0) 121 ? 1 : 0; 122 } 123 124 static inline bool td_is_active(td_t *instance) 109 125 { 110 126 assert(instance); -
uspace/drv/uhci-hcd/utils/device_keeper.c
r0588062e r8e9becf6 39 39 40 40 /*----------------------------------------------------------------------------*/ 41 /** Initializes device keeper structure. 42 * 43 * @param[in] instance Memory place to initialize. 44 */ 41 45 void device_keeper_init(device_keeper_t *instance) 42 46 { … … 49 53 instance->devices[i].occupied = false; 50 54 instance->devices[i].handle = 0; 51 } 52 } 53 /*----------------------------------------------------------------------------*/ 54 void device_keeper_reserve_default( 55 device_keeper_t *instance, usb_speed_t speed) 55 instance->devices[i].toggle_status = 0; 56 } 57 } 58 /*----------------------------------------------------------------------------*/ 59 /** Attempts to obtain address 0, blocks. 60 * 61 * @param[in] instance Device keeper structure to use. 62 * @param[in] speed Speed of the device requesting default address. 63 */ 64 void device_keeper_reserve_default(device_keeper_t *instance, usb_speed_t speed) 56 65 { 57 66 assert(instance); … … 66 75 } 67 76 /*----------------------------------------------------------------------------*/ 77 /** Attempts to obtain address 0, blocks. 78 * 79 * @param[in] instance Device keeper structure to use. 80 * @param[in] speed Speed of the device requesting default address. 81 */ 68 82 void device_keeper_release_default(device_keeper_t *instance) 69 83 { … … 75 89 } 76 90 /*----------------------------------------------------------------------------*/ 91 /** Checks setup data for signs of toggle reset. 92 * 93 * @param[in] instance Device keeper structure to use. 94 * @param[in] target Device to receive setup packet. 95 * @param[in] data Setup packet data. 96 */ 97 void device_keeper_reset_if_need( 98 device_keeper_t *instance, usb_target_t target, const unsigned char *data) 99 { 100 assert(instance); 101 fibril_mutex_lock(&instance->guard); 102 if (target.endpoint > 15 || target.endpoint < 0 103 || target.address >= USB_ADDRESS_COUNT || target.address < 0 104 || !instance->devices[target.address].occupied) { 105 fibril_mutex_unlock(&instance->guard); 106 return; 107 } 108 109 switch (data[1]) 110 { 111 case 0x01: /*clear feature*/ 112 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */ 113 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 114 /* endpoint number is < 16, thus first byte is enough */ 115 instance->devices[target.address].toggle_status &= 116 ~(1 << data[4]); 117 } 118 break; 119 120 case 0x9: /* set configuration */ 121 case 0x11: /* set interface */ 122 instance->devices[target.address].toggle_status = 0; 123 break; 124 } 125 fibril_mutex_unlock(&instance->guard); 126 } 127 /*----------------------------------------------------------------------------*/ 128 /** Gets current value of endpoint toggle. 129 * 130 * @param[in] instance Device keeper structure to use. 131 * @param[in] target Device and endpoint used. 132 * @return Error code 133 */ 134 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target) 135 { 136 assert(instance); 137 int ret; 138 fibril_mutex_lock(&instance->guard); 139 if (target.endpoint > 15 || target.endpoint < 0 140 || target.address >= USB_ADDRESS_COUNT || target.address < 0 141 || !instance->devices[target.address].occupied) { 142 ret = EINVAL; 143 } else { 144 ret = 145 (instance->devices[target.address].toggle_status 146 >> target.endpoint) & 1; 147 } 148 fibril_mutex_unlock(&instance->guard); 149 return ret; 150 } 151 /*----------------------------------------------------------------------------*/ 152 /** Sets current value of endpoint toggle. 153 * 154 * @param[in] instance Device keeper structure to use. 155 * @param[in] target Device and endpoint used. 156 * @param[in] toggle Current toggle value. 157 * @return Error code. 158 */ 159 int device_keeper_set_toggle( 160 device_keeper_t *instance, usb_target_t target, bool toggle) 161 { 162 assert(instance); 163 int ret; 164 fibril_mutex_lock(&instance->guard); 165 if (target.endpoint > 15 || target.endpoint < 0 166 || target.address >= USB_ADDRESS_COUNT || target.address < 0 167 || !instance->devices[target.address].occupied) { 168 ret = EINVAL; 169 } else { 170 if (toggle) { 171 instance->devices[target.address].toggle_status |= (1 << target.endpoint); 172 } else { 173 instance->devices[target.address].toggle_status &= ~(1 << target.endpoint); 174 } 175 ret = EOK; 176 } 177 fibril_mutex_unlock(&instance->guard); 178 return ret; 179 } 180 /*----------------------------------------------------------------------------*/ 181 /** Gets a free USB address 182 * 183 * @param[in] instance Device keeper structure to use. 184 * @param[in] speed Speed of the device requiring address. 185 * @return Free address, or error code. 186 */ 77 187 usb_address_t device_keeper_request( 78 188 device_keeper_t *instance, usb_speed_t speed) … … 96 206 instance->devices[new_address].occupied = true; 97 207 instance->devices[new_address].speed = speed; 208 instance->devices[new_address].toggle_status = 0; 98 209 instance->last_address = new_address; 99 210 fibril_mutex_unlock(&instance->guard); … … 101 212 } 102 213 /*----------------------------------------------------------------------------*/ 214 /** Binds USB address to devman handle. 215 * 216 * @param[in] instance Device keeper structure to use. 217 * @param[in] address Device address 218 * @param[in] handle Devman handle of the device. 219 */ 103 220 void device_keeper_bind( 104 221 device_keeper_t *instance, usb_address_t address, devman_handle_t handle) … … 113 230 } 114 231 /*----------------------------------------------------------------------------*/ 232 /** Releases used USB address. 233 * 234 * @param[in] instance Device keeper structure to use. 235 * @param[in] address Device address 236 */ 115 237 void device_keeper_release(device_keeper_t *instance, usb_address_t address) 116 238 { … … 125 247 } 126 248 /*----------------------------------------------------------------------------*/ 249 /** Finds USB address associated with the device 250 * 251 * @param[in] instance Device keeper structure to use. 252 * @param[in] handle Devman handle of the device seeking its address. 253 * @return USB Address, or error code. 254 */ 127 255 usb_address_t device_keeper_find( 128 256 device_keeper_t *instance, devman_handle_t handle) … … 142 270 } 143 271 /*----------------------------------------------------------------------------*/ 272 /** Gets speed associated with the address 273 * 274 * @param[in] instance Device keeper structure to use. 275 * @param[in] address Address of the device. 276 * @return USB speed. 277 */ 144 278 usb_speed_t device_keeper_speed( 145 279 device_keeper_t *instance, usb_address_t address) -
uspace/drv/uhci-hcd/utils/device_keeper.h
r0588062e r8e9becf6 44 44 usb_speed_t speed; 45 45 bool occupied; 46 uint16_t toggle_status; 46 47 devman_handle_t handle; 47 48 }; … … 55 56 56 57 void device_keeper_init(device_keeper_t *instance); 58 57 59 void device_keeper_reserve_default( 58 60 device_keeper_t *instance, usb_speed_t speed); 61 59 62 void device_keeper_release_default(device_keeper_t *instance); 63 64 void device_keeper_reset_if_need( 65 device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data); 66 67 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target); 68 69 int device_keeper_set_toggle( 70 device_keeper_t *instance, usb_target_t target, bool toggle); 60 71 61 72 usb_address_t device_keeper_request( 62 73 device_keeper_t *instance, usb_speed_t speed); 74 63 75 void device_keeper_bind( 64 76 device_keeper_t *instance, usb_address_t address, devman_handle_t handle); 77 65 78 void device_keeper_release(device_keeper_t *instance, usb_address_t address); 79 66 80 usb_address_t device_keeper_find( 67 81 device_keeper_t *instance, devman_handle_t handle); -
uspace/drv/uhci-hcd/utils/malloc32.h
r0588062e r8e9becf6 34 34 #ifndef DRV_UHCI_TRANSLATOR_H 35 35 #define DRV_UHCI_TRANSLATOR_H 36 37 #include <usb/usbmem.h>38 36 39 37 #include <assert.h> -
uspace/drv/uhci-rhd/main.c
r0588062e r8e9becf6 35 35 #include <devman.h> 36 36 #include <device/hw_res.h> 37 #include <errno.h> 37 38 #include <usb_iface.h> 38 39 #include <usb/ddfiface.h> 40 #include <usb/debug.h> 39 41 40 #include <errno.h>41 42 42 #include <usb/debug.h>43 43 44 44 #include "root_hub.h" … … 47 47 static int hc_get_my_registers(ddf_dev_t *dev, 48 48 uintptr_t *io_reg_address, size_t *io_reg_size); 49 49 /*----------------------------------------------------------------------------*/ 50 50 static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle) 51 51 { … … 58 58 return EOK; 59 59 } 60 60 /*----------------------------------------------------------------------------*/ 61 61 static usb_iface_t uhci_rh_usb_iface = { 62 62 .get_hc_handle = usb_iface_get_hc_handle, 63 63 .get_address = usb_iface_get_address_hub_impl 64 64 }; 65 65 /*----------------------------------------------------------------------------*/ 66 66 static ddf_dev_ops_t uhci_rh_ops = { 67 67 .interfaces[USB_DEV_IFACE] = &uhci_rh_usb_iface, 68 68 }; 69 69 /*----------------------------------------------------------------------------*/ 70 /** Initializes a new ddf driver instance of UHCI root hub. 71 * 72 * @param[in] device DDF instance of the device to initialize. 73 * @return Error code. 74 */ 70 75 static int uhci_rh_add_device(ddf_dev_t *device) 71 76 { … … 104 109 return EOK; 105 110 } 106 111 /*----------------------------------------------------------------------------*/ 107 112 static driver_ops_t uhci_rh_driver_ops = { 108 113 .add_device = uhci_rh_add_device, 109 114 }; 110 115 /*----------------------------------------------------------------------------*/ 111 116 static driver_t uhci_rh_driver = { 112 117 .name = NAME, … … 114 119 }; 115 120 /*----------------------------------------------------------------------------*/ 121 /** Initializes global driver structures (NONE). 122 * 123 * @param[in] argc Nmber of arguments in argv vector (ignored). 124 * @param[in] argv Cmdline argument vector (ignored). 125 * @return Error code. 126 * 127 * Driver debug level is set here. 128 */ 116 129 int main(int argc, char *argv[]) 117 130 { … … 120 133 } 121 134 /*----------------------------------------------------------------------------*/ 122 int hc_get_my_registers(ddf_dev_t *dev, 123 uintptr_t *io_reg_address, size_t *io_reg_size) 135 /** Get address of I/O registers. 136 * 137 * @param[in] dev Device asking for the addresses. 138 * @param[out] io_reg_address Base address of the memory range. 139 * @param[out] io_reg_size Size of the memory range. 140 * @return Error code. 141 */ 142 int hc_get_my_registers( 143 ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size) 124 144 { 125 145 assert(dev != NULL); … … 146 166 for (i = 0; i < hw_resources.count; i++) { 147 167 hw_resource_t *res = &hw_resources.resources[i]; 148 switch (res->type) {149 case IO_RANGE:150 io_address = (uintptr_t)151 152 153 154 break; 155 156 168 switch (res->type) 169 { 170 case IO_RANGE: 171 io_address = (uintptr_t) res->res.io_range.address; 172 io_size = res->res.io_range.size; 173 io_found = true; 174 175 default: 176 break; 157 177 } 158 178 } … … 170 190 } 171 191 rc = EOK; 192 172 193 leave: 173 194 async_hangup(parent_phone); 174 175 195 return rc; 176 196 } -
uspace/drv/uhci-rhd/port.c
r0588062e r8e9becf6 46 46 #include "port_status.h" 47 47 48 static int uhci_port_new_device(uhci_port_t *port, u int16_t status);48 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed); 49 49 static int uhci_port_remove_device(uhci_port_t *port); 50 50 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled); 51 51 static int uhci_port_check(void *port); 52 static int new_device_enable_port(int portno, void *arg); 53 54 int uhci_port_init( 55 uhci_port_t *port, port_status_t *address, unsigned number, 56 unsigned usec, ddf_dev_t *rh) 52 static int uhci_port_reset_enable(int portno, void *arg); 53 /*----------------------------------------------------------------------------*/ 54 /** Initializes UHCI root hub port instance. 55 * 56 * @param[in] port Memory structure to use. 57 * @param[in] addr Address of I/O register. 58 * @param[in] number Port number. 59 * @param[in] usec Polling interval. 60 * @param[in] rh Pointer to ddf instance fo the root hub driver. 61 * @return Error code. 62 * 63 * Starts the polling fibril. 64 */ 65 int uhci_port_init(uhci_port_t *port, 66 port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh) 57 67 { 58 68 assert(port); 69 59 70 port->address = address; 60 71 port->number = number; … … 62 73 port->attached_device = 0; 63 74 port->rh = rh; 75 64 76 int rc = usb_hc_connection_initialize_from_device( 65 77 &port->hc_connection, rh); … … 75 87 return ENOMEM; 76 88 } 89 77 90 fibril_add_ready(port->checker); 78 91 usb_log_debug("Port(%p - %d): Added fibril. %x\n", … … 81 94 } 82 95 /*----------------------------------------------------------------------------*/ 96 /** Finishes UHCI root hub port instance. 97 * 98 * @param[in] port Memory structure to use. 99 * 100 * Stops the polling fibril. 101 */ 83 102 void uhci_port_fini(uhci_port_t *port) 84 103 { 85 // TODO: destroy fibril 86 // TODO: hangup phone 87 // fibril_teardown(port->checker); 104 /* TODO: Kill fibril here */ 88 105 return; 89 106 } 90 107 /*----------------------------------------------------------------------------*/ 108 /** Periodically checks port status and reports new devices. 109 * 110 * @param[in] port Memory structure to use. 111 * @return Error code. 112 */ 91 113 int uhci_port_check(void *port) 92 114 { 93 uhci_port_t * port_instance = port;94 assert( port_instance);95 // port_status_write(port_instance->address, 0); 96 115 uhci_port_t *instance = port; 116 assert(instance); 117 118 /* Iteration count, for debug purposes only */ 97 119 unsigned count = 0; 98 120 99 121 while (1) { 100 async_usleep( port_instance->wait_period_usec);122 async_usleep(instance->wait_period_usec); 101 123 102 124 /* read register value */ 103 port_status_t port_status = 104 port_status_read(port_instance->address); 105 106 /* debug print */107 static fibril_mutex_t dbg_mtx =FIBRIL_MUTEX_INITIALIZER(dbg_mtx);125 port_status_t port_status = port_status_read(instance->address); 126 127 /* debug print mutex */ 128 static fibril_mutex_t dbg_mtx = 129 FIBRIL_MUTEX_INITIALIZER(dbg_mtx); 108 130 fibril_mutex_lock(&dbg_mtx); 109 131 usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n", 110 port_instance->address, port_instance->number, port_status, count++);132 instance->address, instance->number, port_status, count++); 111 133 // print_port_status(port_status); 112 134 fibril_mutex_unlock(&dbg_mtx); 113 135 114 if ((port_status & STATUS_CONNECTED_CHANGED) != 0) { 115 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n", 116 port_instance->address, port_instance->number, port_status); 117 118 119 int rc = usb_hc_connection_open( 120 &port_instance->hc_connection); 121 if (rc != EOK) { 122 usb_log_error("Port(%p - %d): Failed to connect to HC.", 123 port_instance->address, port_instance->number); 124 continue; 125 } 126 127 /* remove any old device */ 128 if (port_instance->attached_device) { 129 usb_log_debug("Port(%p - %d): Removing device.\n", 130 port_instance->address, port_instance->number); 131 uhci_port_remove_device(port_instance); 132 } 133 134 if ((port_status & STATUS_CONNECTED) != 0) { 135 /* new device */ 136 uhci_port_new_device(port_instance, port_status); 137 } else { 138 /* ack changes by writing one to WC bits */ 139 port_status_write(port_instance->address, port_status); 140 usb_log_debug("Port(%p - %d): Change status ACK.\n", 141 port_instance->address, port_instance->number); 142 } 143 144 rc = usb_hc_connection_close( 145 &port_instance->hc_connection); 146 if (rc != EOK) { 147 usb_log_error("Port(%p - %d): Failed to disconnect from HC.", 148 port_instance->address, port_instance->number); 149 } 150 } 151 } 152 return EOK; 153 } 154 136 if ((port_status & STATUS_CONNECTED_CHANGED) == 0) 137 continue; 138 139 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n", 140 instance->address, instance->number, port_status); 141 142 int rc = 143 usb_hc_connection_open(&instance->hc_connection); 144 if (rc != EOK) { 145 usb_log_error("Port(%p - %d): Failed to connect to HC.", 146 instance->address, instance->number); 147 continue; 148 } 149 150 /* Remove any old device */ 151 if (instance->attached_device) { 152 usb_log_debug2("Port(%p - %d): Removing device.\n", 153 instance->address, instance->number); 154 uhci_port_remove_device(instance); 155 } 156 157 if ((port_status & STATUS_CONNECTED) != 0) { 158 /* New device */ 159 const usb_speed_t speed = 160 ((port_status & STATUS_LOW_SPEED) != 0) ? 161 USB_SPEED_LOW : USB_SPEED_FULL; 162 uhci_port_new_device(instance, speed); 163 } else { 164 /* Write one to WC bits, to ack changes */ 165 port_status_write(instance->address, port_status); 166 usb_log_debug("Port(%p - %d): Change status ACK.\n", 167 instance->address, instance->number); 168 } 169 170 rc = usb_hc_connection_close(&instance->hc_connection); 171 if (rc != EOK) { 172 usb_log_error("Port(%p - %d): Failed to disconnect.", 173 instance->address, instance->number); 174 } 175 } 176 return EOK; 177 } 178 /*----------------------------------------------------------------------------*/ 155 179 /** Callback for enabling port during adding a new device. 156 180 * … … 159 183 * @return Error code. 160 184 */ 161 static int new_device_enable_port(int portno, void *arg)185 int uhci_port_reset_enable(int portno, void *arg) 162 186 { 163 187 uhci_port_t *port = (uhci_port_t *) arg; … … 184 208 port_status_write(port->address, port_status); 185 209 async_usleep(10000); 186 port_status = 187 port_status_read(port->address); 210 port_status = port_status_read(port->address); 188 211 port_status &= ~STATUS_IN_RESET; 189 212 port_status_write(port->address, port_status); … … 194 217 /* Enable the port. */ 195 218 uhci_port_set_enabled(port, true); 196 197 return EOK; 198 } 199 200 /*----------------------------------------------------------------------------*/ 201 static int uhci_port_new_device(uhci_port_t *port, uint16_t status) 219 return EOK; 220 } 221 /*----------------------------------------------------------------------------*/ 222 /** Initializes and reports connected device. 223 * 224 * @param[in] port Memory structure to use. 225 * @param[in] speed Detected speed. 226 * @return Error code. 227 * 228 * Uses libUSB function to do the actual work. 229 */ 230 int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed) 202 231 { 203 232 assert(port); … … 209 238 usb_address_t dev_addr; 210 239 int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 211 ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL, 212 new_device_enable_port, port->number, port, 240 speed, uhci_port_reset_enable, port->number, port, 213 241 &dev_addr, &port->attached_device, NULL, NULL, NULL); 214 242 215 243 if (rc != EOK) { 216 usb_log_error("Port(%p-%d): Failed(%d) adding newdevice: %s.\n",244 usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n", 217 245 port->address, port->number, rc, str_error(rc)); 218 246 uhci_port_set_enabled(port, false); … … 225 253 return EOK; 226 254 } 227 228 /*----------------------------------------------------------------------------*/ 229 static int uhci_port_remove_device(uhci_port_t *port) 255 /*----------------------------------------------------------------------------*/ 256 /** Removes device. 257 * 258 * @param[in] port Memory structure to use. 259 * @return Error code. 260 * 261 * Does not work DDF does not support device removal. 262 */ 263 int uhci_port_remove_device(uhci_port_t *port) 230 264 { 231 265 usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n", 232 port->address, port->number, (unsigned int)port->attached_device); 233 // uhci_port_set_enabled(port, false); 234 return EOK; 235 } 236 /*----------------------------------------------------------------------------*/ 237 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled) 266 port->address, port->number, (unsigned int)port->attached_device); 267 return EOK; 268 } 269 /*----------------------------------------------------------------------------*/ 270 /** Enables and disables port. 271 * 272 * @param[in] port Memory structure to use. 273 * @return Error code. (Always EOK) 274 */ 275 int uhci_port_set_enabled(uhci_port_t *port, bool enabled) 238 276 { 239 277 assert(port); 240 278 241 /* read register value */ 242 port_status_t port_status 243 = port_status_read(port->address); 244 245 /* enable port: register write */ 279 /* Read register value */ 280 port_status_t port_status = port_status_read(port->address); 281 282 /* Set enabled bit */ 246 283 if (enabled) { 247 284 port_status |= STATUS_ENABLED; … … 249 286 port_status &= ~STATUS_ENABLED; 250 287 } 288 289 /* Write new value. */ 251 290 port_status_write(port->address, port_status); 252 291 -
uspace/drv/uhci-rhd/port_status.c
r0588062e r8e9becf6 60 60 }; 61 61 62 /** Prints portr status in a human readable way. 63 * 64 * @param[in] value Port value to print. 65 * @return Error code. 66 */ 62 67 void print_port_status(port_status_t value) 63 68 { -
uspace/drv/uhci-rhd/root_hub.c
r0588062e r8e9becf6 40 40 #include "root_hub.h" 41 41 42 /** Initializes UHCI root hub instance. 43 * 44 * @param[in] instance Driver memory structure to use. 45 * @param[in] addr Address of I/O registers. 46 * @param[in] size Size of available I/O space. 47 * @param[in] rh Pointer to ddf instance fo the root hub driver. 48 * @return Error code. 49 */ 42 50 int uhci_root_hub_init( 43 51 uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh) … … 47 55 int ret; 48 56 49 /* allow access to root hubregisters */50 assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT == size);57 /* Allow access to root hub port registers */ 58 assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT <= size); 51 59 port_status_t *regs; 52 60 ret = pio_enable(addr, size, (void**)®s); 53 54 61 if (ret < 0) { 55 usb_log_error("Failed to gain access to port registers at %p\n", regs); 62 usb_log_error( 63 "Failed to gain access to port registers at %p\n", regs); 56 64 return ret; 57 65 } … … 60 68 unsigned i = 0; 61 69 for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) { 62 /* mind pointer arithmetics*/70 /* NOTE: mind pointer arithmetics here */ 63 71 ret = uhci_port_init( 64 &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);72 &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh); 65 73 if (ret != EOK) { 66 74 unsigned j = 0; … … 74 82 } 75 83 /*----------------------------------------------------------------------------*/ 76 int uhci_root_hub_fini( uhci_root_hub_t* instance ) 84 /** Finishes UHCI root hub instance. 85 * 86 * @param[in] instance Driver memory structure to use. 87 * @return Error code. 88 */ 89 int uhci_root_hub_fini(uhci_root_hub_t* instance) 77 90 { 78 assert( instance ); 79 // TODO: 80 //destroy fibril here 81 //disable access to registers 91 assert(instance); 92 unsigned i = 0; 93 for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) { 94 uhci_port_fini(&instance->ports[i]); 95 } 82 96 return EOK; 83 97 } -
uspace/drv/usbhid/hiddev.c
r0588062e r8e9becf6 206 206 assert(endpoint_mapping[0].interface != NULL); 207 207 208 /* 209 * Save polling interval 210 */ 211 hid_dev->poll_interval = endpoint_mapping[0].descriptor->poll_interval; 212 assert(hid_dev->poll_interval > 0); 213 208 214 rc = usbhid_dev_get_report_descriptor(hid_dev, 209 215 descriptors, descriptors_size, -
uspace/drv/usbhid/hiddev.h
r0588062e r8e9becf6 57 57 usb_endpoint_pipe_t poll_pipe; 58 58 59 short poll_interval; 60 59 61 uint16_t iface; 60 62 -
uspace/drv/usbhid/hidreq.c
r0588062e r8e9becf6 69 69 return sess_rc; 70 70 } 71 72 uint16_t value = 0; 73 value |= (type << 8); 71 74 72 75 usb_log_debug("Sending Set_Report request to the device.\n"); … … 74 77 rc = usb_control_request_set(&hid_dev->ctrl_pipe, 75 78 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 76 USB_HIDREQ_SET_REPORT, type, hid_dev->iface, buffer, buf_size);79 USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size); 77 80 78 81 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe); … … 137 140 return sess_rc; 138 141 } 142 143 return EOK; 144 } 145 146 /*----------------------------------------------------------------------------*/ 147 148 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration) 149 { 150 if (hid_dev == NULL) { 151 usb_log_error("usbhid_req_set_idle(): no HID device " 152 "structure given.\n"); 153 return EINVAL; 154 } 155 156 /* 157 * No need for checking other parameters, as they are checked in 158 * the called function (usb_control_request_set()). 159 */ 160 161 int rc, sess_rc; 162 163 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe); 164 if (sess_rc != EOK) { 165 usb_log_warning("Failed to start a session: %s.\n", 166 str_error(sess_rc)); 167 return sess_rc; 168 } 169 170 usb_log_debug("Sending Set_Idle request to the device (" 171 "duration: %u, iface: %d).\n", duration, hid_dev->iface); 172 173 uint16_t value = duration << 8; 174 175 rc = usb_control_request_set(&hid_dev->ctrl_pipe, 176 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 177 USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0); 178 179 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe); 180 181 if (rc != EOK) { 182 usb_log_warning("Error sending output report to the keyboard: " 183 "%s.\n", str_error(rc)); 184 return rc; 185 } 186 187 if (sess_rc != EOK) { 188 usb_log_warning("Error closing session: %s.\n", 189 str_error(sess_rc)); 190 return sess_rc; 191 } 192 193 return EOK; 194 } 195 196 /*----------------------------------------------------------------------------*/ 197 198 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 199 uint8_t *buffer, size_t buf_size, size_t *actual_size) 200 { 201 if (hid_dev == NULL) { 202 usb_log_error("usbhid_req_set_report(): no HID device structure" 203 " given.\n"); 204 return EINVAL; 205 } 206 207 /* 208 * No need for checking other parameters, as they are checked in 209 * the called function (usb_control_request_set()). 210 */ 211 212 int rc, sess_rc; 213 214 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe); 215 if (sess_rc != EOK) { 216 usb_log_warning("Failed to start a session: %s.\n", 217 str_error(sess_rc)); 218 return sess_rc; 219 } 220 221 uint16_t value = 0; 222 value |= (type << 8); 223 224 usb_log_debug("Sending Get_Report request to the device.\n"); 225 226 rc = usb_control_request_get(&hid_dev->ctrl_pipe, 227 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 228 USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size, 229 actual_size); 230 231 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe); 232 233 if (rc != EOK) { 234 usb_log_warning("Error sending output report to the keyboard: " 235 "%s.\n", str_error(rc)); 236 return rc; 237 } 238 239 if (sess_rc != EOK) { 240 usb_log_warning("Error closing session: %s.\n", 241 str_error(sess_rc)); 242 return sess_rc; 243 } 244 245 return EOK; 246 } 247 248 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol) 249 { 250 if (hid_dev == NULL) { 251 usb_log_error("usbhid_req_set_protocol(): no HID device " 252 "structure given.\n"); 253 return EINVAL; 254 } 255 256 /* 257 * No need for checking other parameters, as they are checked in 258 * the called function (usb_control_request_set()). 259 */ 260 261 int rc, sess_rc; 262 263 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe); 264 if (sess_rc != EOK) { 265 usb_log_warning("Failed to start a session: %s.\n", 266 str_error(sess_rc)); 267 return sess_rc; 268 } 269 270 usb_log_debug("Sending Get_Protocol request to the device (" 271 "iface: %d).\n", hid_dev->iface); 272 273 uint8_t buffer[1]; 274 size_t actual_size = 0; 275 276 rc = usb_control_request_get(&hid_dev->ctrl_pipe, 277 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 278 USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size); 279 280 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe); 281 282 if (rc != EOK) { 283 usb_log_warning("Error sending output report to the keyboard: " 284 "%s.\n", str_error(rc)); 285 return rc; 286 } 287 288 if (sess_rc != EOK) { 289 usb_log_warning("Error closing session: %s.\n", 290 str_error(sess_rc)); 291 return sess_rc; 292 } 293 294 if (actual_size != 1) { 295 usb_log_warning("Wrong data size: %zu, expected: 1.\n", 296 actual_size); 297 return ELIMIT; 298 } 299 300 *protocol = buffer[0]; 301 302 return EOK; 303 } 304 305 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration) 306 { 307 if (hid_dev == NULL) { 308 usb_log_error("usbhid_req_set_idle(): no HID device " 309 "structure given.\n"); 310 return EINVAL; 311 } 312 313 /* 314 * No need for checking other parameters, as they are checked in 315 * the called function (usb_control_request_set()). 316 */ 317 318 int rc, sess_rc; 319 320 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe); 321 if (sess_rc != EOK) { 322 usb_log_warning("Failed to start a session: %s.\n", 323 str_error(sess_rc)); 324 return sess_rc; 325 } 326 327 usb_log_debug("Sending Get_Idle request to the device (" 328 "iface: %d).\n", hid_dev->iface); 329 330 uint16_t value = 0; 331 uint8_t buffer[1]; 332 size_t actual_size = 0; 333 334 rc = usb_control_request_get(&hid_dev->ctrl_pipe, 335 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 336 USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1, 337 &actual_size); 338 339 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe); 340 341 if (rc != EOK) { 342 usb_log_warning("Error sending output report to the keyboard: " 343 "%s.\n", str_error(rc)); 344 return rc; 345 } 346 347 if (sess_rc != EOK) { 348 usb_log_warning("Error closing session: %s.\n", 349 str_error(sess_rc)); 350 return sess_rc; 351 } 352 353 if (actual_size != 1) { 354 usb_log_warning("Wrong data size: %zu, expected: 1.\n", 355 actual_size); 356 return ELIMIT; 357 } 358 359 *duration = buffer[0]; 139 360 140 361 return EOK; -
uspace/drv/usbhid/hidreq.h
r0588062e r8e9becf6 50 50 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol); 51 51 52 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration); 53 54 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 55 uint8_t *buffer, size_t buf_size, size_t *actual_size); 56 57 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol); 58 59 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration); 60 52 61 /*----------------------------------------------------------------------------*/ 53 62 -
uspace/drv/usbhid/kbddev.c
r0588062e r8e9becf6 38 38 #include <str_error.h> 39 39 #include <fibril.h> 40 #include <stdio.h> 40 41 41 42 #include <io/keycode.h> … … 62 63 static const size_t BOOTP_BUFFER_SIZE = 8; 63 64 static const size_t BOOTP_BUFFER_OUT_SIZE = 1; 65 static const uint8_t BOOTP_ERROR_ROLLOVER = 1; 66 static const uint8_t IDLE_RATE = 0; 64 67 65 68 /** Keyboard polling endpoint description for boot protocol class. */ … … 149 152 uint8_t buffer[BOOTP_BUFFER_OUT_SIZE]; 150 153 int rc= 0; 151 unsigned i;152 154 153 155 memset(buffer, 0, BOOTP_BUFFER_OUT_SIZE); … … 177 179 } 178 180 179 // TODO: REFACTOR!!! 180 181 usb_log_debug("Output report buffer: "); 182 for (i = 0; i < BOOTP_BUFFER_OUT_SIZE; ++i) { 183 usb_log_debug("0x%x ", buffer[i]); 184 } 185 usb_log_debug("\n"); 186 187 uint16_t value = 0; 188 value |= (USB_HID_REPORT_TYPE_OUTPUT << 8); 189 181 usb_log_debug("Output report buffer: %s\n", 182 usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0)); 183 190 184 assert(kbd_dev->hid_dev != NULL); 191 185 assert(kbd_dev->hid_dev->initialized); 192 usbhid_req_set_report(kbd_dev->hid_dev, value, buffer,193 BOOTP_BUFFER_OUT_SIZE);186 usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT, 187 buffer, BOOTP_BUFFER_OUT_SIZE); 194 188 } 195 189 … … 228 222 229 223 if (mod_mask != 0) { 230 usb_log_debug2("\n\nChanging mods and lock keys\n");231 usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods);232 usb_log_debug2("\nLock keys before:0x%x\n\n",233 kbd_dev->lock_keys);234 235 224 if (type == KEY_PRESS) { 236 usb_log_debug2("\nKey pressed.\n");237 225 /* 238 226 * Only change lock state on transition from released … … 247 235 usbhid_kbd_set_led(kbd_dev); 248 236 } else { 249 usb_log_debug2("\nKey released.\n");250 237 kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask; 251 238 } 252 239 } 253 240 254 usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods);255 usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys);256 257 241 if (key == KC_CAPS_LOCK || key == KC_NUM_LOCK || key == KC_SCROLL_LOCK) { 258 242 // do not send anything to the console, this is our business … … 281 265 ev.key = key; 282 266 ev.mods = kbd_dev->mods; 283 284 if (ev.mods & KM_NUM_LOCK) {285 usb_log_debug("\n\nNum Lock turned on.\n\n");286 }287 267 288 268 ev.c = layout[active_layout]->parse_ev(&ev); … … 340 320 const uint8_t *key_codes) 341 321 { 342 // TODO: phantom state!!343 344 322 unsigned int key; 345 323 unsigned int i, j; 324 325 /* 326 * First of all, check if the kbd have reported phantom state. 327 */ 328 i = 0; 329 // all fields should report Error Rollover 330 while (i < kbd_dev->keycode_count && 331 key_codes[i] == BOOTP_ERROR_ROLLOVER) { 332 ++i; 333 } 334 if (i == kbd_dev->keycode_count) { 335 usb_log_debug("Phantom state occured.\n"); 336 // phantom state, do nothing 337 return; 338 } 346 339 347 340 // TODO: quite dummy right now, think of better implementation … … 362 355 key = usbhid_parse_scancode(kbd_dev->keycodes[j]); 363 356 usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key); 364 usb_log_debug2(" \nKey released: %d\n", key);357 usb_log_debug2("Key released: %d\n", key); 365 358 } else { 366 359 // found, nothing happens … … 382 375 // not found, i.e. new key pressed 383 376 key = usbhid_parse_scancode(key_codes[i]); 384 usb_log_debug2(" \nKey pressed: %d (keycode: %d)\n", key,377 usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 385 378 key_codes[i]); 386 379 usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key); … … 389 382 } 390 383 } 384 // // report all currently pressed keys 385 // for (i = 0; i < kbd_dev->keycode_count; ++i) { 386 // if (key_codes[i] != 0) { 387 // key = usbhid_parse_scancode(key_codes[i]); 388 // usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 389 // key_codes[i]); 390 // usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key); 391 // } 392 // } 391 393 392 394 memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count); 393 394 usb_log_debug2("\nNew stored keycodes: "); 395 for (i = 0; i < kbd_dev->keycode_count; ++i) { 396 usb_log_debug2("%d ", kbd_dev->keycodes[i]); 397 } 395 396 usb_log_debug("New stored keycodes: %s\n", 397 usb_debug_str_buffer(kbd_dev->keycodes, kbd_dev->keycode_count, 0)); 398 398 } 399 399 … … 410 410 return; 411 411 } 412 413 usb_log_debug2("Got keys from parser: ");414 unsigned i;415 for (i = 0; i < count; ++i) {416 usb_log_debug2("%d ", key_codes[i]);417 }418 usb_log_debug2("\n");419 412 420 413 usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg; 421 414 assert(kbd_dev != NULL); 415 416 usb_log_debug("Got keys from parser: %s\n", 417 usb_debug_str_buffer(key_codes, kbd_dev->keycode_count, 0)); 422 418 423 419 if (count != kbd_dev->keycode_count) { … … 444 440 callbacks->keyboard = usbhid_kbd_process_keycodes; 445 441 446 //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 447 // NULL); 448 /*usb_log_debug2("Calling usb_hid_boot_keyboard_input_report() with size" 449 " %zu\n", actual_size);*/ 450 //dump_buffer("bufffer: ", buffer, actual_size); 442 usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with " 443 "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0)); 451 444 452 445 int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, … … 559 552 * Set boot protocol. 560 553 * Set LEDs according to initial setup. 554 * Set Idle rate 561 555 */ 562 556 assert(kbd_dev->hid_dev != NULL); … … 566 560 usbhid_kbd_set_led(kbd_dev); 567 561 562 usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE); 563 568 564 kbd_dev->initialized = 1; 569 565 usb_log_info("HID/KBD device structure initialized.\n"); … … 593 589 594 590 while (true) { 595 async_usleep(1000 * 10);596 597 591 sess_rc = usb_endpoint_pipe_start_session( 598 592 &kbd_dev->hid_dev->poll_pipe); … … 635 629 usb_log_debug("Calling usbhid_kbd_process_data()\n"); 636 630 usbhid_kbd_process_data(kbd_dev, buffer, actual_size); 631 632 // disabled for now, no reason to sleep 633 //async_usleep(kbd_dev->hid_dev->poll_interval); 637 634 } 638 635 -
uspace/drv/usbhid/main.c
r0588062e r8e9becf6 80 80 int main(int argc, char *argv[]) 81 81 { 82 usb_log_enable(USB_LOG_LEVEL_ INFO, NAME);82 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 83 83 return ddf_driver_main(&kbd_driver); 84 84 } -
uspace/drv/usbhub/usbhub.c
r0588062e r8e9becf6 233 233 dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction"); 234 234 usb_endpoint_pipe_start_session(&result->endpoints.control); 235 opResult = usb_request_set_configuration(&result->endpoints.control, 1); 236 assert(opResult == EOK); 237 235 238 opResult = usb_request_get_descriptor(&result->endpoints.control, 236 239 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, … … 243 246 dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult); 244 247 free(serialized_descriptor); 245 return result; 248 free(result); 249 return NULL; 246 250 } 247 251 dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor"); … … 249 253 if(descriptor==NULL){ 250 254 dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor "); 251 result->port_count = 1;///\TODO this code is only for debug!!!252 return result;255 free(result); 256 return NULL; 253 257 } 254 258 … … 286 290 287 291 usb_hub_info_t * hub_info = usb_create_hub_info(dev); 292 if(!hub_info){ 293 return EINTR; 294 } 288 295 289 296 int opResult; … … 294 301 opResult = usb_hub_process_configuration_descriptors(hub_info); 295 302 if(opResult != EOK){ 296 dprintf(USB_LOG_LEVEL_ERROR,"could not get con diguration descriptors, %d",303 dprintf(USB_LOG_LEVEL_ERROR,"could not get configuration descriptors, %d", 297 304 opResult); 298 305 return opResult; -
uspace/drv/usbmid/main.c
r0588062e r8e9becf6 44 44 #include "usbmid.h" 45 45 46 /** Callback when new MID device is attached to the host. 47 * 48 * @param gen_dev Generic DDF device representing the new device. 49 * @return Error code. 50 */ 46 51 static int usbmid_add_device(ddf_dev_t *gen_dev) 47 52 { … … 86 91 } 87 92 93 /** USB MID driver ops. */ 88 94 static driver_ops_t mid_driver_ops = { 89 95 .add_device = usbmid_add_device, 90 96 }; 91 97 98 /** USB MID driver. */ 92 99 static driver_t mid_driver = { 93 100 .name = NAME, -
uspace/drv/usbmid/usbmid.c
r0588062e r8e9becf6 67 67 } 68 68 69 /** DDF interface of the child - interface function. */ 69 70 static usb_iface_t child_usb_iface = { 70 71 .get_hc_handle = usb_iface_get_hc_handle_hub_child_impl, … … 73 74 }; 74 75 75 76 /** Operations for children - interface functions. */ 76 77 static ddf_dev_ops_t child_device_ops = { 77 78 .interfaces[USB_DEV_IFACE] = &child_usb_iface 78 79 }; 79 80 81 /** Operations of the device itself. */ 80 82 static ddf_dev_ops_t mid_device_ops = { 81 83 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl … … 123 125 /** Create new interface for USB MID device. 124 126 * 125 * @param dev Backing generic DDF child device(representing interface).127 * @param fun Backing generic DDF device function (representing interface). 126 128 * @param iface_no Interface number. 127 129 * @return New interface. -
uspace/drv/usbmid/usbmid.h
r0588062e r8e9becf6 44 44 #define NAME "usbmid" 45 45 46 /** USB MID device container. */ 46 47 typedef struct { 47 48 /** Device container. */ … … 54 55 } usbmid_device_t; 55 56 57 58 /** Container for single interface in a MID device. */ 56 59 typedef struct { 57 60 /** Function container. */ -
uspace/drv/usbmouse/init.c
r0588062e r8e9becf6 101 101 102 102 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 103 /** Device ops for USB mouse. */ 103 104 static ddf_dev_ops_t mouse_ops = { 104 105 .default_handler = default_connection_handler … … 107 108 /** Default handler for IPC methods not handled by DDF. 108 109 * 109 * @param dev Devicehandling the call.110 * @param fun Device function handling the call. 110 111 * @param icallid Call id. 111 112 * @param icall Call data. … … 135 136 } 136 137 137 138 /** Create USB mouse device. 139 * 140 * The mouse device is stored into <code>dev->driver_data</code>. 141 * 142 * @param dev Generic device. 143 * @return Error code. 144 */ 138 145 int usb_mouse_create(ddf_dev_t *dev) 139 146 { -
uspace/drv/usbmouse/main.c
r0588062e r8e9becf6 39 39 #include <str_error.h> 40 40 41 /** Callback when new mouse device is attached and recognised by DDF. 42 * 43 * @param dev Representation of a generic DDF device. 44 * @return Error code. 45 */ 41 46 static int usbmouse_add_device(ddf_dev_t *dev) 42 47 { … … 63 68 } 64 69 70 /** USB mouse driver ops. */ 65 71 static driver_ops_t mouse_driver_ops = { 66 72 .add_device = usbmouse_add_device, 67 73 }; 68 74 75 /** USB mouse driver. */ 69 76 static driver_t mouse_driver = { 70 77 .name = NAME, -
uspace/drv/usbmouse/mouse.c
r0588062e r8e9becf6 37 37 #include <usb/debug.h> 38 38 #include <errno.h> 39 #include <str_error.h> 39 40 #include <ipc/mouse.h> 40 41 42 /** Fibril function for polling the mouse device. 43 * 44 * This function shall not terminate unless the device breaks and fails 45 * to send data (e.g. stalls on data request). 46 * 47 * @param arg ddf_dev_t type representing the mouse device. 48 * @return EOK Always. 49 */ 41 50 int usb_mouse_polling_fibril(void *arg) 42 51 { … … 64 73 65 74 size_t actual_size; 75 int rc; 66 76 67 /* FIXME: check for errors. */ 68 usb_endpoint_pipe_start_session(&mouse->poll_pipe); 77 /* 78 * Error checking note: 79 * - failure when starting a session is considered 80 * temporary (e.g. out of phones, next try might succeed) 81 * - failure of transfer considered fatal (probably the 82 * device was unplugged) 83 * - session closing not checked (shall not fail anyway) 84 */ 69 85 70 usb_endpoint_pipe_read(&mouse->poll_pipe, 86 rc = usb_endpoint_pipe_start_session(&mouse->poll_pipe); 87 if (rc != EOK) { 88 usb_log_warning("Failed to start session, will try again: %s.\n", 89 str_error(rc)); 90 continue; 91 } 92 93 rc = usb_endpoint_pipe_read(&mouse->poll_pipe, 71 94 buffer, buffer_size, &actual_size); 72 95 73 96 usb_endpoint_pipe_end_session(&mouse->poll_pipe); 97 98 if (rc != EOK) { 99 usb_log_error("Failed reading mouse input: %s.\n", 100 str_error(rc)); 101 break; 102 } 103 104 usb_log_debug2("got buffer: %s.\n", 105 usb_debug_str_buffer(buffer, buffer_size, 0)); 74 106 75 107 uint8_t butt = buffer[0]; … … 115 147 } 116 148 149 /* 150 * Device was probably unplugged. 151 * Hang-up the phone to the console. 152 * FIXME: release allocated memory. 153 */ 154 async_hangup(mouse->console_phone); 155 mouse->console_phone = -1; 156 157 usb_log_error("Mouse polling fibril terminated.\n"); 158 117 159 return EOK; 118 160 } -
uspace/drv/usbmouse/mouse.h
r0588062e r8e9becf6 43 43 #define NAME "usbmouse" 44 44 45 /** Container for USB mouse device. */ 45 46 typedef struct { 47 /** Generic device container. */ 46 48 ddf_dev_t *device; 49 /** Function representing the device. */ 47 50 ddf_fun_t *mouse_fun; 51 /** Representation of connection to the device. */ 48 52 usb_device_connection_t wire; 53 /** Default (zero) control pipe. */ 49 54 usb_endpoint_pipe_t ctrl_pipe; 55 /** Polling (in) pipe. */ 50 56 usb_endpoint_pipe_t poll_pipe; 57 /** Polling interval in microseconds. */ 51 58 suseconds_t poll_interval_us; 59 /** IPC phone to console (consumer). */ 52 60 int console_phone; 53 61 } usb_mouse_t; -
uspace/drv/vhc/conndev.c
r0588062e r8e9becf6 110 110 /** Callback for DDF when client disconnects. 111 111 * 112 * @param d Devicethe client was connected to.112 * @param fun Device function the client was connected to. 113 113 */ 114 114 void on_client_close(ddf_fun_t *fun) -
uspace/lib/usb/Makefile
r0588062e r8e9becf6 47 47 src/request.c \ 48 48 src/usb.c \ 49 src/usbdevice.c \ 50 src/usbmem.c 49 src/usbdevice.c 51 50 52 51 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usb/include/usb/classes/classes.h
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @brief USB device classes and subclasses.33 * USB device classes (generic constants and functions). 34 34 */ 35 35 #ifndef LIBUSB_CLASSES_H_ -
uspace/lib/usb/include/usb/debug.h
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @briefDebugging related functions.33 * Debugging related functions. 34 34 */ 35 35 #ifndef LIBUSB_DEBUG_H_ … … 39 39 #include <assert.h> 40 40 41 void usb_dprintf(const char *tag, int level, const char *format, ...);42 void usb_dprintf_enable(const char *tag, int level);43 44 41 void usb_dump_standard_descriptor(FILE *, const char *, const char *, 45 42 const uint8_t *, size_t); … … 47 44 /** Logging level. */ 48 45 typedef enum { 46 /** Fatal, unrecoverable, error. 47 * Such error prevents the driver from working at all. 48 */ 49 49 USB_LOG_LEVEL_FATAL, 50 51 /** Serious but recoverable error 52 * Shall be used for errors fatal for single device but not for 53 * driver itself. 54 */ 50 55 USB_LOG_LEVEL_ERROR, 56 57 /** Warning. 58 * Problems from which the driver is able to recover gracefully. 59 */ 51 60 USB_LOG_LEVEL_WARNING, 61 62 /** Information message. 63 * This should be the last level that is printed by default to 64 * the screen. 65 * Typical usage is to inform that new device was found and what 66 * are its capabilities. 67 * Do not use for repetitive actions (such as device polling). 68 */ 52 69 USB_LOG_LEVEL_INFO, 70 71 /** Debugging message. */ 53 72 USB_LOG_LEVEL_DEBUG, 73 74 /** More detailed debugging message. */ 54 75 USB_LOG_LEVEL_DEBUG2, 76 77 /** Terminating constant for logging levels. */ 55 78 USB_LOG_LEVEL_MAX 56 79 } usb_log_level_t; … … 61 84 void usb_log_printf(usb_log_level_t, const char *, ...); 62 85 86 /** Log fatal error. */ 63 87 #define usb_log_fatal(format, ...) \ 64 88 usb_log_printf(USB_LOG_LEVEL_FATAL, format, ##__VA_ARGS__) 65 89 90 /** Log normal (recoverable) error. */ 66 91 #define usb_log_error(format, ...) \ 67 92 usb_log_printf(USB_LOG_LEVEL_ERROR, format, ##__VA_ARGS__) 68 93 94 /** Log warning. */ 69 95 #define usb_log_warning(format, ...) \ 70 96 usb_log_printf(USB_LOG_LEVEL_WARNING, format, ##__VA_ARGS__) 71 97 98 /** Log informational message. */ 72 99 #define usb_log_info(format, ...) \ 73 100 usb_log_printf(USB_LOG_LEVEL_INFO, format, ##__VA_ARGS__) 74 101 102 /** Log debugging message. */ 75 103 #define usb_log_debug(format, ...) \ 76 104 usb_log_printf(USB_LOG_LEVEL_DEBUG, format, ##__VA_ARGS__) 77 105 106 /** Log verbose debugging message. */ 78 107 #define usb_log_debug2(format, ...) \ 79 108 usb_log_printf(USB_LOG_LEVEL_DEBUG2, format, ##__VA_ARGS__) 80 109 110 const char *usb_debug_str_buffer(const uint8_t *, size_t, size_t); 81 111 82 112 -
uspace/lib/usb/include/usb/descriptor.h
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @briefStandard USB descriptors.33 * Standard USB descriptors. 34 34 */ 35 35 #ifndef LIBUSB_DESCRIPTOR_H_ … … 83 83 /** Product descriptor index. */ 84 84 uint8_t str_product; 85 /** Device serial number des riptor index. */85 /** Device serial number descriptor index. */ 86 86 uint8_t str_serial_number; 87 87 /** Number of possible configurations. */ … … 167 167 } __attribute__ ((packed)) usb_standard_endpoint_descriptor_t; 168 168 169 170 /* TODO: string descriptors. */171 172 169 #endif 173 170 /** -
uspace/lib/usb/include/usb/dp.h
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @briefUSB descriptor parser.33 * USB descriptor parser. 34 34 */ 35 35 #ifndef LIBUSB_DP_H_ … … 40 40 #include <usb/descriptor.h> 41 41 42 /** USB descriptors nesting. 43 * The nesting describes the logical tree USB descriptors form 44 * (e.g. that endpoint descriptor belongs to interface or that 45 * interface belongs to configuration). 46 * 47 * See usb_descriptor_type_t for descriptor constants. 48 */ 42 49 typedef struct { 50 /** Child descriptor id. */ 43 51 int child; 52 /** Parent descriptor id. */ 44 53 int parent; 45 54 } usb_dp_descriptor_nesting_t; … … 47 56 extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[]; 48 57 58 /** Descriptor parser structure. */ 49 59 typedef struct { 60 /** Used descriptor nesting. */ 50 61 usb_dp_descriptor_nesting_t *nesting; 51 62 } usb_dp_parser_t; 52 63 64 /** Descriptor parser data. */ 53 65 typedef struct { 66 /** Data to be parsed. */ 54 67 uint8_t *data; 68 /** Size of input data in bytes. */ 55 69 size_t size; 70 /** Custom argument. */ 56 71 void *arg; 57 72 } usb_dp_parser_data_t; -
uspace/lib/usb/include/usb/hub.h
r0588062e r8e9becf6 32 32 /** @file 33 33 * Functions needed by hub drivers. 34 * 35 * For class specific requests, see usb/classes/hub.h. 34 36 */ 35 37 #ifndef LIBUSB_HUB_H_ -
uspace/lib/usb/include/usb/pipes.h
r0588062e r8e9becf6 43 43 #include <ddf/driver.h> 44 44 45 /** 46 * Abstraction of a physical connection to the device. 45 /** Abstraction of a physical connection to the device. 47 46 * This type is an abstraction of the USB wire that connects the host and 48 47 * the function (device). … … 55 54 } usb_device_connection_t; 56 55 57 /** 58 * Abstraction of a logical connection to USB device endpoint. 56 /** Abstraction of a logical connection to USB device endpoint. 59 57 * It encapsulates endpoint attributes (transfer type etc.) as well 60 58 * as information about currently running sessions. … … 111 109 /** Found descriptor fitting the description. */ 112 110 usb_standard_endpoint_descriptor_t *descriptor; 113 /** Interface the endpoint belongs to. */111 /** Interface descriptor the endpoint belongs to. */ 114 112 usb_standard_interface_descriptor_t *interface; 115 113 /** Whether the endpoint was actually found. */ -
uspace/lib/usb/include/usb/request.h
r0588062e r8e9becf6 72 72 union { 73 73 uint16_t value; 74 /* FIXME: add #ifdefs according to host endian ess */74 /* FIXME: add #ifdefs according to host endianness */ 75 75 struct { 76 76 uint8_t value_low; -
uspace/lib/usb/include/usb/usb.h
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @brief Base USB types.33 * Common USB types and functions. 34 34 */ 35 35 #ifndef LIBUSB_USB_H_ … … 121 121 } usb_target_t; 122 122 123 /** Compare USB targets (addresses and endpoints). 124 * 125 * @param a First target. 126 * @param b Second target. 127 * @return Whether @p a and @p b points to the same pipe on the same device. 128 */ 123 129 static inline int usb_target_same(usb_target_t a, usb_target_t b) 124 130 { -
uspace/lib/usb/src/ddfiface.c
r0588062e r8e9becf6 56 56 /** Get host controller handle, interface implementation for hub driver. 57 57 * 58 * @param[in] device Devicethe operation is running on.58 * @param[in] fun Device function the operation is running on. 59 59 * @param[out] handle Storage for the host controller handle. 60 60 * @return Error code. … … 69 69 * a hub driver. 70 70 * 71 * @param[in] device Devicethe operation is running on.71 * @param[in] fun Device function the operation is running on. 72 72 * @param[out] handle Storage for the host controller handle. 73 73 * @return Error code. … … 88 88 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle); 89 89 90 async_hangup(parent_phone); 91 90 92 if (rc != EOK) { 91 93 return rc; … … 99 101 /** Get host controller handle, interface implementation for HC driver. 100 102 * 101 * @param[in] device Devicethe operation is running on.103 * @param[in] fun Device function the operation is running on. 102 104 * @param[out] handle Storage for the host controller handle. 103 105 * @return Always EOK. … … 116 118 /** Get USB device address, interface implementation for hub driver. 117 119 * 118 * @param[in] device Devicethe operation is running on.120 * @param[in] fun Device function the operation is running on. 119 121 * @param[in] handle Devman handle of USB device we want address of. 120 122 * @param[out] address Storage for USB address of device with handle @p handle. … … 151 153 * a hub driver. 152 154 * 153 * @param[in] device Devicethe operation is running on.155 * @param[in] fun Device function the operation is running on. 154 156 * @param[in] handle Devman handle of USB device we want address of. 155 157 * @param[out] address Storage for USB address of device with handle @p handle. -
uspace/lib/usb/src/debug.c
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @brief Debugging support.33 * Debugging and logging support. 34 34 */ 35 35 #include <adt/list.h> … … 40 40 #include <usb/debug.h> 41 41 42 /** Debugging tag. */43 typedef struct {44 /** Linked list member. */45 link_t link;46 /** Tag name.47 * We always have a private copy of the name.48 */49 char *tag;50 /** Enabled level of debugging. */51 int level;52 } usb_debug_tag_t;53 54 /** Get instance of usb_debug_tag_t from link_t. */55 #define USB_DEBUG_TAG_INSTANCE(iterator) \56 list_get_instance(iterator, usb_debug_tag_t, link)57 58 /** List of all known tags. */59 static LIST_INITIALIZE(tag_list);60 /** Mutex guard for the list of all tags. */61 static FIBRIL_MUTEX_INITIALIZE(tag_list_guard);62 63 42 /** Level of logging messages. */ 64 43 static usb_log_level_t log_level = USB_LOG_LEVEL_WARNING; 44 65 45 /** Prefix for logging messages. */ 66 46 static const char *log_prefix = "usb"; 47 67 48 /** Serialization mutex for logging functions. */ 68 49 static FIBRIL_MUTEX_INITIALIZE(log_serializer); 50 51 /** File where to store the log. */ 69 52 static FILE *log_stream = NULL; 70 53 71 /** Find or create new tag with given name.72 *73 * @param tagname Tag name.74 * @return Debug tag structure.75 * @retval NULL Out of memory.76 */77 static usb_debug_tag_t *get_tag(const char *tagname)78 {79 link_t *link;80 for (link = tag_list.next; \81 link != &tag_list; \82 link = link->next) {83 usb_debug_tag_t *tag = USB_DEBUG_TAG_INSTANCE(link);84 if (str_cmp(tag->tag, tagname) == 0) {85 return tag;86 }87 }88 89 /*90 * Tag not found, we will create a new one.91 */92 usb_debug_tag_t *new_tag = malloc(sizeof(usb_debug_tag_t));93 int rc = asprintf(&new_tag->tag, "%s", tagname);94 if (rc < 0) {95 free(new_tag);96 return NULL;97 }98 list_initialize(&new_tag->link);99 new_tag->level = 1;100 101 /*102 * Append it to the end of known tags.103 */104 list_append(&new_tag->link, &tag_list);105 106 return new_tag;107 }108 109 /** Print debugging information.110 * If the tag is used for the first time, its structures are automatically111 * created and initial verbosity level is set to 1.112 *113 * @param tagname Tag name.114 * @param level Level (verbosity) of the message.115 * @param format Formatting string for printf().116 */117 void usb_dprintf(const char *tagname, int level, const char *format, ...)118 {119 fibril_mutex_lock(&tag_list_guard);120 usb_debug_tag_t *tag = get_tag(tagname);121 if (tag == NULL) {122 printf("USB debug: FATAL ERROR - failed to create tag.\n");123 goto leave;124 }125 126 if (tag->level < level) {127 goto leave;128 }129 130 va_list args;131 va_start(args, format);132 133 printf("[%s:%d]: ", tagname, level);134 vprintf(format, args);135 136 va_end(args);137 138 leave:139 fibril_mutex_unlock(&tag_list_guard);140 }141 142 /** Enable debugging prints for given tag.143 *144 * Setting level to <i>n</i> will cause that only printing messages145 * with level lower or equal to <i>n</i> will be printed.146 *147 * @param tagname Tag name.148 * @param level Enabled level.149 */150 void usb_dprintf_enable(const char *tagname, int level)151 {152 fibril_mutex_lock(&tag_list_guard);153 usb_debug_tag_t *tag = get_tag(tagname);154 if (tag == NULL) {155 printf("USB debug: FATAL ERROR - failed to create tag.\n");156 goto leave;157 }158 159 tag->level = level;160 161 leave:162 fibril_mutex_unlock(&tag_list_guard);163 }164 54 165 55 /** Enable logging. … … 182 72 } 183 73 184 74 /** Get log level name prefix. 75 * 76 * @param level Log level. 77 * @return String prefix for the message. 78 */ 185 79 static const char *log_level_name(usb_log_level_t level) 186 80 { … … 252 146 } 253 147 148 149 #define REMAINDER_STR_FMT " (%zu)..." 150 /* string + terminator + number width (enough for 4GB)*/ 151 #define REMAINDER_STR_LEN (5 + 1 + 10) 152 153 /** How many bytes to group together. */ 154 #define BUFFER_DUMP_GROUP_SIZE 4 155 156 /** Size of the string for buffer dumps. */ 157 #define BUFFER_DUMP_LEN 240 /* Ought to be enough for everybody ;-). */ 158 159 /** Fibril local storage for the dumped buffer. */ 160 static fibril_local char buffer_dump[BUFFER_DUMP_LEN]; 161 162 /** Dump buffer into string. 163 * 164 * The function dumps given buffer into hexadecimal format and stores it 165 * in a static fibril local string. 166 * That means that you do not have to deallocate the string (actually, you 167 * can not do that) and you do not have to guard it against concurrent 168 * calls to it. 169 * The only limitation is that each call rewrites the buffer again. 170 * Thus, it is necessary to copy the buffer elsewhere (that includes printing 171 * to screen or writing to file). 172 * Since this function is expected to be used for debugging prints only, 173 * that is not a big limitation. 174 * 175 * @warning You cannot use this function twice in the same printf 176 * (see detailed explanation). 177 * 178 * @param buffer Buffer to be printed (can be NULL). 179 * @param size Size of the buffer in bytes (can be zero). 180 * @param dumped_size How many bytes to actually dump (zero means all). 181 * @return Dumped buffer as a static (but fibril local) string. 182 */ 183 const char *usb_debug_str_buffer(const uint8_t *buffer, size_t size, 184 size_t dumped_size) 185 { 186 /* 187 * Remove previous string (that might also reveal double usage of 188 * this function). 189 */ 190 bzero(buffer_dump, BUFFER_DUMP_LEN); 191 192 if (buffer == NULL) { 193 return "(null)"; 194 } 195 if (size == 0) { 196 return "(empty)"; 197 } 198 if ((dumped_size == 0) || (dumped_size > size)) { 199 dumped_size = size; 200 } 201 202 /* How many bytes are available in the output buffer. */ 203 size_t buffer_remaining_size = BUFFER_DUMP_LEN - 1 - REMAINDER_STR_LEN; 204 char *it = buffer_dump; 205 206 size_t index = 0; 207 208 while (index < size) { 209 /* Determine space before the number. */ 210 const char *space_before; 211 if (index == 0) { 212 space_before = ""; 213 } else if ((index % BUFFER_DUMP_GROUP_SIZE) == 0) { 214 space_before = " "; 215 } else { 216 space_before = " "; 217 } 218 219 /* 220 * Add the byte as a hexadecimal number plus the space. 221 * We do it into temporary buffer to ensure that always 222 * the whole byte is printed. 223 */ 224 int val = buffer[index]; 225 char current_byte[16]; 226 int printed = snprintf(current_byte, 16, 227 "%s%02x", space_before, val); 228 if (printed < 0) { 229 break; 230 } 231 232 if ((size_t) printed > buffer_remaining_size) { 233 break; 234 } 235 236 /* We can safely add 1, because space for end 0 is reserved. */ 237 str_append(it, buffer_remaining_size + 1, current_byte); 238 239 buffer_remaining_size -= printed; 240 /* Point at the terminator 0. */ 241 it += printed; 242 index++; 243 244 if (index >= dumped_size) { 245 break; 246 } 247 } 248 249 /* Add how many bytes were not printed. */ 250 if (index < size) { 251 snprintf(it, REMAINDER_STR_LEN, 252 REMAINDER_STR_FMT, size - index); 253 } 254 255 return buffer_dump; 256 } 257 258 254 259 /** 255 260 * @} -
uspace/lib/usb/src/dp.c
r0588062e r8e9becf6 32 32 /** 33 33 * @file 34 * @brief USB descriptor parser (implementation). 34 * USB descriptor parser (implementation). 35 * 36 * The descriptor parser is a generic parser for structure, where individual 37 * items are stored in single buffer and each item begins with length followed 38 * by type. These types are organized into tree hierarchy. 39 * 40 * The parser is able of only two actions: find first child and find next 41 * sibling. 35 42 */ 36 43 #include <stdio.h> -
uspace/lib/usb/src/dump.c
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @briefDescriptor dumping.33 * Descriptor dumping. 34 34 */ 35 35 #include <adt/list.h> … … 43 43 #include <usb/classes/hid.h> 44 44 45 /** Mapping between descriptor id and dumping function. */ 45 46 typedef struct { 47 /** Descriptor id. */ 46 48 int id; 49 /** Dumping function. */ 47 50 void (*dump)(FILE *, const char *, const char *, 48 51 const uint8_t *, size_t); … … 66 69 const uint8_t *, size_t); 67 70 71 /** Descriptor dumpers mapping. */ 68 72 static descriptor_dump_t descriptor_dumpers[] = { 69 73 { USB_DESCTYPE_DEVICE, usb_dump_descriptor_device }, … … 273 277 const uint8_t *descriptor, size_t descriptor_length) 274 278 { 279 /* TODO */ 275 280 } 276 281 … … 279 284 const uint8_t *descriptor, size_t descriptor_length) 280 285 { 286 /* TODO */ 281 287 } 282 288 -
uspace/lib/usb/src/hub.c
r0588062e r8e9becf6 57 57 * 58 58 * @param connection Opened connection to host controller. 59 * @param speed Speed of the device that will respond on the default address. 59 60 * @return Error code. 60 61 */ … … 86 87 * 87 88 * @param connection Opened connection to host controller. 89 * @param speed Speed of the new device (device that will be assigned 90 * the returned address). 88 91 * @return Assigned USB address or negative error code. 89 92 */ … … 144 147 /** Wrapper for registering attached device to the hub. 145 148 * 146 * The @p enable_port function is expected to enable si ngalling on given149 * The @p enable_port function is expected to enable signaling on given 147 150 * port. 148 151 * The two arguments to it can have arbitrary meaning … … 152 155 * 153 156 * If the @p enable_port fails (i.e. does not return EOK), the device 154 * addition is cancel led.157 * addition is canceled. 155 158 * The return value is then returned (it is good idea to use different 156 159 * error codes than those listed as return codes by this function itself). 157 160 * 158 * @param parent Parent device (i.e. the hub device).159 * @param connection Opened connection to host controller.160 * @param dev_speed New device speed.161 * @param enable_port Function for enabling signalling through the port the161 * @param[in] parent Parent device (i.e. the hub device). 162 * @param[in] connection Opened connection to host controller. 163 * @param[in] dev_speed New device speed. 164 * @param[in] enable_port Function for enabling signaling through the port the 162 165 * device is attached to. 163 * @param port_no Port number (passed through to @p enable_port).164 * @param arg Any data argument to @p enable_port.166 * @param[in] port_no Port number (passed through to @p enable_port). 167 * @param[in] arg Any data argument to @p enable_port. 165 168 * @param[out] assigned_address USB address of the device. 166 169 * @param[out] assigned_handle Devman handle of the new device. 170 * @param[in] dev_ops Child device ops. 171 * @param[in] new_dev_data Arbitrary pointer to be stored in the child 172 * as @c driver_data. 173 * @param[out] new_fun Storage where pointer to allocated child function 174 * will be written. 167 175 * @return Error code. 168 176 * @retval ENOENT Connection to HC not opened. … … 201 209 202 210 /* 203 * Enable the port (i.e. allow signal ling through this port).211 * Enable the port (i.e. allow signaling through this port). 204 212 */ 205 213 rc = enable_port(port_no, arg); -
uspace/lib/usb/src/pipes.c
r0588062e r8e9becf6 99 99 * 100 100 * @param connection Connection structure to be initialized. 101 * @param dev iceGeneric device backing the USB device.101 * @param dev Generic device backing the USB device. 102 102 * @return Error code. 103 103 */ -
uspace/lib/usb/src/pipesio.c
r0588062e r8e9becf6 115 115 116 116 if (data_request_rc != EOK) { 117 return (int) data_request_rc; 117 /* Prefer the return code of the opening request. */ 118 if (opening_request_rc != EOK) { 119 return (int) opening_request_rc; 120 } else { 121 return (int) data_request_rc; 122 } 118 123 } 119 124 if (opening_request_rc != EOK) { … … 331 336 332 337 if (data_request_rc != EOK) { 333 return (int) data_request_rc; 338 /* Prefer the return code of the opening request. */ 339 if (opening_request_rc != EOK) { 340 return (int) opening_request_rc; 341 } else { 342 return (int) data_request_rc; 343 } 334 344 } 335 345 if (opening_request_rc != EOK) { -
uspace/lib/usb/src/recognise.c
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @brief Functions for recognising kindof attached devices.33 * Functions for recognition of attached devices. 34 34 */ 35 35 #include <sys/types.h> … … 44 44 #include <assert.h> 45 45 46 /** Index to append after device name for uniqueness. */ 46 47 static size_t device_name_index = 0; 48 /** Mutex guard for device_name_index. */ 47 49 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 48 50 51 /** DDF operations of child devices. */ 49 52 ddf_dev_ops_t child_ops = { 50 53 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 51 54 }; 52 55 56 /** Get integer part from BCD coded number. */ 53 57 #define BCD_INT(a) (((unsigned int)(a)) / 256) 58 /** Get fraction part from BCD coded number (as an integer, no less). */ 54 59 #define BCD_FRAC(a) (((unsigned int)(a)) % 256) 55 60 61 /** Format for BCD coded number to be used in printf. */ 56 62 #define BCD_FMT "%x.%x" 63 /** Arguments to printf for BCD coded number. */ 57 64 #define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a)) 58 65 … … 113 120 } 114 121 122 /** Add match id to list or return with error code. 123 * 124 * @param match_ids List of match ids. 125 * @param score Match id score. 126 * @param format Format of the matching string 127 * @param ... Arguments for the format. 128 */ 115 129 #define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \ 116 130 do { \ … … 124 138 /** Create device match ids based on its interface. 125 139 * 126 * @param[in] descriptor Interface descriptor. 140 * @param[in] desc_device Device descriptor. 141 * @param[in] desc_interface Interface descriptor. 127 142 * @param[out] matches Initialized list of match ids. 128 143 * @return Error code (the two mentioned are not the only ones). 129 144 * @retval EINVAL Invalid input parameters (expects non NULL pointers). 130 * @retval ENOENT Interface does not specify class.145 * @retval ENOENT Device class is not "use interface". 131 146 */ 132 147 int usb_device_create_match_ids_from_interface( … … 319 334 * @param[in] parent Parent device. 320 335 * @param[out] child_handle Handle of the child device. 336 * @param[in] dev_ops Child device ops. 337 * @param[in] dev_data Arbitrary pointer to be stored in the child 338 * as @c driver_data. 339 * @param[out] child_fun Storage where pointer to allocated child function 340 * will be written. 321 341 * @return Error code. 322 342 */ -
uspace/lib/usb/src/request.c
r0588062e r8e9becf6 110 110 * (must be in USB endianness). 111 111 * @param data Buffer where to store data accepted during the DATA stage. 112 * (they will come in USB endian ess).112 * (they will come in USB endianness). 113 113 * @param data_size Size of the @p data buffer 114 114 * (in native endianness). … … 161 161 * the new address. 162 162 * 163 * @see usb_drv_reserve_default_address164 * @see usb_drv_release_default_address165 * @see usb_drv_request_address166 * @see usb_drv_release_address167 * @see usb_drv_bind_address168 *169 163 * @param pipe Control endpoint pipe (session must be already started). 170 164 * @param new_address New USB address to be set (in native endianness). … … 201 195 * @param[in] pipe Control endpoint pipe (session must be already started). 202 196 * @param[in] request_type Request type (standard/class/vendor). 197 * @param[in] recipient Request recipient (device/interface/endpoint). 203 198 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 204 199 * @param[in] descriptor_index Descriptor index. … … 235 230 * @param[in] pipe Control endpoint pipe (session must be already started). 236 231 * @param[in] request_type Request type (standard/class/vendor). 232 * @param[in] recipient Request recipient (device/interface/endpoint). 237 233 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 238 234 * @param[in] descriptor_index Descriptor index. … … 528 524 return EEMPTY; 529 525 } 530 /* Sub stract first 2 bytes (length and descriptor type). */526 /* Subtract first 2 bytes (length and descriptor type). */ 531 527 string_descriptor_size -= 2; 532 528 … … 548 544 size_t i; 549 545 for (i = 0; i < langs_count; i++) { 550 /* Language code from the descriptor is in USB endian ess. */546 /* Language code from the descriptor is in USB endianness. */ 551 547 /* FIXME: is this really correct? */ 552 548 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8) … … 569 565 * 570 566 * @param[in] pipe Control endpoint pipe (session must be already started). 571 * @param[in] index String index (in native endian ess),567 * @param[in] index String index (in native endianness), 572 568 * first index has number 1 (index from descriptors can be used directly). 573 * @param[in] lang String language (in native endian ess).569 * @param[in] lang String language (in native endianness). 574 570 * @param[out] string_ptr Where to store allocated string in native encoding. 575 571 * @return Error code. … … 613 609 goto leave; 614 610 } 615 /* Sub stract first 2 bytes (length and descriptor type). */611 /* Subtract first 2 bytes (length and descriptor type). */ 616 612 string_size -= 2; 617 613 -
uspace/lib/usb/src/usb.c
r0588062e r8e9becf6 31 31 */ 32 32 /** @file 33 * @brief Base USB types.33 * Common USB functions. 34 34 */ 35 35 #include <usb/usb.h> … … 37 37 38 38 39 /** String representation for USB transfer type. */ 39 /** String representation for USB transfer type. 40 * 41 * @param t Transfer type. 42 * @return Transfer type as a string (in English). 43 */ 40 44 const char * usb_str_transfer_type(usb_transfer_type_t t) 41 45 {
Note:
See TracChangeset
for help on using the changeset viewer.