Changeset 7feeb84 in mainline
- Timestamp:
- 2010-12-13T14:25:49Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 76daaf9f
- Parents:
- 8f8ae1fd
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/virtusbkbd/virtusbkbd.c
r8f8ae1fd r7feeb84 76 76 } 77 77 78 static int on_class_request(struct usbvirt_device *dev,79 usb_device_request_setup_packet_t *request, uint8_t *data)80 {81 printf("%s: class request (%d)\n", NAME, (int) request->request);82 83 return EOK;84 }85 78 86 79 /** Compares current and last status of pressed keys. … … 138 131 } 139 132 133 static usbvirt_control_transfer_handler_t endpoint_zero_handlers[] = { 134 { 135 .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE( 136 USB_DIRECTION_IN, 137 USBVIRT_REQUEST_TYPE_STANDARD, 138 USBVIRT_REQUEST_RECIPIENT_DEVICE), 139 .request = USB_DEVREQ_GET_DESCRIPTOR, 140 .callback = stdreq_on_get_descriptor 141 }, 142 { 143 .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE( 144 USB_DIRECTION_IN, 145 USBVIRT_REQUEST_TYPE_CLASS, 146 USBVIRT_REQUEST_RECIPIENT_DEVICE), 147 .request = USB_DEVREQ_GET_DESCRIPTOR, 148 .callback = stdreq_on_get_descriptor 149 }, 150 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 151 }; 140 152 141 153 /** Keyboard callbacks. … … 143 155 */ 144 156 static usbvirt_device_ops_t keyboard_ops = { 145 .on_standard_request[USB_DEVREQ_GET_DESCRIPTOR] 146 = stdreq_on_get_descriptor, 147 .on_class_device_request = on_class_request, 157 .control_transfer_handlers = endpoint_zero_handlers, 148 158 .on_data = on_incoming_data, 149 159 .on_data_request = on_request_for_data -
uspace/drv/vhc/hubops.c
r8f8ae1fd r7feeb84 61 61 static int on_set_configuration(struct usbvirt_device *dev, 62 62 usb_device_request_setup_packet_t *request, uint8_t *data); 63 static int on_class_request(struct usbvirt_device *dev,64 usb_device_request_setup_packet_t *request, uint8_t *data);65 63 static int on_data_request(struct usbvirt_device *dev, 66 64 usb_endpoint_t endpoint, … … 69 67 static void clear_port_status_change_nl(hub_port_t *, uint16_t); 70 68 static void set_port_state_nl(hub_port_t *, hub_port_state_t); 71 72 /** Hub operations. */ 73 usbvirt_device_ops_t hub_ops = { 74 .on_standard_request[USB_DEVREQ_GET_DESCRIPTOR] = on_get_descriptor, 75 .on_standard_request[USB_DEVREQ_SET_CONFIGURATION] = on_set_configuration, 76 .on_class_device_request = on_class_request, 77 .on_data = NULL, 78 .on_data_request = on_data_request 79 }; 69 static int get_port_status(uint16_t portindex); 80 70 81 71 /** Callback for GET_DESCRIPTOR request. */ … … 300 290 } 301 291 302 staticint get_port_status(uint16_t portindex)292 int get_port_status(uint16_t portindex) 303 293 { 304 294 _GET_PORT(port, portindex); … … 384 374 385 375 386 /** Callback for class request. */387 static int on_class_request(struct usbvirt_device *dev,388 usb_device_request_setup_packet_t *request, uint8_t *data)389 {390 dprintf(2, "hub class request (%d)", (int) request->request);391 392 uint8_t recipient = request->request_type & 31;393 uint8_t direction = request->request_type >> 7;394 395 #define _VERIFY(cond) \396 do { \397 if (!(cond)) { \398 dprintf(0, "WARN: invalid class request (%s not met).\n", \399 NAME, #cond); \400 return EINVAL; \401 } \402 } while (0)403 404 switch (request->request) {405 case USB_HUB_REQUEST_CLEAR_FEATURE:406 _VERIFY(direction == 0);407 _VERIFY(request->length == 0);408 if (recipient == 0) {409 _VERIFY(request->index == 0);410 return clear_hub_feature(request->value);411 } else {412 _VERIFY(recipient == 3);413 return clear_port_feature(request->value,414 request->index);415 }416 417 case USB_HUB_REQUEST_GET_STATE:418 return get_bus_state(request->index);419 420 case USB_HUB_REQUEST_GET_DESCRIPTOR:421 return get_hub_descriptor(dev, request->value_low,422 request->value_high, request->length);423 424 case USB_HUB_REQUEST_GET_STATUS:425 if (recipient == 0) {426 return get_hub_status();427 } else {428 return get_port_status(request->index);429 }430 431 case USB_HUB_REQUEST_SET_FEATURE:432 if (recipient == 0) {433 return set_hub_feature(request->value);434 } else {435 return set_port_feature(request->value, request->index);436 }437 438 default:439 dprintf(0, "WARN: unknown request (%d)!\n",440 request->request);441 break;442 }443 444 #undef _VERIFY445 446 447 return EOK;448 }449 450 376 void clear_port_status_change_nl(hub_port_t *port, uint16_t change) 451 377 { … … 509 435 510 436 437 438 static int req_clear_hub_feature(usbvirt_device_t *dev, 439 usb_device_request_setup_packet_t *request, 440 uint8_t *data) 441 { 442 return clear_hub_feature(request->value); 443 } 444 445 static int req_clear_port_feature(usbvirt_device_t *dev, 446 usb_device_request_setup_packet_t *request, 447 uint8_t *data) 448 { 449 return clear_port_feature(request->value, request->index); 450 } 451 452 static int req_get_bus_state(usbvirt_device_t *dev, 453 usb_device_request_setup_packet_t *request, 454 uint8_t *data) 455 { 456 return get_bus_state(request->index); 457 } 458 459 static int req_get_hub_descriptor(usbvirt_device_t *dev, 460 usb_device_request_setup_packet_t *request, 461 uint8_t *data) 462 { 463 return get_hub_descriptor(dev, request->value_low, 464 request->value_high, request->length); 465 } 466 467 static int req_get_hub_status(usbvirt_device_t *dev, 468 usb_device_request_setup_packet_t *request, 469 uint8_t *data) 470 { 471 return get_hub_status(); 472 } 473 474 static int req_get_port_status(usbvirt_device_t *dev, 475 usb_device_request_setup_packet_t *request, 476 uint8_t *data) 477 { 478 return get_port_status(request->index); 479 } 480 481 static int req_set_hub_feature(usbvirt_device_t *dev, 482 usb_device_request_setup_packet_t *request, 483 uint8_t *data) 484 { 485 return set_hub_feature(request->value); 486 } 487 488 static int req_set_port_feature(usbvirt_device_t *dev, 489 usb_device_request_setup_packet_t *request, 490 uint8_t *data) 491 { 492 return set_port_feature(request->value, request->index); 493 } 494 495 #define CLASS_REQ_IN(recipient) \ 496 USBVIRT_MAKE_CONTROL_REQUEST_TYPE(USB_DIRECTION_IN, \ 497 USBVIRT_REQUEST_TYPE_CLASS, recipient) 498 #define CLASS_REQ_OUT(recipient) \ 499 USBVIRT_MAKE_CONTROL_REQUEST_TYPE(USB_DIRECTION_OUT, \ 500 USBVIRT_REQUEST_TYPE_CLASS, recipient) 501 502 #define REC_OTHER USBVIRT_REQUEST_RECIPIENT_OTHER 503 #define REC_DEVICE USBVIRT_REQUEST_RECIPIENT_DEVICE 504 #define DIR_IN USB_DIRECTION_IN 505 #define DIR_OUT USB_DIRECTION_OUT 506 507 #define CLASS_REQ(direction, recipient, req) \ 508 .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \ 509 USBVIRT_REQUEST_TYPE_CLASS, recipient), \ 510 .request = req 511 512 #define STD_REQ(direction, recipient, req) \ 513 .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \ 514 USBVIRT_REQUEST_TYPE_STANDARD, recipient), \ 515 .request = req 516 517 /** Hub operations on control endpoint zero. */ 518 static usbvirt_control_transfer_handler_t endpoint_zero_handlers[] = { 519 { 520 STD_REQ(DIR_OUT, REC_DEVICE, USB_DEVREQ_SET_CONFIGURATION), 521 .callback = on_set_configuration 522 }, 523 { 524 STD_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR), 525 .callback = on_get_descriptor 526 }, 527 { 528 CLASS_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR), 529 .callback = on_get_descriptor 530 }, 531 { 532 CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATUS), 533 .callback = req_get_port_status 534 }, 535 { 536 CLASS_REQ(DIR_OUT, REC_DEVICE, USB_HUB_REQUEST_CLEAR_FEATURE), 537 .callback = req_clear_hub_feature 538 }, 539 { 540 CLASS_REQ(DIR_OUT, REC_OTHER, USB_HUB_REQUEST_CLEAR_FEATURE), 541 .callback = req_clear_port_feature 542 }, 543 { 544 CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATE), 545 .callback = req_get_bus_state 546 }, 547 { 548 CLASS_REQ(DIR_IN, REC_DEVICE, USB_HUB_REQUEST_GET_DESCRIPTOR), 549 .callback = req_get_hub_descriptor 550 }, 551 { 552 CLASS_REQ(DIR_IN, REC_DEVICE, USB_HUB_REQUEST_GET_STATUS), 553 .callback = req_get_hub_status 554 }, 555 { 556 CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATUS), 557 .callback = req_get_port_status 558 }, 559 { 560 CLASS_REQ(DIR_OUT, REC_DEVICE, USB_HUB_REQUEST_SET_FEATURE), 561 .callback = req_set_hub_feature 562 }, 563 { 564 CLASS_REQ(DIR_OUT, REC_OTHER, USB_HUB_REQUEST_SET_FEATURE), 565 .callback = req_set_port_feature 566 }, 567 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 568 }; 569 570 571 /** Hub operations. */ 572 usbvirt_device_ops_t hub_ops = { 573 .control_transfer_handlers = endpoint_zero_handlers, 574 .on_data = NULL, 575 .on_data_request = on_data_request 576 }; 577 511 578 /** 512 579 * @} -
uspace/lib/usbvirt/include/usbvirt/device.h
r8f8ae1fd r7feeb84 40 40 #include <usb/devreq.h> 41 41 42 typedef enum { 43 USBVIRT_REQUEST_TYPE_STANDARD = 0, 44 USBVIRT_REQUEST_TYPE_CLASS = 1 45 } usbvirt_request_type_t; 46 47 typedef enum { 48 USBVIRT_REQUEST_RECIPIENT_DEVICE = 0, 49 USBVIRT_REQUEST_RECIPIENT_INTERFACE = 1, 50 USBVIRT_REQUEST_RECIPIENT_ENDPOINT = 2, 51 USBVIRT_REQUEST_RECIPIENT_OTHER = 3 52 } usbvirt_request_recipient_t; 53 42 54 typedef struct usbvirt_device usbvirt_device_t; 43 55 struct usbvirt_control_transfer; … … 47 59 uint8_t *data); 48 60 61 typedef int (*usbvirt_control_request_callback_t)(usbvirt_device_t *dev, 62 usb_device_request_setup_packet_t *request, 63 uint8_t *data); 64 65 typedef struct { 66 uint8_t request_type; 67 uint8_t request; 68 usbvirt_control_request_callback_t callback; 69 } usbvirt_control_transfer_handler_t; 70 71 #define USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, type, recipient) \ 72 ((((direction) == USB_DIRECTION_IN) ? 1 : 0) << 7) \ 73 | (((type) & 3) << 5) \ 74 | (((recipient) & 31)) 75 76 #define USBVIRT_CONTROL_TRANSFER_HANDLER_LAST { 0, 0, NULL } 77 49 78 /** Device operations. */ 50 79 typedef struct { 51 /** Callbacks for standard device requests. 52 * The callbacks are indexed by usb_stddevreq_t enum. 53 */ 54 usbvirt_on_device_request_t on_standard_request[USB_DEVREQ_LAST_STD]; 55 /** Callback for class-specific USB request. */ 56 usbvirt_on_device_request_t on_class_device_request; 57 80 /** Callbacks for transfers over control pipe zero. */ 81 usbvirt_control_transfer_handler_t *control_transfer_handlers; 82 58 83 int (*on_control_transfer)(usbvirt_device_t *dev, 59 84 usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer); -
uspace/lib/usbvirt/src/ctrlpipe.c
r8f8ae1fd r7feeb84 37 37 #include "private.h" 38 38 39 #define REQUEST_TYPE_STANDARD 0 40 #define REQUEST_TYPE_CLASS 1 39 /** Compares handler type with request packet type. 40 * 41 * @param handler Handler. 42 * @param request_packet Request packet. 43 * @return Whether handler can serve this packet. 44 */ 45 static bool is_suitable_handler(usbvirt_control_transfer_handler_t *handler, 46 usb_device_request_setup_packet_t *request_packet) 47 { 48 return ( 49 (handler->request_type == request_packet->request_type) 50 && (handler->request == request_packet->request)); 41 51 42 #define GET_MIDBITS_MASK(size, shift) \ 43 (((1 << size) - 1) << shift) 44 #define GET_MIDBITS(value, size, shift) \ 45 ((value & GET_MIDBITS_MASK(size, shift)) >> shift) 52 } 53 54 /** Find suitable transfer handler for given request packet. 55 * 56 * @param handlers Array of available handlers. 57 * @param request_packet Request SETUP packet. 58 * @return Handler or NULL. 59 */ 60 static usbvirt_control_transfer_handler_t *find_handler( 61 usbvirt_control_transfer_handler_t *handlers, 62 usb_device_request_setup_packet_t *request_packet) 63 { 64 if (handlers == NULL) { 65 return NULL; 66 } 67 68 while (handlers->callback != NULL) { 69 if (is_suitable_handler(handlers, request_packet)) { 70 return handlers; 71 } 72 handlers++; 73 } 74 75 return NULL; 76 } 46 77 47 78 48 static const char *str_request_type(int type)49 {50 switch (type) {51 case REQUEST_TYPE_STANDARD:52 return "standard";53 case REQUEST_TYPE_CLASS:54 return "class";55 default:56 return "unknown";57 }58 }59 60 /** Tell request type.61 * By type is meant either standard, class, vendor or other.62 */63 static int request_get_type(uint8_t request_type)64 {65 return GET_MIDBITS(request_type, 2, 5);66 }67 79 68 80 /** Handle communication over control pipe zero. … … 77 89 } 78 90 79 usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) transfer->request; 80 uint8_t *remaining_data = transfer->data; 91 usb_device_request_setup_packet_t *request 92 = (usb_device_request_setup_packet_t *) transfer->request; 93 printf("Request: %d,%d\n", request->request_type, request->request); 81 94 82 int type = request_get_type(request->request_type); 83 84 int rc = EOK; 85 86 device->lib_debug(device, 2, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO, 87 "request type: %s", str_request_type(type)); 88 89 switch (type) { 90 case REQUEST_TYPE_STANDARD: 91 rc = handle_std_request(device, request, remaining_data); 92 break; 93 case REQUEST_TYPE_CLASS: 94 if (DEVICE_HAS_OP(device, on_class_device_request)) { 95 rc = device->ops->on_class_device_request(device, 96 request, remaining_data); 97 } 98 break; 99 default: 100 break; 95 /* 96 * First, see whether user provided its own callback. 97 */ 98 int rc = EFORWARD; 99 if (device->ops) { 100 usbvirt_control_transfer_handler_t *user_handler 101 = find_handler(device->ops->control_transfer_handlers, 102 request); 103 if (user_handler != NULL) { 104 rc = user_handler->callback(device, request, 105 transfer->data); 106 } 107 } 108 109 /* 110 * If there was no user callback or the callback returned EFORWARD, 111 * we need to run a local handler. 112 */ 113 if (rc == EFORWARD) { 114 usbvirt_control_transfer_handler_t *lib_handler 115 = find_handler(control_pipe_zero_local_handlers, 116 request); 117 if (lib_handler != NULL) { 118 rc = lib_handler->callback(device, request, 119 transfer->data); 120 } 101 121 } 102 122 123 /* 124 * Check for SET_ADDRESS finalization. 125 */ 103 126 if (device->new_address != -1) { 104 127 /* -
uspace/lib/usbvirt/src/private.h
r8f8ae1fd r7feeb84 87 87 } 88 88 89 extern usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[]; 90 89 91 #endif 90 92 /** -
uspace/lib/usbvirt/src/stdreq.c
r8f8ae1fd r7feeb84 40 40 #include "private.h" 41 41 42 43 typedef int (*usbvirt_stdreq_handler_t)(usbvirt_device_t *,44 usb_device_request_setup_packet_t *, uint8_t *);45 46 42 /* 47 43 * All sub handlers must return EFORWARD to inform the caller that … … 177 173 } 178 174 179 static usbvirt_stdreq_handler_t local_handlers[USB_DEVREQ_LAST_STD] = { 180 [USB_DEVREQ_GET_DESCRIPTOR] = handle_get_descriptor, 181 [USB_DEVREQ_SET_ADDRESS] = handle_set_address, 182 [USB_DEVREQ_SET_CONFIGURATION] = handle_set_configuration 175 176 #define MAKE_BM_REQUEST(direction, recipient) \ 177 USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \ 178 USBVIRT_REQUEST_TYPE_STANDARD, recipient) 179 #define MAKE_BM_REQUEST_DEV(direction) \ 180 MAKE_BM_REQUEST(direction, USBVIRT_REQUEST_RECIPIENT_DEVICE) 181 182 usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = { 183 { 184 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_IN), 185 .request = USB_DEVREQ_GET_DESCRIPTOR, 186 .callback = handle_get_descriptor 187 }, 188 { 189 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 190 .request = USB_DEVREQ_SET_ADDRESS, 191 .callback = handle_set_address 192 }, 193 { 194 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 195 .request = USB_DEVREQ_SET_CONFIGURATION, 196 .callback = handle_set_configuration 197 }, 198 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 183 199 }; 184 185 /** Handle standard device request. */186 int handle_std_request(usbvirt_device_t *device,187 usb_device_request_setup_packet_t *request_packet, uint8_t *data)188 {189 int request = request_packet->request;190 191 device->lib_debug(device, 3, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO,192 "handling standard request %d", request);193 194 if (request >= USB_DEVREQ_LAST_STD) {195 return ENOTSUP;196 }197 198 int rc = EFORWARD;199 if ((device->ops)200 && (device->ops->on_standard_request[request])) {201 rc = device->ops->on_standard_request[request](device,202 request_packet, data);203 }204 205 if (rc == EFORWARD) {206 if (local_handlers[request]) {207 rc = local_handlers[request](device,208 request_packet, data);209 } else {210 rc = ENOTSUP;211 }212 }213 214 assert(rc != EFORWARD);215 return rc;216 }217 200 218 201 /**
Note:
See TracChangeset
for help on using the changeset viewer.