Changes in uspace/drv/bus/usb/ohci/root_hub.c [9c10e51:549ff23] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/root_hub.c
r9c10e51 r549ff23 35 35 #include <errno.h> 36 36 #include <str_error.h> 37 #include <fibril_synch.h> 37 38 38 39 #include <usb/debug.h> 40 #include <usb/dev/request.h> 41 #include <usb/classes/hub.h> 39 42 40 43 #include "root_hub.h" … … 43 46 #include <usb/dev/driver.h> 44 47 #include "ohci_regs.h" 45 46 #include <usb/dev/request.h>47 #include <usb/classes/hub.h>48 48 49 49 /** … … 108 108 static void create_serialized_hub_descriptor(rh_t *instance); 109 109 static void rh_init_descriptors(rh_t *instance); 110 static uint16_t create_interrupt_mask(rh_t *instance); 111 static int get_status(rh_t *instance, usb_transfer_batch_t *request); 112 static int get_descriptor(rh_t *instance, usb_transfer_batch_t *request); 113 static int set_feature(rh_t *instance, usb_transfer_batch_t *request); 114 static int clear_feature(rh_t *instance, usb_transfer_batch_t *request); 115 static int set_feature_port(rh_t *instance, uint16_t feature, uint16_t port); 116 static int clear_feature_port(rh_t *instance, uint16_t feature, uint16_t port); 110 static uint16_t create_interrupt_mask(const rh_t *instance); 111 static int get_status(const rh_t *instance, usb_transfer_batch_t *request); 112 static int get_descriptor(const rh_t *instance, usb_transfer_batch_t *request); 113 static int set_feature(const rh_t *instance, usb_transfer_batch_t *request); 114 static int clear_feature(const rh_t *instance, usb_transfer_batch_t *request); 115 static int set_feature_port( 116 const rh_t *instance, uint16_t feature, uint16_t port); 117 static int clear_feature_port( 118 const rh_t *instance, uint16_t feature, uint16_t port); 117 119 static int control_request(rh_t *instance, usb_transfer_batch_t *request); 118 120 static inline void interrupt_request( … … 153 155 instance->unfinished_interrupt_transfer = NULL; 154 156 155 #if defOHCI_POWER_SWITCH_no157 #if defined OHCI_POWER_SWITCH_no 156 158 /* Set port power mode to no power-switching. (always on) */ 157 159 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 160 158 161 /* Set to no over-current reporting */ 159 162 instance->registers->rh_desc_a |= RHDA_NOCP_FLAG; 163 160 164 #elif defined OHCI_POWER_SWITCH_ganged 161 165 /* Set port power mode to no ganged power-switching. */ … … 163 167 instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG; 164 168 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 169 165 170 /* Set to global over-current */ 166 171 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG; … … 174 179 instance->registers->rh_desc_b &= (RHDB_PCC_MASK << RHDB_PCC_SHIFT); 175 180 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 181 176 182 /* Return control to per port state */ 177 183 instance->registers->rh_desc_b |= 178 184 ((1 << (instance->port_count + 1)) - 1) << RHDB_PCC_SHIFT; 185 179 186 /* Set per port over-current */ 180 187 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG; … … 182 189 #endif 183 190 191 fibril_mutex_initialize(&instance->guard); 184 192 rh_init_descriptors(instance); 185 193 … … 209 217 case USB_TRANSFER_INTERRUPT: 210 218 usb_log_debug("Root hub got INTERRUPT packet\n"); 219 fibril_mutex_lock(&instance->guard); 220 assert(instance->unfinished_interrupt_transfer == NULL); 211 221 const uint16_t mask = create_interrupt_mask(instance); 212 222 if (mask == 0) { 213 223 usb_log_debug("No changes..\n"); 214 assert(instance->unfinished_interrupt_transfer == NULL);215 224 instance->unfinished_interrupt_transfer = request; 225 fibril_mutex_unlock(&instance->guard); 216 226 return; 217 227 } 218 228 usb_log_debug("Processing changes...\n"); 219 229 interrupt_request(request, mask, instance->interrupt_mask_size); 230 fibril_mutex_unlock(&instance->guard); 220 231 break; 221 232 … … 224 235 usb_transfer_batch_finish_error(request, NULL, 0, EINVAL); 225 236 } 226 usb_transfer_batch_d ispose(request);237 usb_transfer_batch_destroy(request); 227 238 } 228 239 /*----------------------------------------------------------------------------*/ … … 237 248 assert(instance); 238 249 239 if (!instance->unfinished_interrupt_transfer) 240 return; 241 242 usb_log_debug("Finalizing interrupt transfer\n"); 243 const uint16_t mask = create_interrupt_mask(instance); 244 interrupt_request(instance->unfinished_interrupt_transfer, 245 mask, instance->interrupt_mask_size); 246 usb_transfer_batch_dispose(instance->unfinished_interrupt_transfer); 247 248 instance->unfinished_interrupt_transfer = NULL; 250 fibril_mutex_lock(&instance->guard); 251 if (instance->unfinished_interrupt_transfer) { 252 usb_log_debug("Finalizing interrupt transfer\n"); 253 const uint16_t mask = create_interrupt_mask(instance); 254 interrupt_request(instance->unfinished_interrupt_transfer, 255 mask, instance->interrupt_mask_size); 256 usb_transfer_batch_destroy( 257 instance->unfinished_interrupt_transfer); 258 instance->unfinished_interrupt_transfer = NULL; 259 } 260 fibril_mutex_unlock(&instance->guard); 249 261 } 250 262 /*----------------------------------------------------------------------------*/ … … 342 354 * @return Mask of changes. 343 355 */ 344 uint16_t create_interrupt_mask( rh_t *instance)356 uint16_t create_interrupt_mask(const rh_t *instance) 345 357 { 346 358 assert(instance); … … 351 363 mask |= 1; 352 364 } 353 size_t port = 1; 354 for (; port <= instance->port_count; ++port) { 365 for (size_t port = 1; port <= instance->port_count; ++port) { 355 366 /* Write-clean bits are those that indicate change */ 356 367 if (RHPS_CHANGE_WC_MASK … … 373 384 * @return error code 374 385 */ 375 int get_status( rh_t *instance, usb_transfer_batch_t *request)386 int get_status(const rh_t *instance, usb_transfer_batch_t *request) 376 387 { 377 388 assert(instance); … … 419 430 * @return Error code 420 431 */ 421 int get_descriptor( rh_t *instance, usb_transfer_batch_t *request)432 int get_descriptor(const rh_t *instance, usb_transfer_batch_t *request) 422 433 { 423 434 assert(instance); … … 497 508 * @return error code 498 509 */ 499 int set_feature_port( rh_t *instance, uint16_t feature, uint16_t port)510 int set_feature_port(const rh_t *instance, uint16_t feature, uint16_t port) 500 511 { 501 512 assert(instance); … … 536 547 * @return error code 537 548 */ 538 int clear_feature_port( rh_t *instance, uint16_t feature, uint16_t port)549 int clear_feature_port(const rh_t *instance, uint16_t feature, uint16_t port) 539 550 { 540 551 assert(instance); … … 593 604 * @return error code 594 605 */ 595 int set_feature( rh_t *instance, usb_transfer_batch_t *request)606 int set_feature(const rh_t *instance, usb_transfer_batch_t *request) 596 607 { 597 608 assert(instance); … … 629 640 * @return error code 630 641 */ 631 int clear_feature( rh_t *instance, usb_transfer_batch_t *request)642 int clear_feature(const rh_t *instance, usb_transfer_batch_t *request) 632 643 { 633 644 assert(instance); … … 636 647 const usb_device_request_setup_packet_t *setup_request = 637 648 (usb_device_request_setup_packet_t *) request->setup_buffer; 649 638 650 request->transfered_size = 0; 651 639 652 switch (setup_request->request_type) 640 653 { … … 648 661 /* 649 662 * Chapter 11.16.2 specifies that only C_HUB_LOCAL_POWER and 650 * C_HUB_OVER_CURRENT are supported. C_HUB_OVER_CURRENT is represented 651 * by OHCI RHS_OCIC_FLAG. C_HUB_LOCAL_POWER is not supported 663 * C_HUB_OVER_CURRENT are supported. 664 * C_HUB_OVER_CURRENT is represented by OHCI RHS_OCIC_FLAG. 665 * C_HUB_LOCAL_POWER is not supported 652 666 * as root hubs do not support local power status feature. 653 667 * (OHCI pg. 127) */ … … 721 735 "additional data\n"); 722 736 return clear_feature(instance, request); 737 723 738 case USB_DEVREQ_SET_FEATURE: 724 739 usb_log_debug2("Processing request without "
Note:
See TracChangeset
for help on using the changeset viewer.