Changeset 5ca08d4 in mainline
- Timestamp:
- 2011-12-06T13:56:22Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 11cb0565
- Parents:
- 6fa04db
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/root_hub.c
r6fa04db r5ca08d4 109 109 static void rh_init_descriptors(rh_t *instance); 110 110 static uint16_t create_interrupt_mask(const rh_t *instance); 111 static intget_status(const rh_t *instance, usb_transfer_batch_t *request);112 static intget_descriptor(const rh_t *instance, usb_transfer_batch_t *request);113 static intset_feature(const rh_t *instance, usb_transfer_batch_t *request);114 static intclear_feature(const rh_t *instance, usb_transfer_batch_t *request);111 static void get_status(const rh_t *instance, usb_transfer_batch_t *request); 112 static void get_descriptor(const rh_t *instance, usb_transfer_batch_t *request); 113 static void set_feature(const rh_t *instance, usb_transfer_batch_t *request); 114 static void clear_feature(const rh_t *instance, usb_transfer_batch_t *request); 115 115 static int set_feature_port( 116 116 const rh_t *instance, uint16_t feature, uint16_t port); 117 117 static int clear_feature_port( 118 118 const rh_t *instance, uint16_t feature, uint16_t port); 119 static intcontrol_request(rh_t *instance, usb_transfer_batch_t *request);119 static void control_request(rh_t *instance, usb_transfer_batch_t *request); 120 120 static inline void interrupt_request( 121 121 usb_transfer_batch_t *request, uint16_t mask, size_t size) 122 122 { 123 123 assert(request); 124 125 request->transfered_size = size;126 124 usb_transfer_batch_finish_error(request, &mask, size, EOK); 127 } 128 129 #define TRANSFER_OK(bytes) \ 125 usb_transfer_batch_destroy(request); 126 } 127 128 #define TRANSFER_END_DATA(request, data, bytes) \ 130 129 do { \ 131 request->transfered_size = bytes; \ 132 return EOK; \ 130 usb_transfer_batch_finish_error(request, data, bytes, EOK); \ 131 usb_transfer_batch_destroy(request); \ 132 return; \ 133 } while (0) 134 135 #define TRANSFER_END(request, error) \ 136 do { \ 137 usb_transfer_batch_finish_error(request, NULL, 0, error); \ 138 usb_transfer_batch_destroy(request); \ 139 return; \ 133 140 } while (0) 134 141 … … 212 219 case USB_TRANSFER_CONTROL: 213 220 usb_log_debug("Root hub got CONTROL packet\n"); 214 con st int ret = control_request(instance, request);215 usb_transfer_batch_finish_error(request, NULL, 0, ret);216 break; 221 control_request(instance, request); 222 break; 223 217 224 case USB_TRANSFER_INTERRUPT: 218 225 usb_log_debug("Root hub got INTERRUPT packet\n"); … … 221 228 const uint16_t mask = create_interrupt_mask(instance); 222 229 if (mask == 0) { 223 usb_log_debug("No changes.. \n");230 usb_log_debug("No changes...\n"); 224 231 instance->unfinished_interrupt_transfer = request; 225 fibril_mutex_unlock(&instance->guard); 226 return; 232 } else { 233 usb_log_debug("Processing changes...\n"); 234 interrupt_request( 235 request, mask, instance->interrupt_mask_size); 227 236 } 228 usb_log_debug("Processing changes...\n");229 interrupt_request(request, mask, instance->interrupt_mask_size);230 237 fibril_mutex_unlock(&instance->guard); 231 238 break; … … 233 240 default: 234 241 usb_log_error("Root hub got unsupported request.\n"); 235 usb_transfer_batch_finish_error(request, NULL, 0, EINVAL); 236 } 237 usb_transfer_batch_destroy(request); 242 TRANSFER_END(request, ENOTSUP); 243 } 238 244 } 239 245 /*----------------------------------------------------------------------------*/ … … 254 260 interrupt_request(instance->unfinished_interrupt_transfer, 255 261 mask, instance->interrupt_mask_size); 256 usb_transfer_batch_destroy(257 instance->unfinished_interrupt_transfer);258 262 instance->unfinished_interrupt_transfer = NULL; 259 263 } … … 384 388 * @return error code 385 389 */ 386 intget_status(const rh_t *instance, usb_transfer_batch_t *request)390 void get_status(const rh_t *instance, usb_transfer_batch_t *request) 387 391 { 388 392 assert(instance); 389 393 assert(request); 394 395 if (request->buffer_size < 4) { 396 usb_log_error("Buffer too small for get status request.\n"); 397 TRANSFER_END(request, EOVERFLOW); 398 } 390 399 391 400 const usb_device_request_setup_packet_t *request_packet = 392 401 (usb_device_request_setup_packet_t*)request->setup_buffer; 393 394 if (request->buffer_size < 4) {395 usb_log_error("Buffer too small for get status request.\n");396 return EOVERFLOW;397 }398 402 399 403 /* Hub status: just filter relevant info from rh_status reg */ … … 401 405 const uint32_t data = instance->registers->rh_status & 402 406 (RHS_LPS_FLAG | RHS_LPSC_FLAG | RHS_OCI_FLAG | RHS_OCIC_FLAG); 403 memcpy(request->buffer, &data, sizeof(data)); 404 TRANSFER_OK(sizeof(data)); 407 TRANSFER_END_DATA(request, &data, sizeof(data)); 405 408 } 406 409 … … 410 413 const unsigned port = request_packet->index; 411 414 if (port < 1 || port > instance->port_count) 412 return EINVAL;415 TRANSFER_END(request, EINVAL); 413 416 414 417 const uint32_t data = 415 418 instance->registers->rh_port_status[port - 1]; 416 memcpy(request->buffer, &data, sizeof(data)); 417 TRANSFER_OK(sizeof(data)); 418 } 419 420 return ENOTSUP; 419 TRANSFER_END_DATA(request, &data, sizeof(data)); 420 } 421 422 TRANSFER_END(request, ENOTSUP); 421 423 } 422 424 /*----------------------------------------------------------------------------*/ … … 430 432 * @return Error code 431 433 */ 432 intget_descriptor(const rh_t *instance, usb_transfer_batch_t *request)434 void get_descriptor(const rh_t *instance, usb_transfer_batch_t *request) 433 435 { 434 436 assert(instance); … … 440 442 const void *descriptor = NULL; 441 443 const uint16_t setup_request_value = setup_request->value_high; 442 //(setup_request->value_low << 8);443 444 switch (setup_request_value) 444 445 { … … 489 490 setup_request_value, setup_request->index, 490 491 setup_request->length); 491 return EINVAL;492 TRANSFER_END(request, EINVAL); 492 493 } 493 494 if (request->buffer_size < size) { … … 495 496 } 496 497 497 memcpy(request->buffer, descriptor, size); 498 TRANSFER_OK(size); 498 TRANSFER_END_DATA(request, descriptor, size); 499 499 } 500 500 /*----------------------------------------------------------------------------*/ … … 604 604 * @return error code 605 605 */ 606 intset_feature(const rh_t *instance, usb_transfer_batch_t *request)606 void set_feature(const rh_t *instance, usb_transfer_batch_t *request) 607 607 { 608 608 assert(instance); … … 615 615 case USB_HUB_REQ_TYPE_SET_PORT_FEATURE: 616 616 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 617 returnset_feature_port(instance,617 const int ret = set_feature_port(instance, 618 618 setup_request->value, setup_request->index); 619 TRANSFER_END(request, ret); 619 620 620 621 case USB_HUB_REQ_TYPE_SET_HUB_FEATURE: … … 623 624 * features. It makes no sense to SET either. */ 624 625 usb_log_error("Invalid HUB set feature request.\n"); 625 return ENOTSUP;626 TRANSFER_END(request, ENOTSUP); 626 627 default: 627 628 usb_log_error("Invalid set feature request type: %d\n", 628 629 setup_request->request_type); 629 return EINVAL;630 TRANSFER_END(request, EINVAL); 630 631 } 631 632 } … … 640 641 * @return error code 641 642 */ 642 intclear_feature(const rh_t *instance, usb_transfer_batch_t *request)643 void clear_feature(const rh_t *instance, usb_transfer_batch_t *request) 643 644 { 644 645 assert(instance); … … 647 648 const usb_device_request_setup_packet_t *setup_request = 648 649 (usb_device_request_setup_packet_t *) request->setup_buffer; 649 650 request->transfered_size = 0;651 650 652 651 switch (setup_request->request_type) … … 654 653 case USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE: 655 654 usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE\n"); 656 returnclear_feature_port(instance,655 const int ret = clear_feature_port(instance, 657 656 setup_request->value, setup_request->index); 657 TRANSFER_END(request, ret); 658 658 659 659 case USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE: … … 668 668 if (setup_request->value == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) { 669 669 instance->registers->rh_status = RHS_OCIC_FLAG; 670 TRANSFER_ OK(0);670 TRANSFER_END(request, EOK); 671 671 } 672 672 default: 673 673 usb_log_error("Invalid clear feature request type: %d\n", 674 674 setup_request->request_type); 675 return EINVAL;675 TRANSFER_END(request, EINVAL); 676 676 } 677 677 } … … 695 695 * @return error code 696 696 */ 697 intcontrol_request(rh_t *instance, usb_transfer_batch_t *request)697 void control_request(rh_t *instance, usb_transfer_batch_t *request) 698 698 { 699 699 assert(instance); … … 702 702 if (!request->setup_buffer) { 703 703 usb_log_error("Root hub received empty transaction!"); 704 return EINVAL;704 TRANSFER_END(request, EBADMEM); 705 705 } 706 706 707 707 if (sizeof(usb_device_request_setup_packet_t) > request->setup_size) { 708 708 usb_log_error("Setup packet too small\n"); 709 return EOVERFLOW;709 TRANSFER_END(request, EOVERFLOW); 710 710 } 711 711 … … 718 718 case USB_DEVREQ_GET_STATUS: 719 719 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 720 return get_status(instance, request); 720 get_status(instance, request); 721 break; 721 722 722 723 case USB_DEVREQ_GET_DESCRIPTOR: 723 724 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 724 return get_descriptor(instance, request); 725 get_descriptor(instance, request); 726 break; 725 727 726 728 case USB_DEVREQ_GET_CONFIGURATION: 727 729 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 728 if (request->buffer_size != 1)729 return EINVAL;730 request->buffer[0]= 1;731 TRANSFER_ OK(1);730 if (request->buffer_size == 0) 731 TRANSFER_END(request, EOVERFLOW); 732 static const uint8_t config = 1; 733 TRANSFER_END_DATA(request, &config, sizeof(config)); 732 734 733 735 case USB_DEVREQ_CLEAR_FEATURE: 734 usb_log_debug2(" Processing request without "735 "additional data\n");736 return clear_feature(instance, request);736 usb_log_debug2("USB_DEVREQ_CLEAR_FEATURE\n"); 737 clear_feature(instance, request); 738 break; 737 739 738 740 case USB_DEVREQ_SET_FEATURE: 739 usb_log_debug2(" Processing request without "740 "additional data\n");741 return set_feature(instance, request);741 usb_log_debug2("USB_DEVREQ_SET_FEATURE\n"); 742 set_feature(instance, request); 743 break; 742 744 743 745 case USB_DEVREQ_SET_ADDRESS: 744 746 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 745 747 instance->address = setup_request->value; 746 TRANSFER_ OK(0);748 TRANSFER_END(request, EOK); 747 749 748 750 case USB_DEVREQ_SET_CONFIGURATION: 749 751 usb_log_debug("USB_DEVREQ_SET_CONFIGURATION\n"); 750 752 /* We don't need to do anything */ 751 TRANSFER_ OK(0);753 TRANSFER_END(request, EOK); 752 754 753 755 case USB_DEVREQ_SET_DESCRIPTOR: /* Not supported by OHCI RH */ … … 755 757 usb_log_error("Received unsupported request: %d.\n", 756 758 setup_request->request); 757 return ENOTSUP; 758 } 759 } 760 759 TRANSFER_END(request, ENOTSUP); 760 } 761 } 761 762 /** 762 763 * @}
Note:
See TracChangeset
for help on using the changeset viewer.