Changeset 4069f5c in mainline for uspace/drv/bus/usb/ohci/root_hub.c
- Timestamp:
- 2011-07-17T09:52:42Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 64639256, ca1f1ec
- Parents:
- 27eddb52 (diff), 4118f5f (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/root_hub.c
r27eddb52 r4069f5c 40 40 #include "root_hub.h" 41 41 #include <usb/classes/classes.h> 42 #include <usb/classes/hub.h> 42 43 #include <usb/dev/driver.h> 43 44 #include "ohci_regs.h" … … 56 57 .device_subclass = 0, 57 58 .device_version = 0, 58 .length = sizeof 59 .max_packet_size = 8,60 .vendor_id = 0x16db, 59 .length = sizeof(usb_standard_device_descriptor_t), 60 .max_packet_size = 64, 61 .vendor_id = 0x16db, /* HelenOS does not have USB vendor ID assigned.*/ 61 62 .product_id = 0x0001, 62 63 .str_serial_number = 0, … … 73 74 .descriptor_type = USB_DESCTYPE_CONFIGURATION, 74 75 .interface_count = 1, 75 .length = sizeof 76 .max_power = 100,76 .length = sizeof(usb_standard_configuration_descriptor_t), 77 .max_power = 0, /* root hubs don't need no power */ 77 78 .str_configuration = 0, 78 79 }; … … 89 90 .interface_protocol = 0, 90 91 .interface_subclass = 0, 91 .length = sizeof 92 .length = sizeof(usb_standard_interface_descriptor_t), 92 93 .str_interface = 0, 93 94 }; … … 100 101 .descriptor_type = USB_DESCTYPE_ENDPOINT, 101 102 .endpoint_address = 1 + (1 << 7), 102 .length = sizeof 103 .max_packet_size = 8,103 .length = sizeof(usb_standard_endpoint_descriptor_t), 104 .max_packet_size = 2, 104 105 .poll_interval = 255, 105 106 }; 106 107 107 /** 108 * bitmask of hub features that are valid to be cleared 109 */ 110 static const uint32_t hub_clear_feature_valid_mask = 111 RHS_OCIC_FLAG | 112 RHS_CLEAR_PORT_POWER; 113 114 /** 115 * bitmask of hub features that are cleared by writing 1 (and not 0) 116 */ 117 static const uint32_t hub_clear_feature_by_writing_one_mask = 118 RHS_CLEAR_PORT_POWER; 119 120 /** 121 * bitmask of hub features that are valid to be set 122 */ 123 static const uint32_t hub_set_feature_valid_mask = 124 RHS_LPSC_FLAG | 125 RHS_OCIC_FLAG; 126 127 /** 128 * bitmask of hub features that are set by writing 1 and cleared by writing 0 129 */ 130 static const uint32_t hub_set_feature_direct_mask = 131 RHS_SET_PORT_POWER; 132 133 /** 134 * bitmask of port features that are valid to be set 135 */ 136 static const uint32_t port_set_feature_valid_mask = 137 RHPS_SET_PORT_ENABLE | 138 RHPS_SET_PORT_SUSPEND | 139 RHPS_SET_PORT_RESET | 140 RHPS_SET_PORT_POWER; 141 142 /** 143 * bitmask of port features that can be cleared 144 */ 145 static const uint32_t port_clear_feature_valid_mask = 146 RHPS_CCS_FLAG | 147 RHPS_SET_PORT_SUSPEND | 148 RHPS_POCI_FLAG | 149 RHPS_SET_PORT_POWER | 150 RHPS_CSC_FLAG | 151 RHPS_PESC_FLAG | 152 RHPS_PSSC_FLAG | 153 RHPS_OCIC_FLAG | 154 RHPS_PRSC_FLAG; 155 156 //note that USB_HUB_FEATURE_PORT_POWER bit is translated into 157 //USB_HUB_FEATURE_PORT_LOW_SPEED for port set feature request 158 159 /** 160 * bitmask with port status changes 161 */ 162 static const uint32_t port_status_change_mask = RHPS_CHANGE_WC_MASK; 163 164 static int create_serialized_hub_descriptor(rh_t *instance); 165 166 static int rh_init_descriptors(rh_t *instance); 167 168 static int process_get_port_status_request(rh_t *instance, uint16_t port, 169 usb_transfer_batch_t * request); 170 171 static int process_get_hub_status_request(rh_t *instance, 172 usb_transfer_batch_t * request); 173 174 static int process_get_status_request(rh_t *instance, 175 usb_transfer_batch_t * request); 176 177 static void create_interrupt_mask_in_instance(rh_t *instance); 178 179 static int process_get_descriptor_request(rh_t *instance, 180 usb_transfer_batch_t *request); 181 182 static int process_get_configuration_request(rh_t *instance, 183 usb_transfer_batch_t *request); 184 185 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 186 187 static int process_hub_feature_clear_request(rh_t *instance, 188 uint16_t feature); 189 190 static int process_port_feature_set_request(rh_t *instance, 191 uint16_t feature, uint16_t port); 192 193 static int process_port_feature_clear_request(rh_t *instance, 194 uint16_t feature, uint16_t port); 195 196 static int process_address_set_request(rh_t *instance, 197 uint16_t address); 198 199 static int process_request_with_output(rh_t *instance, 200 usb_transfer_batch_t *request); 201 202 static int process_request_with_input(rh_t *instance, 203 usb_transfer_batch_t *request); 204 205 static int process_request_without_data(rh_t *instance, 206 usb_transfer_batch_t *request); 207 208 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); 209 210 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request); 211 212 static bool is_zeros(void * buffer, size_t size); 213 214 /** Root hub initialization 215 * @return Error code. 216 */ 217 int rh_init(rh_t *instance, ohci_regs_t *regs) { 218 assert(instance); 108 static void create_serialized_hub_descriptor(rh_t *instance); 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); 117 static int control_request(rh_t *instance, usb_transfer_batch_t *request); 118 static inline void interrupt_request( 119 usb_transfer_batch_t *request, uint16_t mask, size_t size) 120 { 121 assert(request); 122 123 memcpy(request->data_buffer, &mask, size); 124 request->transfered_size = size; 125 usb_transfer_batch_finish_error(request, EOK); 126 } 127 128 #define TRANSFER_OK(bytes) \ 129 do { \ 130 request->transfered_size = bytes; \ 131 return EOK; \ 132 } while (0) 133 134 /** Root Hub driver structure initialization. 135 * 136 * Reads info registers and prepares descriptors. Sets power mode. 137 */ 138 void rh_init(rh_t *instance, ohci_regs_t *regs) 139 { 140 assert(instance); 141 assert(regs); 142 219 143 instance->registers = regs; 220 144 instance->port_count = 221 145 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 222 int opResult = rh_init_descriptors(instance); 223 if (opResult != EOK) { 224 return opResult; 225 } 226 // set port power mode to no-power-switching 146 if (instance->port_count > 15) { 147 usb_log_warning("OHCI specification does not allow more than 15" 148 " ports. Max 15 ports will be used"); 149 instance->port_count = 15; 150 } 151 152 /* Don't forget the hub status bit and round up */ 153 instance->interrupt_mask_size = 1 + (instance->port_count / 8); 154 instance->unfinished_interrupt_transfer = NULL; 155 156 #ifdef OHCI_POWER_SWITCH_no 157 /* Set port power mode to no power-switching. (always on) */ 227 158 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 228 instance->unfinished_interrupt_transfer = NULL; 229 instance->interrupt_mask_size = (instance->port_count + 8) / 8; 230 instance->interrupt_buffer = malloc(instance->interrupt_mask_size); 231 if (!instance->interrupt_buffer) 232 return ENOMEM; 159 /* Set to no over-current reporting */ 160 instance->registers->rh_desc_a |= RHDA_NOCP_FLAG; 161 #elif defined OHCI_POWER_SWITCH_ganged 162 /* Set port power mode to no ganged power-switching. */ 163 instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG; 164 instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG; 165 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 166 /* Set to global over-current */ 167 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG; 168 instance->registers->rh_desc_a &= ~RHDA_OCPM_FLAG; 169 #else 170 /* Set port power mode to no per port power-switching. */ 171 instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG; 172 instance->registers->rh_desc_a |= RHDA_PSM_FLAG; 173 174 /* Control all ports by global switch and turn them off */ 175 instance->registers->rh_desc_b &= (RHDB_PCC_MASK << RHDB_PCC_SHIFT); 176 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 177 /* Return control to per port state */ 178 instance->registers->rh_desc_b |= 179 ((1 << (instance->port_count + 1)) - 1) << RHDB_PCC_SHIFT; 180 /* Set per port over-current */ 181 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG; 182 instance->registers->rh_desc_a |= RHDA_OCPM_FLAG; 183 #endif 184 185 rh_init_descriptors(instance); 233 186 234 187 usb_log_info("Root hub (%zu ports) initialized.\n", 235 188 instance->port_count); 236 237 return EOK; 238 } 239 /*----------------------------------------------------------------------------*/ 240 241 /** 242 * process root hub request 243 * 244 * @param instance root hub instance 245 * @param request structure containing both request and response information 246 * @return error code 247 */ 248 int rh_request(rh_t *instance, usb_transfer_batch_t *request) { 189 } 190 /*----------------------------------------------------------------------------*/ 191 /** 192 * Process root hub request. 193 * 194 * @param instance Root hub instance 195 * @param request Structure containing both request and response information 196 * @return Error code 197 */ 198 void rh_request(rh_t *instance, usb_transfer_batch_t *request) 199 { 249 200 assert(instance); 250 201 assert(request); 251 int opResult; 252 if (request->ep->transfer_type == USB_TRANSFER_CONTROL) { 202 203 switch (request->ep->transfer_type) 204 { 205 case USB_TRANSFER_CONTROL: 253 206 usb_log_debug("Root hub got CONTROL packet\n"); 254 opResult = process_ctrl_request(instance, request); 255 usb_transfer_batch_finish_error(request, opResult); 256 } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) { 207 const int ret = control_request(instance, request); 208 usb_transfer_batch_finish_error(request, ret); 209 break; 210 case USB_TRANSFER_INTERRUPT: 257 211 usb_log_debug("Root hub got INTERRUPT packet\n"); 258 create_interrupt_mask_in_instance(instance); 259 if (is_zeros(instance->interrupt_buffer, 260 instance->interrupt_mask_size)) { 212 const uint16_t mask = create_interrupt_mask(instance); 213 if (mask == 0) { 261 214 usb_log_debug("No changes..\n"); 215 assert(instance->unfinished_interrupt_transfer == NULL); 262 216 instance->unfinished_interrupt_transfer = request; 263 //will be finished later 264 } else { 265 usb_log_debug("Processing changes..\n"); 266 process_interrupt_mask_in_instance(instance, request); 217 break; 267 218 } 268 opResult = EOK; 269 } else { 270 271 opResult = EINVAL; 272 usb_transfer_batch_finish_error(request, opResult); 273 } 274 return EOK; 275 } 276 277 /*----------------------------------------------------------------------------*/ 278 279 /** 280 * process interrupt on a hub 219 usb_log_debug("Processing changes...\n"); 220 interrupt_request(request, mask, instance->interrupt_mask_size); 221 break; 222 223 default: 224 usb_log_error("Root hub got unsupported request.\n"); 225 usb_transfer_batch_finish_error(request, EINVAL); 226 } 227 } 228 /*----------------------------------------------------------------------------*/ 229 /** 230 * Process interrupt on a hub device. 281 231 * 282 232 * If there is no pending interrupt transfer, nothing happens. 283 233 * @param instance 284 234 */ 285 void rh_interrupt(rh_t *instance) { 286 if (!instance->unfinished_interrupt_transfer) { 235 void rh_interrupt(rh_t *instance) 236 { 237 assert(instance); 238 239 if (!instance->unfinished_interrupt_transfer) 287 240 return; 288 } 241 289 242 usb_log_debug("Finalizing interrupt transfer\n"); 290 create_interrupt_mask_in_instance(instance); 291 process_interrupt_mask_in_instance(instance, 292 instance->unfinished_interrupt_transfer); 293 } 294 /*----------------------------------------------------------------------------*/ 295 296 /** 297 * Create hub descriptor used in hub-driver <-> hub communication 298 * 299 * This means creating byt array from data in root hub registers. For more 300 * info see usb hub specification. 301 * 243 const uint16_t mask = create_interrupt_mask(instance); 244 interrupt_request(instance->unfinished_interrupt_transfer, 245 mask, instance->interrupt_mask_size); 246 247 instance->unfinished_interrupt_transfer = NULL; 248 } 249 /*----------------------------------------------------------------------------*/ 250 /** 251 * Create hub descriptor. 252 * 253 * For descriptor format see USB hub specification (chapter 11.15.2.1, pg. 263) 254 * 255 * @param instance Root hub instance 256 * @return Error code 257 */ 258 void create_serialized_hub_descriptor(rh_t *instance) 259 { 260 assert(instance); 261 262 /* 7 bytes + 2 port bit fields (port count + global bit) */ 263 const size_t size = 7 + (instance->interrupt_mask_size * 2); 264 assert(size <= HUB_DESCRIPTOR_MAX_SIZE); 265 instance->hub_descriptor_size = size; 266 267 const uint32_t hub_desc = instance->registers->rh_desc_a; 268 const uint32_t port_desc = instance->registers->rh_desc_b; 269 270 /* bDescLength */ 271 instance->descriptors.hub[0] = size; 272 /* bDescriptorType */ 273 instance->descriptors.hub[1] = USB_DESCTYPE_HUB; 274 /* bNmbrPorts */ 275 instance->descriptors.hub[2] = instance->port_count; 276 /* wHubCharacteristics */ 277 instance->descriptors.hub[3] = 0 | 278 /* The lowest 2 bits indicate power switching mode */ 279 (((hub_desc & RHDA_PSM_FLAG) ? 1 : 0) << 0) | 280 (((hub_desc & RHDA_NPS_FLAG) ? 1 : 0) << 1) | 281 /* Bit 3 indicates device type (compound device) */ 282 (((hub_desc & RHDA_DT_FLAG) ? 1 : 0) << 2) | 283 /* Bits 4,5 indicate over-current protection mode */ 284 (((hub_desc & RHDA_OCPM_FLAG) ? 1 : 0) << 3) | 285 (((hub_desc & RHDA_NOCP_FLAG) ? 1 : 0) << 4); 286 287 /* Reserved */ 288 instance->descriptors.hub[4] = 0; 289 /* bPwrOn2PwrGood */ 290 instance->descriptors.hub[5] = 291 (hub_desc >> RHDA_POTPGT_SHIFT) & RHDA_POTPGT_MASK; 292 /* bHubContrCurrent, root hubs don't need no power. */ 293 instance->descriptors.hub[6] = 0; 294 295 /* Device Removable and some legacy 1.0 stuff*/ 296 instance->descriptors.hub[7] = 297 (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK & 0xff; 298 instance->descriptors.hub[8] = 0xff; 299 if (instance->interrupt_mask_size == 2) { 300 instance->descriptors.hub[8] = 301 (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK >> 8; 302 instance->descriptors.hub[9] = 0xff; 303 instance->descriptors.hub[10] = 0xff; 304 } 305 } 306 /*----------------------------------------------------------------------------*/ 307 /** Initialize hub descriptors. 308 * 309 * A full configuration descriptor is assembled. The configuration and endpoint 310 * descriptors have local modifications. 311 * @param instance Root hub instance 312 * @return Error code 313 */ 314 void rh_init_descriptors(rh_t *instance) 315 { 316 assert(instance); 317 318 instance->descriptors.configuration = ohci_rh_conf_descriptor; 319 instance->descriptors.interface = ohci_rh_iface_descriptor; 320 instance->descriptors.endpoint = ohci_rh_ep_descriptor; 321 create_serialized_hub_descriptor(instance); 322 323 instance->descriptors.endpoint.max_packet_size = 324 instance->interrupt_mask_size; 325 326 instance->descriptors.configuration.total_length = 327 sizeof(usb_standard_configuration_descriptor_t) + 328 sizeof(usb_standard_endpoint_descriptor_t) + 329 sizeof(usb_standard_interface_descriptor_t) + 330 instance->hub_descriptor_size; 331 } 332 /*----------------------------------------------------------------------------*/ 333 /** 334 * Create bitmap of changes to answer status interrupt. 335 * 336 * Result contains bitmap where bit 0 indicates change on hub and 337 * bit i indicates change on i`th port (i>0). For more info see 338 * Hub and Port status bitmap specification in USB specification 339 * (chapter 11.13.4). 302 340 * @param instance root hub instance 303 * @return error code 304 */ 305 static int create_serialized_hub_descriptor(rh_t *instance) { 306 size_t size = 7 + 307 ((instance->port_count + 7) / 8) * 2; 308 size_t var_size = (instance->port_count + 7) / 8; 309 uint8_t * result = (uint8_t*) malloc(size); 310 if (!result) return ENOMEM; 311 312 bzero(result, size); 313 //size 314 result[0] = size; 315 //descriptor type 316 result[1] = USB_DESCTYPE_HUB; 317 result[2] = instance->port_count; 318 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 319 result[3] = 320 ((hub_desc_reg >> 8) % 2) + 321 (((hub_desc_reg >> 9) % 2) << 1) + 322 (((hub_desc_reg >> 10) % 2) << 2) + 323 (((hub_desc_reg >> 11) % 2) << 3) + 324 (((hub_desc_reg >> 12) % 2) << 4); 325 result[4] = 0; 326 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 327 result[6] = 50; 328 329 size_t port; 330 for (port = 1; port <= instance->port_count; ++port) { 331 uint8_t is_non_removable = 332 instance->registers->rh_desc_b >> port % 2; 333 result[7 + port / 8] += 334 is_non_removable << (port % 8); 335 } 336 size_t i; 337 for (i = 0; i < var_size; ++i) { 338 result[7 + var_size + i] = 255; 339 } 340 instance->hub_descriptor = result; 341 instance->descriptor_size = size; 342 343 return EOK; 344 } 345 /*----------------------------------------------------------------------------*/ 346 347 /** initialize hub descriptors 348 * 349 * Initialized are device and full configuration descriptor. These need to 350 * be initialized only once per hub. 351 * @instance root hub instance 352 * @return error code 353 */ 354 static int rh_init_descriptors(rh_t *instance) { 355 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 356 sizeof (ohci_rh_device_descriptor) 357 ); 358 usb_standard_configuration_descriptor_t descriptor; 359 memcpy(&descriptor, &ohci_rh_conf_descriptor, 360 sizeof (ohci_rh_conf_descriptor)); 361 362 int opResult = create_serialized_hub_descriptor(instance); 363 if (opResult != EOK) { 364 return opResult; 365 } 366 descriptor.total_length = 367 sizeof (usb_standard_configuration_descriptor_t) + 368 sizeof (usb_standard_endpoint_descriptor_t) + 369 sizeof (usb_standard_interface_descriptor_t) + 370 instance->descriptor_size; 371 372 uint8_t * full_config_descriptor = 373 (uint8_t*) malloc(descriptor.total_length); 374 if (!full_config_descriptor) { 375 return ENOMEM; 376 } 377 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor)); 378 memcpy(full_config_descriptor + sizeof (descriptor), 379 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor)); 380 memcpy(full_config_descriptor + sizeof (descriptor) + 381 sizeof (ohci_rh_iface_descriptor), 382 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor)); 383 memcpy(full_config_descriptor + sizeof (descriptor) + 384 sizeof (ohci_rh_iface_descriptor) + 385 sizeof (ohci_rh_ep_descriptor), 386 instance->hub_descriptor, instance->descriptor_size); 387 388 instance->descriptors.configuration = full_config_descriptor; 389 instance->descriptors.configuration_size = descriptor.total_length; 390 391 return EOK; 392 } 393 /*----------------------------------------------------------------------------*/ 394 395 /** 396 * create answer to port status_request 397 * 398 * Copy content of corresponding port status register to answer buffer. The 399 * format of the port status register and port status data is the same ( 400 * see OHCI root hub and USB hub documentation). 401 * 402 * @param instance root hub instance 403 * @param port port number, counted from 1 404 * @param request structure containing both request and response information 405 * @return error code 406 */ 407 static int process_get_port_status_request(rh_t *instance, uint16_t port, 408 usb_transfer_batch_t * request) { 409 if (port < 1 || port > instance->port_count) 410 return EINVAL; 411 request->transfered_size = 4; 412 uint32_t data = instance->registers->rh_port_status[port - 1]; 413 memcpy(request->data_buffer, &data, 4); 414 return EOK; 415 } 416 /*----------------------------------------------------------------------------*/ 417 418 /** 419 * create answer to port status_request 420 * 421 * This copies flags in hub status register into the buffer. The format of the 422 * status register and status message is the same, according to USB hub 423 * specification and OHCI root hub specification. 424 * 425 * @param instance root hub instance 426 * @param request structure containing both request and response information 427 * @return error code 428 */ 429 static int process_get_hub_status_request(rh_t *instance, 430 usb_transfer_batch_t * request) { 431 request->transfered_size = 4; 432 //bits, 0,1,16,17 433 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 434 uint32_t data = mask & instance->registers->rh_status; 435 memcpy(request->data_buffer, &data, 4); 436 437 return EOK; 438 } 439 /*----------------------------------------------------------------------------*/ 440 441 /** 442 * create answer to status request 341 * @return Mask of changes. 342 */ 343 uint16_t create_interrupt_mask(rh_t *instance) 344 { 345 assert(instance); 346 uint16_t mask = 0; 347 348 /* Only local power source change and over-current change can happen */ 349 if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) { 350 mask |= 1; 351 } 352 size_t port = 1; 353 for (; port <= instance->port_count; ++port) { 354 /* Write-clean bits are those that indicate change */ 355 if (RHPS_CHANGE_WC_MASK 356 & instance->registers->rh_port_status[port - 1]) { 357 358 mask |= (1 << port); 359 } 360 } 361 /* USB is little endian */ 362 return host2uint32_t_le(mask); 363 } 364 /*----------------------------------------------------------------------------*/ 365 /** 366 * Create answer to status request. 443 367 * 444 368 * This might be either hub status or port status request. If neither, … … 448 372 * @return error code 449 373 */ 450 static int process_get_status_request(rh_t *instance, 451 usb_transfer_batch_t * request) { 452 size_t buffer_size = request->buffer_size; 453 usb_device_request_setup_packet_t * request_packet = 454 (usb_device_request_setup_packet_t*) 455 request->setup_buffer; 456 457 usb_hub_bm_request_type_t request_type = request_packet->request_type; 458 if (buffer_size < 4) { 459 usb_log_warning("Requested more data than buffer size\n"); 460 return EINVAL; 461 } 462 463 if (request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) 464 return process_get_hub_status_request(instance, request); 465 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 466 return process_get_port_status_request(instance, 467 request_packet->index, 468 request); 374 int get_status(rh_t *instance, usb_transfer_batch_t *request) 375 { 376 assert(instance); 377 assert(request); 378 379 const usb_device_request_setup_packet_t *request_packet = 380 (usb_device_request_setup_packet_t*)request->setup_buffer; 381 382 if (request->buffer_size < 4) { 383 usb_log_error("Buffer too small for get status request.\n"); 384 return EOVERFLOW; 385 } 386 387 /* Hub status: just filter relevant info from rh_status reg */ 388 if (request_packet->request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) { 389 const uint32_t data = instance->registers->rh_status & 390 (RHS_LPS_FLAG | RHS_LPSC_FLAG | RHS_OCI_FLAG | RHS_OCIC_FLAG); 391 memcpy(request->data_buffer, &data, 4); 392 TRANSFER_OK(4); 393 } 394 395 /* Copy appropriate rh_port_status register, OHCI designers were 396 * kind enough to make those bit values match USB specification */ 397 if (request_packet->request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) { 398 const unsigned port = request_packet->index; 399 if (port < 1 || port > instance->port_count) 400 return EINVAL; 401 402 const uint32_t data = 403 instance->registers->rh_port_status[port - 1]; 404 memcpy(request->data_buffer, &data, 4); 405 TRANSFER_OK(4); 406 } 469 407 470 408 return ENOTSUP; 471 409 } 472 410 /*----------------------------------------------------------------------------*/ 473 474 /** 475 * create answer to status interrupt consisting of change bitmap 476 * 477 * Result contains bitmap where bit 0 indicates change on hub and 478 * bit i indicates change on i`th port (i>0). For more info see 479 * Hub and Port status bitmap specification in USB specification 480 * (chapter 11.13.4). 481 * Uses instance`s interrupt buffer to store the interrupt information. 482 * @param instance root hub instance 483 */ 484 static void create_interrupt_mask_in_instance(rh_t * instance) { 485 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer); 486 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 487 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 488 bzero(bitmap, instance->interrupt_mask_size); 489 if ((instance->registers->rh_status & mask) != 0) { 490 bitmap[0] = 1; 491 } 492 size_t port; 493 mask = port_status_change_mask; 494 for (port = 1; port <= instance->port_count; ++port) { 495 if ((mask & instance->registers->rh_port_status[port - 1]) != 0) { 496 497 bitmap[(port) / 8] += 1 << (port % 8); 498 } 499 } 500 } 501 /*----------------------------------------------------------------------------*/ 502 503 /** 504 * create answer to a descriptor request 411 /** 412 * Create answer to a descriptor request. 505 413 * 506 414 * This might be a request for standard (configuration, device, endpoint or 507 415 * interface) or device specific (hub) descriptor. 508 * @param instance root hub instance 509 * @param request structure containing both request and response information 510 * @return error code 511 */ 512 static int process_get_descriptor_request(rh_t *instance, 513 usb_transfer_batch_t *request) { 514 usb_device_request_setup_packet_t * setup_request = 515 (usb_device_request_setup_packet_t*) request->setup_buffer; 416 * @param instance Root hub instance 417 * @param request Structure containing both request and response information 418 * @return Error code 419 */ 420 int get_descriptor(rh_t *instance, usb_transfer_batch_t *request) 421 { 422 assert(instance); 423 assert(request); 424 425 const usb_device_request_setup_packet_t *setup_request = 426 (usb_device_request_setup_packet_t *) request->setup_buffer; 516 427 size_t size; 517 const void * result_descriptor = NULL;428 const void *descriptor = NULL; 518 429 const uint16_t setup_request_value = setup_request->value_high; 519 430 //(setup_request->value_low << 8); 520 switch (setup_request_value) { 521 case USB_DESCTYPE_HUB: 522 { 523 usb_log_debug2("USB_DESCTYPE_HUB\n"); 524 result_descriptor = instance->hub_descriptor; 525 size = instance->descriptor_size; 526 break; 527 } 528 case USB_DESCTYPE_DEVICE: 529 { 530 usb_log_debug2("USB_DESCTYPE_DEVICE\n"); 531 result_descriptor = &ohci_rh_device_descriptor; 532 size = sizeof (ohci_rh_device_descriptor); 533 break; 534 } 535 case USB_DESCTYPE_CONFIGURATION: 536 { 537 usb_log_debug2("USB_DESCTYPE_CONFIGURATION\n"); 538 result_descriptor = instance->descriptors.configuration; 539 size = instance->descriptors.configuration_size; 540 break; 541 } 542 case USB_DESCTYPE_INTERFACE: 543 { 544 usb_log_debug2("USB_DESCTYPE_INTERFACE\n"); 545 result_descriptor = &ohci_rh_iface_descriptor; 546 size = sizeof (ohci_rh_iface_descriptor); 547 break; 548 } 549 case USB_DESCTYPE_ENDPOINT: 550 { 551 usb_log_debug2("USB_DESCTYPE_ENDPOINT\n"); 552 result_descriptor = &ohci_rh_ep_descriptor; 553 size = sizeof (ohci_rh_ep_descriptor); 554 break; 555 } 556 default: 557 { 558 usb_log_debug2("USB_DESCTYPE_EINVAL %d \n", 559 setup_request->value); 560 usb_log_debug2("\ttype %d\n\trequest %d\n\tvalue " 561 "%d\n\tindex %d\n\tlen %d\n ", 562 setup_request->request_type, 563 setup_request->request, 564 setup_request_value, 565 setup_request->index, 566 setup_request->length 567 ); 568 return EINVAL; 569 } 431 switch (setup_request_value) 432 { 433 case USB_DESCTYPE_HUB: 434 usb_log_debug2("USB_DESCTYPE_HUB\n"); 435 /* Hub descriptor was generated locally */ 436 descriptor = instance->descriptors.hub; 437 size = instance->hub_descriptor_size; 438 break; 439 440 case USB_DESCTYPE_DEVICE: 441 usb_log_debug2("USB_DESCTYPE_DEVICE\n"); 442 /* Device descriptor is shared (No one should ask for it)*/ 443 descriptor = &ohci_rh_device_descriptor; 444 size = sizeof(ohci_rh_device_descriptor); 445 break; 446 447 case USB_DESCTYPE_CONFIGURATION: 448 usb_log_debug2("USB_DESCTYPE_CONFIGURATION\n"); 449 /* Start with configuration and add others depending on 450 * request size */ 451 descriptor = &instance->descriptors; 452 size = instance->descriptors.configuration.total_length; 453 break; 454 455 case USB_DESCTYPE_INTERFACE: 456 usb_log_debug2("USB_DESCTYPE_INTERFACE\n"); 457 /* Use local interface descriptor. There is one and it 458 * might be modified */ 459 descriptor = &instance->descriptors.interface; 460 size = sizeof(instance->descriptors.interface); 461 break; 462 463 case USB_DESCTYPE_ENDPOINT: 464 /* Use local endpoint descriptor. There is one 465 * it might have max_packet_size field modified*/ 466 usb_log_debug2("USB_DESCTYPE_ENDPOINT\n"); 467 descriptor = &instance->descriptors.endpoint; 468 size = sizeof(instance->descriptors.endpoint); 469 break; 470 471 default: 472 usb_log_debug2("USB_DESCTYPE_EINVAL %d \n" 473 "\ttype %d\n\trequest %d\n\tvalue " 474 "%d\n\tindex %d\n\tlen %d\n ", 475 setup_request->value, 476 setup_request->request_type, setup_request->request, 477 setup_request_value, setup_request->index, 478 setup_request->length); 479 return EINVAL; 570 480 } 571 481 if (request->buffer_size < size) { 572 482 size = request->buffer_size; 573 483 } 574 request->transfered_size = size; 575 memcpy(request->data_buffer, result_descriptor, size); 576 577 return EOK; 578 } 579 /*----------------------------------------------------------------------------*/ 580 581 /** 582 * answer to get configuration request 583 * 584 * Root hub works independently on the configuration. 585 * @param instance root hub instance 586 * @param request structure containing both request and response information 587 * @return error code 588 */ 589 static int process_get_configuration_request(rh_t *instance, 590 usb_transfer_batch_t *request) { 591 //set and get configuration requests do not have any meaning, only dummy 592 //values are returned 593 if (request->buffer_size != 1) 594 return EINVAL; 595 request->data_buffer[0] = 1; 596 request->transfered_size = 1; 597 598 return EOK; 599 } 600 /*----------------------------------------------------------------------------*/ 601 602 /** 603 * process feature-enabling request on hub 604 * 605 * @param instance root hub instance 606 * @param feature feature selector 607 * @return error code 608 */ 609 static int process_hub_feature_set_request(rh_t *instance, 610 uint16_t feature) { 611 if (!((1 << feature) & hub_set_feature_valid_mask)) 612 return EINVAL; 613 if (feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER) 614 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16; 615 instance->registers->rh_status = 616 (instance->registers->rh_status | (1 << feature)) 617 & (~hub_clear_feature_by_writing_one_mask); 618 619 return EOK; 620 } 621 /*----------------------------------------------------------------------------*/ 622 623 /** 624 * process feature-disabling request on hub 625 * 626 * @param instance root hub instance 627 * @param feature feature selector 628 * @return error code 629 */ 630 static int process_hub_feature_clear_request(rh_t *instance, 631 uint16_t feature) { 632 if (!((1 << feature) & hub_clear_feature_valid_mask)) 633 return EINVAL; 634 //is the feature cleared directly? 635 if ((1 << feature) & hub_set_feature_direct_mask) { 636 instance->registers->rh_status = 637 (instance->registers->rh_status & (~(1 << feature))) 638 & (~hub_clear_feature_by_writing_one_mask); 639 } else {//the feature is cleared by writing '1' 640 641 instance->registers->rh_status = 642 (instance->registers->rh_status 643 & (~hub_clear_feature_by_writing_one_mask)) 644 | (1 << feature); 645 } 646 return EOK; 647 } 648 /*----------------------------------------------------------------------------*/ 649 484 485 memcpy(request->data_buffer, descriptor, size); 486 TRANSFER_OK(size); 487 } 488 /*----------------------------------------------------------------------------*/ 650 489 /** 651 490 * process feature-enabling request on hub … … 657 496 * @return error code 658 497 */ 659 static int process_port_feature_set_request(rh_t *instance, 660 uint16_t feature, uint16_t port){661 if (!((1 << feature) & port_set_feature_valid_mask))662 return EINVAL; 498 int set_feature_port(rh_t *instance, uint16_t feature, uint16_t port) 499 { 500 assert(instance); 501 663 502 if (port < 1 || port > instance->port_count) 664 503 return EINVAL; 665 instance->registers->rh_port_status[port - 1] = 666 (instance->registers->rh_port_status[port - 1] | (1 << feature)) 667 & (~port_clear_feature_valid_mask); 668 return EOK; 669 } 670 /*----------------------------------------------------------------------------*/ 671 672 /** 673 * process feature-disabling request on hub 504 505 switch (feature) 506 { 507 case USB_HUB_FEATURE_PORT_POWER: //8 508 /* No power switching */ 509 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG) 510 return EOK; 511 /* Ganged power switching */ 512 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) { 513 instance->registers->rh_status = RHS_SET_GLOBAL_POWER; 514 return EOK; 515 } 516 case USB_HUB_FEATURE_PORT_ENABLE: //1 517 case USB_HUB_FEATURE_PORT_SUSPEND: //2 518 case USB_HUB_FEATURE_PORT_RESET: //4 519 /* Nice thing is that these shifts correspond to the position 520 * of control bits in register */ 521 instance->registers->rh_port_status[port - 1] = (1 << feature); 522 return EOK; 523 default: 524 return ENOTSUP; 525 } 526 } 527 /*----------------------------------------------------------------------------*/ 528 /** 529 * Process feature clear request. 674 530 * 675 531 * @param instance root hub instance … … 679 535 * @return error code 680 536 */ 681 static int process_port_feature_clear_request(rh_t *instance, 682 uint16_t feature, uint16_t port){683 if (!((1 << feature) & port_clear_feature_valid_mask))684 return EINVAL; 537 int clear_feature_port(rh_t *instance, uint16_t feature, uint16_t port) 538 { 539 assert(instance); 540 685 541 if (port < 1 || port > instance->port_count) 686 542 return EINVAL; 687 if (feature == USB_HUB_FEATURE_PORT_POWER) 688 feature = USB_HUB_FEATURE_PORT_LOW_SPEED; 689 if (feature == USB_HUB_FEATURE_PORT_SUSPEND) 690 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 691 instance->registers->rh_port_status[port - 1] = 692 (instance->registers->rh_port_status[port - 1] 693 & (~port_clear_feature_valid_mask)) 694 | (1 << feature); 695 696 return EOK; 697 } 698 /*----------------------------------------------------------------------------*/ 699 700 /** 701 * register address to this device 702 * 703 * @param instance root hub instance 704 * @param address new address 705 * @return error code 706 */ 707 static int process_address_set_request(rh_t *instance, 708 uint16_t address) { 709 return ENOTSUP; 710 } 711 /*----------------------------------------------------------------------------*/ 712 713 /** 714 * process one of requests that requere output data 715 * 716 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or 717 * USB_DEVREQ_GET_CONFIGURATION. 718 * @param instance root hub instance 719 * @param request structure containing both request and response information 720 * @return error code 721 */ 722 static int process_request_with_output(rh_t *instance, 723 usb_transfer_batch_t *request) { 724 usb_device_request_setup_packet_t * setup_request = 725 (usb_device_request_setup_packet_t*) request->setup_buffer; 726 if (setup_request->request == USB_DEVREQ_GET_STATUS) { 727 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 728 return process_get_status_request(instance, request); 729 } 730 if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR) { 731 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 732 return process_get_descriptor_request(instance, request); 733 } 734 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) { 735 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 736 737 return process_get_configuration_request(instance, request); 738 } 739 return ENOTSUP; 740 } 741 /*----------------------------------------------------------------------------*/ 742 743 /** 744 * process one of requests that carry input data 745 * 746 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or 747 * USB_DEVREQ_SET_CONFIGURATION. 748 * @param instance root hub instance 749 * @param request structure containing both request and response information 750 * @return error code 751 */ 752 static int process_request_with_input(rh_t *instance, 753 usb_transfer_batch_t *request) { 754 usb_device_request_setup_packet_t * setup_request = 755 (usb_device_request_setup_packet_t*) request->setup_buffer; 756 request->transfered_size = 0; 757 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) { 543 544 /* Enabled features to clear: see page 269 of USB specs */ 545 switch (feature) 546 { 547 case USB_HUB_FEATURE_PORT_POWER: //8 548 /* No power switching */ 549 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG) 550 return ENOTSUP; 551 /* Ganged power switching */ 552 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) { 553 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 554 return EOK; 555 } 556 instance->registers->rh_port_status[port - 1] = 557 RHPS_CLEAR_PORT_POWER; 558 return EOK; 559 560 case USB_HUB_FEATURE_PORT_ENABLE: //1 561 instance->registers->rh_port_status[port - 1] = 562 RHPS_CLEAR_PORT_ENABLE; 563 return EOK; 564 565 case USB_HUB_FEATURE_PORT_SUSPEND: //2 566 instance->registers->rh_port_status[port - 1] = 567 RHPS_CLEAR_PORT_SUSPEND; 568 return EOK; 569 570 case USB_HUB_FEATURE_C_PORT_CONNECTION: //16 571 case USB_HUB_FEATURE_C_PORT_ENABLE: //17 572 case USB_HUB_FEATURE_C_PORT_SUSPEND: //18 573 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: //19 574 case USB_HUB_FEATURE_C_PORT_RESET: //20 575 /* Nice thing is that these shifts correspond to the position 576 * of control bits in register */ 577 instance->registers->rh_port_status[port - 1] = (1 << feature); 578 return EOK; 579 580 default: 758 581 return ENOTSUP; 759 582 } 760 if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION) { 761 //set and get configuration requests do not have any meaning, 762 //only dummy values are returned 763 764 return EOK; 765 } 766 return ENOTSUP; 767 } 768 /*----------------------------------------------------------------------------*/ 769 583 } 584 /*----------------------------------------------------------------------------*/ 770 585 /** 771 586 * process one of requests that do not request nor carry additional data … … 777 592 * @return error code 778 593 */ 779 static int process_request_without_data(rh_t *instance, 780 usb_transfer_batch_t *request) { 781 usb_device_request_setup_packet_t * setup_request = 782 (usb_device_request_setup_packet_t*) request->setup_buffer; 783 request->transfered_size = 0; 784 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) { 785 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) { 786 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 787 return process_hub_feature_clear_request(instance, 788 setup_request->value); 789 } 790 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 791 usb_log_debug2("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 792 return process_port_feature_clear_request(instance, 793 setup_request->value, 794 setup_request->index); 795 } 796 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 594 int set_feature(rh_t *instance, usb_transfer_batch_t *request) 595 { 596 assert(instance); 597 assert(request); 598 599 const usb_device_request_setup_packet_t *setup_request = 600 (usb_device_request_setup_packet_t *) request->setup_buffer; 601 switch (setup_request->request_type) 602 { 603 case USB_HUB_REQ_TYPE_SET_PORT_FEATURE: 604 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 605 return set_feature_port(instance, 606 setup_request->value, setup_request->index); 607 608 case USB_HUB_REQ_TYPE_SET_HUB_FEATURE: 609 /* Chapter 11.16.2 specifies that hub can be recipient 610 * only for C_HUB_LOCAL_POWER and C_HUB_OVER_CURRENT 611 * features. It makes no sense to SET either. */ 612 usb_log_error("Invalid HUB set feature request.\n"); 613 return ENOTSUP; 614 default: 615 usb_log_error("Invalid set feature request type: %d\n", 797 616 setup_request->request_type); 798 617 return EINVAL; 799 618 } 800 if (setup_request->request == USB_DEVREQ_SET_FEATURE) { 801 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) { 802 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 803 return process_hub_feature_set_request(instance, 804 setup_request->value); 619 } 620 /*----------------------------------------------------------------------------*/ 621 /** 622 * process one of requests that do not request nor carry additional data 623 * 624 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or 625 * USB_DEVREQ_SET_ADDRESS. 626 * @param instance root hub instance 627 * @param request structure containing both request and response information 628 * @return error code 629 */ 630 int clear_feature(rh_t *instance, usb_transfer_batch_t *request) 631 { 632 assert(instance); 633 assert(request); 634 635 const usb_device_request_setup_packet_t *setup_request = 636 (usb_device_request_setup_packet_t *) request->setup_buffer; 637 request->transfered_size = 0; 638 switch (setup_request->request_type) 639 { 640 case USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE: 641 usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE\n"); 642 return clear_feature_port(instance, 643 setup_request->value, setup_request->index); 644 645 case USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE: 646 usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE\n"); 647 /* 648 * Chapter 11.16.2 specifies that only C_HUB_LOCAL_POWER and 649 * C_HUB_OVER_CURRENT are supported. C_HUB_OVER_CURRENT is represented 650 * by OHCI RHS_OCIC_FLAG. C_HUB_LOCAL_POWER is not supported 651 * as root hubs do not support local power status feature. 652 * (OHCI pg. 127) */ 653 if (setup_request->value == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) { 654 instance->registers->rh_status = RHS_OCIC_FLAG; 655 TRANSFER_OK(0); 805 656 } 806 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 807 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 808 return process_port_feature_set_request(instance, 809 setup_request->value, 810 setup_request->index); 811 } 812 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 657 default: 658 usb_log_error("Invalid clear feature request type: %d\n", 813 659 setup_request->request_type); 814 660 return EINVAL; 815 661 } 816 if (setup_request->request == USB_DEVREQ_SET_ADDRESS) { 817 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 818 return process_address_set_request(instance, 819 setup_request->value); 820 } 821 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 822 setup_request->request_type); 823 824 return ENOTSUP; 825 } 826 /*----------------------------------------------------------------------------*/ 827 828 /** 829 * process hub control request 662 } 663 /*----------------------------------------------------------------------------*/ 664 /** 665 * Process hub control request. 830 666 * 831 667 * If needed, writes answer into the request structure. … … 844 680 * @return error code 845 681 */ 846 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) { 682 int control_request(rh_t *instance, usb_transfer_batch_t *request) 683 { 684 assert(instance); 685 assert(request); 686 847 687 if (!request->setup_buffer) { 848 usb_log_error(" root hub received empty transaction?");688 usb_log_error("Root hub received empty transaction!"); 849 689 return EINVAL; 850 690 } 851 int opResult; 852 if (sizeof 691 692 if (sizeof(usb_device_request_setup_packet_t) > request->setup_size) { 853 693 usb_log_error("Setup packet too small\n"); 854 return EINVAL; 855 } 856 usb_log_debug("CTRL packet: %s.\n", 857 usb_debug_str_buffer( 858 (const uint8_t *) request->setup_buffer, 8, 8)); 859 usb_device_request_setup_packet_t * setup_request = 860 (usb_device_request_setup_packet_t*) 861 request->setup_buffer; 862 switch (setup_request->request) { 863 case USB_DEVREQ_GET_STATUS: 864 case USB_DEVREQ_GET_DESCRIPTOR: 865 case USB_DEVREQ_GET_CONFIGURATION: 866 usb_log_debug2("Processing request with output\n"); 867 opResult = process_request_with_output( 868 instance, request); 869 break; 870 case USB_DEVREQ_CLEAR_FEATURE: 871 case USB_DEVREQ_SET_FEATURE: 872 case USB_DEVREQ_SET_ADDRESS: 873 usb_log_debug2("Processing request without " 874 "additional data\n"); 875 opResult = process_request_without_data( 876 instance, request); 877 break; 878 case USB_DEVREQ_SET_DESCRIPTOR: 879 case USB_DEVREQ_SET_CONFIGURATION: 880 usb_log_debug2("Processing request with input\n"); 881 opResult = process_request_with_input( 882 instance, request); 883 884 break; 885 default: 886 usb_log_warning("Received unsupported request: %d.\n", 887 setup_request->request); 888 opResult = ENOTSUP; 889 } 890 return opResult; 891 } 892 /*----------------------------------------------------------------------------*/ 893 894 /** 895 * process hanging interrupt request 896 * 897 * If an interrupt transfer has been received and there was no change, 898 * the driver stores the transfer information and waits for change to occcur. 899 * This routine is called when that happens and it finalizes the interrupt 900 * transfer. 901 * 902 * @param instance hub instance 903 * @param request batch request to be processed 904 * 905 * @return 906 */ 907 static int process_interrupt_mask_in_instance(rh_t *instance, 908 usb_transfer_batch_t * request) { 909 memcpy(request->data_buffer, instance->interrupt_buffer, 910 instance->interrupt_mask_size); 911 request->transfered_size = instance->interrupt_mask_size; 912 instance->unfinished_interrupt_transfer = NULL; 913 usb_transfer_batch_finish_error(request, EOK); 914 915 return EOK; 916 } 917 918 /*----------------------------------------------------------------------------*/ 919 920 /** 921 * return whether the buffer is full of zeros 922 * 923 * Convenience function. 924 * @param buffer 925 * @param size 926 * @return 927 */ 928 static bool is_zeros(void *buffer, size_t size) { 929 if (!buffer) return true; 930 if (!size) return true; 931 size_t i; 932 for (i = 0; i < size; ++i) { 933 if (((char*) buffer)[i]) 934 return false; 935 } 936 return true; 694 return EOVERFLOW; 695 } 696 697 usb_log_debug2("CTRL packet: %s.\n", 698 usb_debug_str_buffer((uint8_t *) request->setup_buffer, 8, 8)); 699 const usb_device_request_setup_packet_t *setup_request = 700 (usb_device_request_setup_packet_t *) request->setup_buffer; 701 switch (setup_request->request) 702 { 703 case USB_DEVREQ_GET_STATUS: 704 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 705 return get_status(instance, request); 706 707 case USB_DEVREQ_GET_DESCRIPTOR: 708 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 709 return get_descriptor(instance, request); 710 711 case USB_DEVREQ_GET_CONFIGURATION: 712 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 713 if (request->buffer_size != 1) 714 return EINVAL; 715 request->data_buffer[0] = 1; 716 TRANSFER_OK(1); 717 718 case USB_DEVREQ_CLEAR_FEATURE: 719 usb_log_debug2("Processing request without " 720 "additional data\n"); 721 return clear_feature(instance, request); 722 case USB_DEVREQ_SET_FEATURE: 723 usb_log_debug2("Processing request without " 724 "additional data\n"); 725 return set_feature(instance, request); 726 727 case USB_DEVREQ_SET_ADDRESS: 728 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 729 instance->address = setup_request->value; 730 TRANSFER_OK(0); 731 732 case USB_DEVREQ_SET_CONFIGURATION: 733 usb_log_debug("USB_DEVREQ_SET_CONFIGURATION\n"); 734 /* We don't need to do anything */ 735 TRANSFER_OK(0); 736 737 case USB_DEVREQ_SET_DESCRIPTOR: /* Not supported by OHCI RH */ 738 default: 739 usb_log_error("Received unsupported request: %d.\n", 740 setup_request->request); 741 return ENOTSUP; 742 } 937 743 } 938 744
Note:
See TracChangeset
for help on using the changeset viewer.