Changeset 97ab321 in mainline
- Timestamp:
- 2011-04-07T09:53:12Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d41f301
- Parents:
- c4e0b47 (diff), 41c1f7b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 7 added
- 17 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
rc4e0b47 r97ab321 73 73 CHECK_NULL_DISPOSE_RETURN(instance, 74 74 "Failed to allocate batch instance.\n"); 75 usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size,76 buffer, NULL, buffer_size, NULL, setup_size, func_in,77 func_ out, arg, fun, NULL);75 usb_transfer_batch_init(instance, target, transfer_type, speed, 76 max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 77 func_in, func_out, arg, fun, NULL, NULL); 78 78 79 79 if (buffer_size > 0) { -
uspace/drv/ohci/hc.c
rc4e0b47 r97ab321 92 92 instance->ddf_instance = fun; 93 93 usb_device_keeper_init(&instance->manager); 94 ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,95 bandwidth_count_usb11);96 CHECK_RET_RETURN(ret, "Failed to initialize bandwidth allocator: %s.\n",94 ret = usb_endpoint_manager_init(&instance->ep_manager, 95 BANDWIDTH_AVAILABLE_USB11); 96 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n", 97 97 ret, str_error(ret)); 98 98 … … 183 183 * maintain reset for at least the time specified in USB spec (50 ms)*/ 184 184 async_usleep(50000); 185 186 /* turn off legacy emulation */ 187 volatile uint32_t *ohci_emulation_reg = 188 (uint32_t*)((char*)instance->registers + 0x100); 189 usb_log_info("OHCI legacy register status %p: %x.\n", 190 ohci_emulation_reg, *ohci_emulation_reg); 191 *ohci_emulation_reg = 0; 192 185 193 } 186 194 /*----------------------------------------------------------------------------*/ -
uspace/drv/ohci/hc.h
rc4e0b47 r97ab321 42 42 #include <usb/usb.h> 43 43 #include <usb/host/device_keeper.h> 44 #include <usb/host/ bandwidth.h>44 #include <usb/host/usb_endpoint_manager.h> 45 45 #include <usbhc_iface.h> 46 46 … … 48 48 #include "ohci_regs.h" 49 49 #include "root_hub.h" 50 #include "hw_struct/hcca.h" 50 51 51 52 typedef struct hc { … … 55 56 ddf_fun_t *ddf_instance; 56 57 usb_device_keeper_t manager; 57 bandwidth_t bandwidth;58 usb_endpoint_manager_t ep_manager; 58 59 fid_t interrupt_emulator; 59 60 } hc_t; -
uspace/drv/ohci/iface.c
rc4e0b47 r97ab321 162 162 address, endpoint, usb_str_transfer_type(transfer_type), 163 163 usb_str_speed(speed), direction, size, max_packet_size, interval); 164 return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction,165 speed, transfer_type, max_packet_size, size, interval);164 // TODO use real endpoint here! 165 return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0); 166 166 } 167 167 /*----------------------------------------------------------------------------*/ … … 183 183 usb_log_debug("Unregister endpoint %d:%d %d.\n", 184 184 address, endpoint, direction); 185 return bandwidth_release(&hc->bandwidth, address, endpoint, direction); 186 187 return ENOTSUP; 185 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 186 endpoint, direction); 188 187 } 189 188 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/batch.c
rc4e0b47 r97ab321 49 49 td_t *tds; 50 50 size_t transfers; 51 usb_device_keeper_t *manager;52 51 } uhci_batch_t; 53 52 … … 73 72 * @param[in] func_out function to call on outbound transaction completion 74 73 * @param[in] arg additional parameter to func_in or func_out 75 * @param[in] manager Pointer totoggle management structure.74 * @param[in] ep Pointer to endpoint toggle management structure. 76 75 * @return Valid pointer if all substructures were successfully created, 77 76 * NULL otherwise. … … 86 85 char* setup_buffer, size_t setup_size, 87 86 usbhc_iface_transfer_in_callback_t func_in, 88 usbhc_iface_transfer_out_callback_t func_out, void *arg, 89 usb_device_keeper_t *manager 87 usbhc_iface_transfer_out_callback_t func_out, void *arg, endpoint_t *ep 90 88 ) 91 89 { … … 105 103 CHECK_NULL_DISPOSE_RETURN(instance, 106 104 "Failed to allocate batch instance.\n"); 107 usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size, 105 usb_transfer_batch_init(instance, target, 106 transfer_type, speed, max_packet_size, 108 107 buffer, NULL, buffer_size, NULL, setup_size, func_in, 109 func_out, arg, fun, NULL);108 func_out, arg, fun, ep, NULL); 110 109 111 110 … … 114 113 "Failed to allocate batch instance.\n"); 115 114 bzero(data, sizeof(uhci_batch_t)); 116 data->manager = manager;117 115 instance->private_data = data; 118 116 … … 180 178 instance, i, data->tds[i].status); 181 179 td_print_status(&data->tds[i]); 182 183 usb_device_keeper_set_toggle(data->manager, 184 instance->target, instance->direction, 185 td_toggle(&data->tds[i])); 180 if (instance->ep != NULL) 181 endpoint_toggle_set(instance->ep, 182 td_toggle(&data->tds[i])); 186 183 if (i > 0) 187 184 goto substract_ret; … … 310 307 311 308 const bool low_speed = instance->speed == USB_SPEED_LOW; 312 int toggle = usb_device_keeper_get_toggle( 313 data->manager, instance->target, instance->direction); 309 int toggle = endpoint_toggle_get(instance->ep); 314 310 assert(toggle == 0 || toggle == 1); 315 311 … … 342 338 } 343 339 td_set_ioc(&data->tds[transfer - 1]); 344 usb_device_keeper_set_toggle(data->manager, instance->target, 345 instance->direction, toggle); 340 endpoint_toggle_set(instance->ep, toggle); 346 341 } 347 342 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/batch.h
rc4e0b47 r97ab321 35 35 #define DRV_UHCI_BATCH_H 36 36 37 #include <adt/list.h>38 39 37 #include <usbhc_iface.h> 40 38 #include <usb/usb.h> 41 39 #include <usb/host/device_keeper.h> 40 #include <usb/host/endpoint.h> 42 41 #include <usb/host/batch.h> 43 42 … … 57 56 usbhc_iface_transfer_out_callback_t func_out, 58 57 void *arg, 59 usb_device_keeper_t *manager58 endpoint_t *ep 60 59 ); 61 60 -
uspace/drv/uhci-hcd/hc.c
rc4e0b47 r97ab321 66 66 static int hc_interrupt_emulator(void *arg); 67 67 static int hc_debug_checker(void *arg); 68 68 #if 0 69 69 static bool usb_is_allowed( 70 70 bool low_speed, usb_transfer_type_t transfer, size_t size); 71 #endif 71 72 /*----------------------------------------------------------------------------*/ 72 73 /** Initialize UHCI hcd driver structure … … 239 240 usb_log_debug("Initialized device manager.\n"); 240 241 241 ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11, 242 bandwidth_count_usb11); 242 ret = 243 usb_endpoint_manager_init(&instance->ep_manager, 244 BANDWIDTH_AVAILABLE_USB11); 243 245 assert(ret == EOK); 244 246 … … 326 328 assert(instance); 327 329 assert(batch); 328 const int low_speed = (batch->speed == USB_SPEED_LOW);329 if (!usb_is_allowed(330 low_speed, batch->transfer_type, batch->max_packet_size)) {331 usb_log_error("Invalid USB transfer specified %s %d %zu.\n",332 usb_str_speed(batch->speed), batch->transfer_type,333 batch->max_packet_size);334 return ENOTSUP;335 }336 /* Check available bandwidth */337 if (batch->transfer_type == USB_TRANSFER_INTERRUPT ||338 batch->transfer_type == USB_TRANSFER_ISOCHRONOUS) {339 int ret =340 bandwidth_use(&instance->bandwidth, batch->target.address,341 batch->target.endpoint, batch->direction);342 if (ret != EOK) {343 usb_log_warning("Failed(%d) to use reserved bw: %s.\n",344 ret, str_error(ret));345 }346 }347 330 348 331 transfer_list_t *list = … … 398 381 case USB_TRANSFER_INTERRUPT: 399 382 case USB_TRANSFER_ISOCHRONOUS: { 383 /* 400 384 int ret = bandwidth_free(&instance->bandwidth, 401 385 batch->target.address, … … 406 390 "reserved bw: %s.\n", ret, 407 391 str_error(ret)); 392 */ 408 393 } 409 394 default: … … 529 514 * @return True if transaction is allowed by USB specs, false otherwise 530 515 */ 516 #if 0 531 517 bool usb_is_allowed( 532 518 bool low_speed, usb_transfer_type_t transfer, size_t size) … … 546 532 return false; 547 533 } 534 #endif 548 535 /** 549 536 * @} -
uspace/drv/uhci-hcd/hc.h
rc4e0b47 r97ab321 43 43 #include <usbhc_iface.h> 44 44 #include <usb/host/device_keeper.h> 45 #include <usb/host/ bandwidth.h>45 #include <usb/host/usb_endpoint_manager.h> 46 46 47 47 #include "batch.h" … … 85 85 typedef struct hc { 86 86 usb_device_keeper_t manager; 87 bandwidth_t bandwidth;87 usb_endpoint_manager_t ep_manager; 88 88 89 89 regs_t *registers; -
uspace/drv/uhci-hcd/hw_struct/queue_head.h
rc4e0b47 r97ab321 39 39 40 40 #include "link_pointer.h" 41 #include "utils/malloc32.h"42 41 43 42 typedef struct queue_head { -
uspace/drv/uhci-hcd/iface.c
rc4e0b47 r97ab321 36 36 37 37 #include <usb/debug.h> 38 #include <usb/host/endpoint.h> 38 39 39 40 #include "iface.h" … … 54 55 usb_device_keeper_reserve_default_address(&hc->manager, speed); 55 56 return EOK; 57 #if 0 58 endpoint_t *ep = malloc(sizeof(endpoint_t)); 59 if (ep == NULL) 60 return ENOMEM; 61 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64; 62 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size); 63 int ret; 64 try_retgister: 65 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, 66 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0); 67 if (ret == EEXISTS) { 68 async_usleep(1000); 69 goto try_retgister; 70 } 71 if (ret != EOK) { 72 endpoint_destroy(ep); 73 } 74 return ret; 75 #endif 56 76 } 57 77 /*----------------------------------------------------------------------------*/ … … 67 87 assert(hc); 68 88 usb_log_debug("Default address release.\n"); 89 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager, 90 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH); 69 91 usb_device_keeper_release_default_address(&hc->manager); 70 92 return EOK; … … 137 159 const usb_speed_t speed = 138 160 usb_device_keeper_get_speed(&hc->manager, address); 139 size_t size = max_packet_size; 161 const size_t size = 162 (transfer_type == USB_TRANSFER_INTERRUPT 163 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 164 max_packet_size : 0; 165 int ret; 166 167 endpoint_t *ep = malloc(sizeof(endpoint_t)); 168 if (ep == NULL) 169 return ENOMEM; 170 ret = endpoint_init(ep, address, endpoint, direction, 171 transfer_type, speed, max_packet_size); 172 if (ret != EOK) { 173 free(ep); 174 return ret; 175 } 140 176 141 177 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 142 178 address, endpoint, usb_str_transfer_type(transfer_type), 143 179 usb_str_speed(speed), direction, size, max_packet_size, interval); 144 return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction, 145 speed, transfer_type, max_packet_size, size, interval); 180 181 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 182 if (ret != EOK) { 183 endpoint_destroy(ep); 184 } else { 185 usb_device_keeper_add_ep(&hc->manager, address, ep); 186 } 187 return ret; 146 188 } 147 189 /*----------------------------------------------------------------------------*/ … … 154 196 usb_log_debug("Unregister endpoint %d:%d %d.\n", 155 197 address, endpoint, direction); 156 return bandwidth_release(&hc->bandwidth, address, endpoint, direction); 198 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 199 endpoint, direction); 157 200 } 158 201 /*----------------------------------------------------------------------------*/ … … 175 218 hc_t *hc = fun_to_hc(fun); 176 219 assert(hc); 177 usb_speed_t speed =178 usb_device_keeper_get_speed(&hc->manager, target.address);179 220 180 221 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 181 222 target.address, target.endpoint, size, max_packet_size); 182 223 224 size_t res_bw; 225 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 226 target.address, target.endpoint, USB_DIRECTION_OUT, &res_bw); 227 if (ep == NULL) { 228 usb_log_error("Endpoint(%d:%d) not registered for INT OUT.\n", 229 target.address, target.endpoint); 230 return ENOENT; 231 } 232 const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type, 233 size, ep->max_packet_size); 234 if (res_bw < bw) 235 { 236 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw " 237 "but only %zu is reserved.\n", 238 target.address, target.endpoint, bw, res_bw); 239 return ENOENT; 240 } 241 assert(ep->speed == 242 usb_device_keeper_get_speed(&hc->manager, target.address)); 243 assert(ep->max_packet_size == max_packet_size); 244 assert(ep->transfer_type == USB_TRANSFER_INTERRUPT); 245 183 246 usb_transfer_batch_t *batch = 184 batch_get(fun, target, USB_TRANSFER_INTERRUPT,max_packet_size,185 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);247 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 248 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep); 186 249 if (!batch) 187 250 return ENOMEM; … … 212 275 hc_t *hc = fun_to_hc(fun); 213 276 assert(hc); 214 usb_speed_t speed = 215 usb_device_keeper_get_speed(&hc->manager, target.address); 277 216 278 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 217 279 target.address, target.endpoint, size, max_packet_size); 218 280 281 size_t res_bw; 282 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 283 target.address, target.endpoint, USB_DIRECTION_IN, &res_bw); 284 if (ep == NULL) { 285 usb_log_error("Endpoint(%d:%d) not registered for INT IN.\n", 286 target.address, target.endpoint); 287 return ENOENT; 288 } 289 const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type, 290 size, ep->max_packet_size); 291 if (res_bw < bw) 292 { 293 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw " 294 "but only %zu bw is reserved.\n", 295 target.address, target.endpoint, bw, res_bw); 296 return ENOENT; 297 } 298 299 assert(ep->speed == 300 usb_device_keeper_get_speed(&hc->manager, target.address)); 301 assert(ep->max_packet_size == max_packet_size); 302 assert(ep->transfer_type == USB_TRANSFER_INTERRUPT); 303 219 304 usb_transfer_batch_t *batch = 220 batch_get(fun, target, USB_TRANSFER_INTERRUPT,max_packet_size,221 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);305 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 306 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep); 222 307 if (!batch) 223 308 return ENOMEM; … … 248 333 hc_t *hc = fun_to_hc(fun); 249 334 assert(hc); 250 usb_speed_t speed =251 usb_device_keeper_get_speed(&hc->manager, target.address);252 335 253 336 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 254 337 target.address, target.endpoint, size, max_packet_size); 255 338 339 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 340 target.address, target.endpoint, USB_DIRECTION_OUT, NULL); 341 if (ep == NULL) { 342 usb_log_error("Endpoint(%d:%d) not registered for BULK OUT.\n", 343 target.address, target.endpoint); 344 return ENOENT; 345 } 346 assert(ep->speed == 347 usb_device_keeper_get_speed(&hc->manager, target.address)); 348 assert(ep->max_packet_size == max_packet_size); 349 assert(ep->transfer_type == USB_TRANSFER_BULK); 350 256 351 usb_transfer_batch_t *batch = 257 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,258 data, size, NULL, 0, NULL, callback, arg, &hc->manager);352 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 353 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep); 259 354 if (!batch) 260 355 return ENOMEM; … … 285 380 hc_t *hc = fun_to_hc(fun); 286 381 assert(hc); 287 usb_speed_t speed =288 usb_device_keeper_get_speed(&hc->manager, target.address);289 382 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 290 383 target.address, target.endpoint, size, max_packet_size); 291 384 385 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 386 target.address, target.endpoint, USB_DIRECTION_IN, NULL); 387 if (ep == NULL) { 388 usb_log_error("Endpoint(%d:%d) not registered for BULK IN.\n", 389 target.address, target.endpoint); 390 return ENOENT; 391 } 392 assert(ep->speed == 393 usb_device_keeper_get_speed(&hc->manager, target.address)); 394 assert(ep->max_packet_size == max_packet_size); 395 assert(ep->transfer_type == USB_TRANSFER_BULK); 396 292 397 usb_transfer_batch_t *batch = 293 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,294 data, size, NULL, 0, callback, NULL, arg, &hc->manager);398 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 399 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep); 295 400 if (!batch) 296 401 return ENOMEM; … … 328 433 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 329 434 speed, target.address, target.endpoint, size, max_packet_size); 435 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 436 target.address, target.endpoint, USB_DIRECTION_BOTH, NULL); 437 if (ep == NULL) { 438 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n", 439 target.address, target.endpoint); 440 } 330 441 331 442 if (setup_size != 8) … … 334 445 usb_transfer_batch_t *batch = 335 446 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 336 data, size, setup_data, setup_size, NULL, callback, arg, 337 &hc->manager); 447 data, size, setup_data, setup_size, NULL, callback, arg, ep); 338 448 if (!batch) 339 449 return ENOMEM; … … 373 483 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 374 484 speed, target.address, target.endpoint, size, max_packet_size); 485 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 486 target.address, target.endpoint, USB_DIRECTION_BOTH, NULL); 487 if (ep == NULL) { 488 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n", 489 target.address, target.endpoint); 490 } 375 491 usb_transfer_batch_t *batch = 376 492 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 377 data, size, setup_data, setup_size, callback, NULL, arg, 378 &hc->manager); 493 data, size, setup_data, setup_size, callback, NULL, arg, ep); 379 494 if (!batch) 380 495 return ENOMEM; -
uspace/drv/uhci-hcd/transfer_list.h
rc4e0b47 r97ab321 39 39 #include "batch.h" 40 40 #include "hw_struct/queue_head.h" 41 #include "utils/malloc32.h" 41 42 42 43 typedef struct transfer_list -
uspace/drv/uhci-hcd/utils/malloc32.h
rc4e0b47 r97ab321 36 36 37 37 #include <assert.h> 38 #include <errno.h> 38 39 #include <malloc.h> 39 40 #include <mem.h> -
uspace/lib/usb/Makefile
rc4e0b47 r97ab321 54 54 src/host/device_keeper.c \ 55 55 src/host/batch.c \ 56 src/host/bandwidth.c 56 src/host/endpoint.c \ 57 src/host/usb_endpoint_manager.c 57 58 58 59 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usb/include/usb/host/batch.h
rc4e0b47 r97ab321 39 39 #include <usbhc_iface.h> 40 40 #include <usb/usb.h> 41 #include <usb/host/endpoint.h> 41 42 42 43 typedef struct usb_transfer_batch usb_transfer_batch_t; … … 60 61 ddf_fun_t *fun; 61 62 void *arg; 63 endpoint_t *ep; 62 64 void *private_data; 63 65 }; … … 78 80 void *arg, 79 81 ddf_fun_t *fun, 82 endpoint_t *ep, 80 83 void *private_data 81 84 ); -
uspace/lib/usb/include/usb/host/device_keeper.h
rc4e0b47 r97ab321 40 40 #ifndef LIBUSB_HOST_DEVICE_KEEPER_H 41 41 #define LIBUSB_HOST_DEVICE_KEEPER_H 42 43 #include <adt/list.h> 42 44 #include <devman.h> 43 45 #include <fibril_synch.h> 44 46 #include <usb/usb.h> 47 #include <usb/host/endpoint.h> 45 48 46 49 /** Number of USB address for array dimensions. */ … … 51 54 usb_speed_t speed; 52 55 bool occupied; 56 link_t endpoints; 53 57 uint16_t control_used; 54 uint16_t toggle_status[2];55 58 devman_handle_t handle; 56 59 }; … … 68 71 void usb_device_keeper_init(usb_device_keeper_t *instance); 69 72 70 void usb_device_keeper_reserve_default_address(usb_device_keeper_t *instance, 71 usb_speed_t speed); 73 void usb_device_keeper_add_ep( 74 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep); 75 76 void usb_device_keeper_reserve_default_address( 77 usb_device_keeper_t *instance, usb_speed_t speed); 72 78 73 79 void usb_device_keeper_release_default_address(usb_device_keeper_t *instance); 74 80 75 81 void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance, 76 usb_target_t target, 77 const uint8_t *setup_data); 78 79 int usb_device_keeper_get_toggle(usb_device_keeper_t *instance, 80 usb_target_t target, usb_direction_t direction); 81 82 int usb_device_keeper_set_toggle(usb_device_keeper_t *instance, 83 usb_target_t target, usb_direction_t direction, bool toggle); 82 usb_target_t target, const uint8_t *setup_data); 84 83 85 84 usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance, -
uspace/lib/usb/include/usb/host/usb_endpoint_manager.h
rc4e0b47 r97ab321 37 37 * This structure shall simplify the management. 38 38 */ 39 #ifndef LIBUSB_HOST_ BANDWIDTH_H40 #define LIBUSB_HOST_ BANDWIDTH_H39 #ifndef LIBUSB_HOST_USB_ENDPOINT_MANAGER_H 40 #define LIBUSB_HOST_YSB_ENDPOINT_MANAGER_H 41 41 42 42 #include <adt/hash_table.h> 43 43 #include <fibril_synch.h> 44 44 #include <usb/usb.h> 45 #include <usb/host/endpoint.h> 45 46 46 47 #define BANDWIDTH_TOTAL_USB11 12000000 47 48 #define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9) 48 49 49 typedef struct bandwidth{50 hash_table_t reserved;50 typedef struct usb_endpoint_manager { 51 hash_table_t ep_table; 51 52 fibril_mutex_t guard; 52 size_t free;53 size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t);54 } bandwidth_t;53 fibril_condvar_t change; 54 size_t free_bw; 55 } usb_endpoint_manager_t; 55 56 56 57 size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type, 57 58 size_t size, size_t max_packet_size); 58 59 59 int bandwidth_init(bandwidth_t *instance, size_t bandwidth,60 size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t));60 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance, 61 size_t available_bandwidth); 61 62 62 void bandwidth_destroy(bandwidth_t *instance);63 void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance); 63 64 64 int bandwidth_reserve(bandwidth_t *instance, usb_address_t address, 65 usb_endpoint_t endpoint, usb_direction_t direction, usb_speed_t speed, 66 usb_transfer_type_t transfer_type, size_t max_packet_size, size_t size, 67 unsigned interval); 65 int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance, 66 endpoint_t *ep, size_t data_size); 68 67 69 int bandwidth_release(bandwidth_t *instance, usb_address_t address, 70 usb_endpoint_t endpoint, usb_direction_t direction); 68 int usb_endpoint_manager_register_ep_wait(usb_endpoint_manager_t *instance, 69 usb_address_t address, usb_endpoint_t ep, usb_direction_t direction, 70 void *data, void (*data_remove_callback)(void* data, void* arg), void *arg, 71 size_t bw); 71 72 72 int bandwidth_use(bandwidth_t *instance, usb_address_t address,73 usb_ endpoint_t endpoint, usb_direction_t direction);73 int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance, 74 usb_address_t address, usb_endpoint_t ep, usb_direction_t direction); 74 75 75 int bandwidth_free(bandwidth_t *instance, usb_address_t address, 76 usb_endpoint_t endpoint, usb_direction_t direction); 76 endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance, 77 usb_address_t address, usb_endpoint_t ep, usb_direction_t direction, 78 size_t *bw); 77 79 78 80 #endif … … 80 82 * @} 81 83 */ 84 -
uspace/lib/usb/src/host/batch.c
rc4e0b47 r97ab321 54 54 void *arg, 55 55 ddf_fun_t *fun, 56 endpoint_t *ep, 56 57 void *private_data 57 58 ) … … 77 78 instance->next_step = NULL; 78 79 instance->error = EOK; 79 80 instance->ep = ep; 80 81 } 81 82 /*----------------------------------------------------------------------------*/ -
uspace/lib/usb/src/host/device_keeper.c
rc4e0b47 r97ab321 56 56 instance->devices[i].control_used = 0; 57 57 instance->devices[i].handle = 0; 58 instance->devices[i].toggle_status[0] = 0; 59 instance->devices[i].toggle_status[1] = 0; 60 } 58 list_initialize(&instance->devices[i].endpoints); 59 } 60 } 61 /*----------------------------------------------------------------------------*/ 62 void usb_device_keeper_add_ep( 63 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep) 64 { 65 assert(instance); 66 fibril_mutex_lock(&instance->guard); 67 assert(instance->devices[address].occupied); 68 list_append(&ep->same_device_eps, &instance->devices[address].endpoints); 69 fibril_mutex_unlock(&instance->guard); 61 70 } 62 71 /*----------------------------------------------------------------------------*/ … … 66 75 * @param[in] speed Speed of the device requesting default address. 67 76 */ 68 void usb_device_keeper_reserve_default_address( usb_device_keeper_t *instance,69 usb_ speed_t speed)77 void usb_device_keeper_reserve_default_address( 78 usb_device_keeper_t *instance, usb_speed_t speed) 70 79 { 71 80 assert(instance); … … 101 110 * Really ugly one. 102 111 */ 103 void usb_device_keeper_reset_if_need( usb_device_keeper_t *instance,104 usb_ target_t target, const uint8_t *data)112 void usb_device_keeper_reset_if_need( 113 usb_device_keeper_t *instance, usb_target_t target, const uint8_t *data) 105 114 { 106 115 assert(instance); … … 119 128 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */ 120 129 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 130 link_t *current = 131 instance->devices[target.address].endpoints.next; 132 while (current != 133 &instance->devices[target.address].endpoints) 134 { 121 135 /* endpoint number is < 16, thus first byte is enough */ 122 instance->devices[target.address].toggle_status[0] &=123 ~(1 <<data[4]);124 instance->devices[target.address].toggle_status[1] &=125 ~(1 << data[4]);136 endpoint_toggle_reset_filtered( 137 current, data[4]); 138 current = current->next; 139 } 126 140 } 127 141 break; … … 131 145 /* target must be device */ 132 146 if ((data[0] & 0xf) == 0) { 133 instance->devices[target.address].toggle_status[0] = 0; 134 instance->devices[target.address].toggle_status[1] = 0; 147 link_t *current = 148 instance->devices[target.address].endpoints.next; 149 while (current != 150 &instance->devices[target.address].endpoints) 151 { 152 endpoint_toggle_reset(current); 153 current = current->next; 154 } 135 155 } 136 156 break; 137 157 } 138 158 fibril_mutex_unlock(&instance->guard); 139 }140 /*----------------------------------------------------------------------------*/141 /** Get current value of endpoint toggle.142 *143 * @param[in] instance Device keeper structure to use.144 * @param[in] target Device and endpoint used.145 * @return Error code146 */147 int usb_device_keeper_get_toggle(usb_device_keeper_t *instance,148 usb_target_t target, usb_direction_t direction)149 {150 assert(instance);151 /* only control pipes are bi-directional and those do not need toggle */152 if (direction == USB_DIRECTION_BOTH)153 return ENOENT;154 int ret;155 fibril_mutex_lock(&instance->guard);156 if (target.endpoint > 15 || target.endpoint < 0157 || target.address >= USB_ADDRESS_COUNT || target.address < 0158 || !instance->devices[target.address].occupied) {159 usb_log_error("Invalid data when asking for toggle value.\n");160 ret = EINVAL;161 } else {162 ret = (instance->devices[target.address].toggle_status[direction]163 >> target.endpoint) & 1;164 }165 fibril_mutex_unlock(&instance->guard);166 return ret;167 }168 /*----------------------------------------------------------------------------*/169 /** Set current value of endpoint toggle.170 *171 * @param[in] instance Device keeper structure to use.172 * @param[in] target Device and endpoint used.173 * @param[in] toggle Toggle value.174 * @return Error code.175 */176 int usb_device_keeper_set_toggle(usb_device_keeper_t *instance,177 usb_target_t target, usb_direction_t direction, bool toggle)178 {179 assert(instance);180 /* only control pipes are bi-directional and those do not need toggle */181 if (direction == USB_DIRECTION_BOTH)182 return ENOENT;183 int ret;184 fibril_mutex_lock(&instance->guard);185 if (target.endpoint > 15 || target.endpoint < 0186 || target.address >= USB_ADDRESS_COUNT || target.address < 0187 || !instance->devices[target.address].occupied) {188 usb_log_error("Invalid data when setting toggle value.\n");189 ret = EINVAL;190 } else {191 if (toggle) {192 instance->devices[target.address].toggle_status[direction]193 |= (1 << target.endpoint);194 } else {195 instance->devices[target.address].toggle_status[direction]196 &= ~(1 << target.endpoint);197 }198 ret = EOK;199 }200 fibril_mutex_unlock(&instance->guard);201 return ret;202 159 } 203 160 /*----------------------------------------------------------------------------*/ … … 208 165 * @return Free address, or error code. 209 166 */ 210 usb_address_t device_keeper_get_free_address( usb_device_keeper_t *instance,211 usb_ speed_t speed)167 usb_address_t device_keeper_get_free_address( 168 usb_device_keeper_t *instance, usb_speed_t speed) 212 169 { 213 170 assert(instance); … … 229 186 instance->devices[new_address].occupied = true; 230 187 instance->devices[new_address].speed = speed; 231 instance->devices[new_address].toggle_status[0] = 0;232 instance->devices[new_address].toggle_status[1] = 0;233 188 instance->last_address = new_address; 234 189 fibril_mutex_unlock(&instance->guard); … … 259 214 * @param[in] address Device address 260 215 */ 261 void usb_device_keeper_release( usb_device_keeper_t *instance,262 usb_ address_t address)216 void usb_device_keeper_release( 217 usb_device_keeper_t *instance, usb_address_t address) 263 218 { 264 219 assert(instance); … … 278 233 * @return USB Address, or error code. 279 234 */ 280 usb_address_t usb_device_keeper_find( usb_device_keeper_t *instance,281 devman_handle_t handle)235 usb_address_t usb_device_keeper_find( 236 usb_device_keeper_t *instance, devman_handle_t handle) 282 237 { 283 238 assert(instance); … … 301 256 * @return USB speed. 302 257 */ 303 usb_speed_t usb_device_keeper_get_speed( usb_device_keeper_t *instance,304 usb_ address_t address)258 usb_speed_t usb_device_keeper_get_speed( 259 usb_device_keeper_t *instance, usb_address_t address) 305 260 { 306 261 assert(instance); … … 310 265 } 311 266 /*----------------------------------------------------------------------------*/ 312 void usb_device_keeper_use_control( usb_device_keeper_t *instance,313 usb_ target_t target)267 void usb_device_keeper_use_control( 268 usb_device_keeper_t *instance, usb_target_t target) 314 269 { 315 270 assert(instance); … … 323 278 } 324 279 /*----------------------------------------------------------------------------*/ 325 void usb_device_keeper_release_control( usb_device_keeper_t *instance,326 usb_ target_t target)280 void usb_device_keeper_release_control( 281 usb_device_keeper_t *instance, usb_target_t target) 327 282 { 328 283 assert(instance); -
uspace/lib/usb/src/host/usb_endpoint_manager.c
rc4e0b47 r97ab321 1 1 /* 2 2 * Copyright (c) 2011 Jan Vesely 3 * All rights reserved.3 * All rights eps. 4 4 * 5 5 * Redistribution and use in source and binary forms, with or without … … 27 27 */ 28 28 29 #include <bool.h> 29 30 #include <assert.h> 30 31 #include <errno.h> 31 #include <usb/host/bandwidth.h> 32 32 33 #include <usb/host/usb_endpoint_manager.h> 34 35 #define BUCKET_COUNT 7 36 37 #define MAX_KEYS (3) 33 38 typedef struct { 34 usb_address_t address;35 usb_endpoint_t endpoint;36 usb_direction_t direction;37 } __attribute__((aligned (sizeof(unsigned long)))) transfer_t;38 /*----------------------------------------------------------------------------*/39 typedef struct {40 transfer_t transfer;41 39 link_t link; 42 bool used; 43 size_t required; 44 } transfer_status_t; 45 /*----------------------------------------------------------------------------*/ 46 #define BUCKET_COUNT 7 47 #define MAX_KEYS (sizeof(transfer_t) / sizeof(unsigned long)) 48 /*----------------------------------------------------------------------------*/ 49 static hash_index_t transfer_hash(unsigned long key[]) 40 size_t bw; 41 endpoint_t *ep; 42 } node_t; 43 /*----------------------------------------------------------------------------*/ 44 static hash_index_t node_hash(unsigned long key[]) 50 45 { 51 46 hash_index_t hash = 0; … … 58 53 } 59 54 /*----------------------------------------------------------------------------*/ 60 static int transfer_compare( 61 unsigned long key[], hash_count_t keys, link_t *item) 55 static int node_compare(unsigned long key[], hash_count_t keys, link_t *item) 62 56 { 63 57 assert(item); 64 transfer_status_t *status = 65 hash_table_get_instance(item, transfer_status_t, link); 66 const size_t bytes = 67 keys < MAX_KEYS ? keys * sizeof(unsigned long) : sizeof(transfer_t); 68 return bcmp(key, &status->transfer, bytes); 69 } 70 /*----------------------------------------------------------------------------*/ 71 static void transfer_remove(link_t *item) 58 node_t *node = hash_table_get_instance(item, node_t, link); 59 assert(node); 60 assert(node->ep); 61 bool match = true; 62 switch (keys) { 63 case 3: 64 match = match && (key[2] == node->ep->direction); 65 case 2: 66 match = match && (key[1] == (unsigned long)node->ep->endpoint); 67 case 1: 68 match = match && (key[0] == (unsigned long)node->ep->address); 69 break; 70 default: 71 match = false; 72 } 73 return match; 74 } 75 /*----------------------------------------------------------------------------*/ 76 static void node_remove(link_t *item) 72 77 { 73 78 assert(item); 74 transfer_status_t *status = 75 hash_table_get_instance(item, transfer_status_t, link); 76 assert(status); 77 free(status); 78 } 79 /*----------------------------------------------------------------------------*/ 80 hash_table_operations_t op = { 81 .hash = transfer_hash, 82 .compare = transfer_compare, 83 .remove_callback = transfer_remove, 79 node_t *node = hash_table_get_instance(item, node_t, link); 80 endpoint_destroy(node->ep); 81 free(node); 82 } 83 /*----------------------------------------------------------------------------*/ 84 static hash_table_operations_t op = { 85 .hash = node_hash, 86 .compare = node_compare, 87 .remove_callback = node_remove, 84 88 }; 85 89 /*----------------------------------------------------------------------------*/ … … 120 124 } 121 125 /*----------------------------------------------------------------------------*/ 122 int bandwidth_init(bandwidth_t *instance, size_t bandwidth,123 size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t))126 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance, 127 size_t available_bandwidth) 124 128 { 125 129 assert(instance); 126 130 fibril_mutex_initialize(&instance->guard); 127 instance->free = bandwidth;128 instance-> usage_fnc = usage_fnc;131 fibril_condvar_initialize(&instance->change); 132 instance->free_bw = available_bandwidth; 129 133 bool ht = 130 hash_table_create(&instance-> reserved, BUCKET_COUNT, MAX_KEYS, &op);134 hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op); 131 135 return ht ? EOK : ENOMEM; 132 136 } 133 137 /*----------------------------------------------------------------------------*/ 134 void bandwidth_destroy(bandwidth_t *instance) 135 { 136 hash_table_destroy(&instance->reserved); 137 } 138 /*----------------------------------------------------------------------------*/ 139 int bandwidth_reserve(bandwidth_t *instance, usb_address_t address, 140 usb_endpoint_t endpoint, usb_direction_t direction, usb_speed_t speed, 141 usb_transfer_type_t transfer_type, size_t max_packet_size, size_t size, 142 unsigned interval) 143 { 144 if (transfer_type != USB_TRANSFER_ISOCHRONOUS && 145 transfer_type != USB_TRANSFER_INTERRUPT) { 146 return ENOTSUP; 147 } 148 149 assert(instance); 150 assert(instance->usage_fnc); 151 152 transfer_t trans = { 153 .address = address, 154 .endpoint = endpoint, 155 .direction = direction, 156 }; 138 void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance) 139 { 140 hash_table_destroy(&instance->ep_table); 141 } 142 /*----------------------------------------------------------------------------*/ 143 int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance, 144 endpoint_t *ep, size_t data_size) 145 { 146 assert(ep); 147 size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type, 148 data_size, ep->max_packet_size); 149 assert(instance); 150 151 unsigned long key[MAX_KEYS] = 152 {ep->address, ep->endpoint, ep->direction}; 157 153 fibril_mutex_lock(&instance->guard); 158 const size_t required = 159 instance->usage_fnc(speed, transfer_type, size, max_packet_size); 160 161 if (required > instance->free) { 154 155 link_t *item = 156 hash_table_find(&instance->ep_table, key); 157 if (item != NULL) { 158 fibril_mutex_unlock(&instance->guard); 159 return EEXISTS; 160 } 161 162 if (bw > instance->free_bw) { 162 163 fibril_mutex_unlock(&instance->guard); 163 164 return ENOSPC; 164 165 } 165 166 166 link_t *item = 167 hash_table_find(&instance->reserved, (unsigned long*)&trans); 168 if (item != NULL) { 169 fibril_mutex_unlock(&instance->guard); 170 return EEXISTS; 171 } 172 173 transfer_status_t *status = malloc(sizeof(transfer_status_t)); 174 if (status == NULL) { 167 node_t *node = malloc(sizeof(node_t)); 168 if (node == NULL) { 175 169 fibril_mutex_unlock(&instance->guard); 176 170 return ENOMEM; 177 171 } 178 172 179 status->transfer = trans; 180 status->required = required; 181 status->used = false; 182 link_initialize(&status->link); 183 184 hash_table_insert(&instance->reserved, 185 (unsigned long*)&status->transfer, &status->link); 186 instance->free -= required; 173 node->bw = bw; 174 node->ep = ep; 175 link_initialize(&node->link); 176 177 hash_table_insert(&instance->ep_table, key, &node->link); 178 instance->free_bw -= bw; 187 179 fibril_mutex_unlock(&instance->guard); 180 fibril_condvar_broadcast(&instance->change); 188 181 return EOK; 189 /* TODO: compute bandwidth used */ 190 } 191 /*----------------------------------------------------------------------------*/ 192 int bandwidth_release(bandwidth_t *instance, usb_address_t address, 193 usb_endpoint_t endpoint, usb_direction_t direction) 194 { 195 assert(instance); 196 transfer_t trans = { 197 .address = address, 198 .endpoint = endpoint, 199 .direction = direction, 200 }; 182 } 183 /*----------------------------------------------------------------------------*/ 184 int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance, 185 usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction) 186 { 187 assert(instance); 188 unsigned long key[MAX_KEYS] = {address, endpoint, direction}; 189 201 190 fibril_mutex_lock(&instance->guard); 202 link_t *item = 203 hash_table_find(&instance->reserved, (unsigned long*)&trans); 191 link_t *item = hash_table_find(&instance->ep_table, key); 204 192 if (item == NULL) { 205 193 fibril_mutex_unlock(&instance->guard); … … 207 195 } 208 196 209 transfer_status_t *status = 210 hash_table_get_instance(item, transfer_status_t, link); 211 212 instance->free += status->required; 213 214 hash_table_remove(&instance->reserved, 215 (unsigned long*)&trans, MAX_KEYS); 197 node_t *node = hash_table_get_instance(item, node_t, link); 198 instance->free_bw += node->bw; 199 hash_table_remove(&instance->ep_table, key, MAX_KEYS); 216 200 217 201 fibril_mutex_unlock(&instance->guard); 202 fibril_condvar_broadcast(&instance->change); 218 203 return EOK; 219 /* TODO: compute bandwidth freed */ 220 } 221 /*----------------------------------------------------------------------------*/ 222 int bandwidth_use(bandwidth_t *instance, usb_address_t address, 223 usb_endpoint_t endpoint, usb_direction_t direction) 224 { 225 assert(instance); 226 transfer_t trans = { 227 .address = address, 228 .endpoint = endpoint, 229 .direction = direction, 230 }; 204 } 205 /*----------------------------------------------------------------------------*/ 206 endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance, 207 usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction, 208 size_t *bw) 209 { 210 assert(instance); 211 unsigned long key[MAX_KEYS] = {address, endpoint, direction}; 212 231 213 fibril_mutex_lock(&instance->guard); 232 link_t *item = 233 hash_table_find(&instance->reserved, (unsigned long*)&trans); 234 int ret = EOK; 235 if (item != NULL) { 236 transfer_status_t *status = 237 hash_table_get_instance(item, transfer_status_t, link); 238 assert(status); 239 if (status->used) { 240 ret = EINPROGRESS; 241 } 242 status->used = true; 243 } else { 244 ret = EINVAL; 245 } 214 link_t *item = hash_table_find(&instance->ep_table, key); 215 if (item == NULL) { 216 fibril_mutex_unlock(&instance->guard); 217 return NULL; 218 } 219 node_t *node = hash_table_get_instance(item, node_t, link); 220 if (bw) 221 *bw = node->bw; 222 246 223 fibril_mutex_unlock(&instance->guard); 247 return ret; 248 } 249 /*----------------------------------------------------------------------------*/ 250 int bandwidth_free(bandwidth_t *instance, usb_address_t address, 251 usb_endpoint_t endpoint, usb_direction_t direction) 252 { 253 assert(instance); 254 transfer_t trans = { 255 .address = address, 256 .endpoint = endpoint, 257 .direction = direction, 258 }; 259 fibril_mutex_lock(&instance->guard); 260 link_t *item = 261 hash_table_find(&instance->reserved, (unsigned long*)&trans); 262 int ret = EOK; 263 if (item != NULL) { 264 transfer_status_t *status = 265 hash_table_get_instance(item, transfer_status_t, link); 266 assert(status); 267 if (!status->used) { 268 ret = ENOENT; 269 } 270 status->used = false; 271 } else { 272 ret = EINVAL; 273 } 274 fibril_mutex_unlock(&instance->guard); 275 return ret; 276 } 224 return node->ep; 225 }
Note:
See TracChangeset
for help on using the changeset viewer.