Changeset 07c08ea in mainline
- Timestamp:
- 2017-08-20T13:22:44Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 60ac352
- Parents:
- d32d51d
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/hc.c
rd32d51d r07c08ea 458 458 status = hc->op_regs->usbsts; 459 459 460 /* TODO: Figure out how root hub interrupts work. */ 461 if (status | 1) { 462 usb_log_debug2("Root hub interrupt."); 463 xhci_rh_interrupt(&hc->rh); 464 } 465 460 466 if (status & XHCI_REG_MASK(XHCI_OP_HSE)) { 461 467 usb_log_error("Host controller error occured. Bad things gonna happen..."); -
uspace/drv/bus/usb/xhci/hc.h
rd32d51d r07c08ea 76 76 xhci_scratchpad_t *scratchpad; 77 77 78 78 /* Root hub emulation */ 79 79 xhci_rh_t rh; 80 80 -
uspace/drv/bus/usb/xhci/rh.c
rd32d51d r07c08ea 44 44 #include "rh.h" 45 45 46 enum { 47 HUB_STATUS_CHANGE_PIPE = 1, 48 }; 49 50 static usbvirt_device_ops_t ops; 51 46 52 int xhci_rh_init(xhci_rh_t *rh) 47 53 { 48 /* TODO: Implement me! */49 return EOK;54 return virthub_base_init(&rh->base, "xhci rh", &ops, rh, NULL, 55 &rh->hub_descriptor.header, HUB_STATUS_CHANGE_PIPE); 50 56 } 51 57 … … 229 235 int xhci_rh_schedule(xhci_rh_t *rh, usb_transfer_batch_t *batch) 230 236 { 231 /* TODO: Implement me! */ 237 assert(rh); 238 assert(batch); 239 const usb_target_t target = {{ 240 .address = batch->ep->address, 241 .endpoint = batch->ep->endpoint, 242 }}; 243 batch->error = virthub_base_request(&rh->base, target, 244 usb_transfer_batch_direction(batch), (void*)batch->setup_buffer, 245 batch->buffer, batch->buffer_size, &batch->transfered_size); 246 if (batch->error == ENAK) { 247 /* This is safe because only status change interrupt transfers 248 * return NAK. The assertion holds true because the batch 249 * existence prevents communication with that ep */ 250 assert(rh->unfinished_interrupt_transfer == NULL); 251 rh->unfinished_interrupt_transfer = batch; 252 } else { 253 usb_transfer_batch_finish(batch, NULL); 254 usb_transfer_batch_destroy(batch); 255 } 256 return EOK; 257 } 258 259 int xhci_rh_interrupt(xhci_rh_t *rh) 260 { 261 usb_log_debug2("Called xhci_rh_interrupt()."); 262 263 /* TODO: atomic swap needed */ 264 usb_transfer_batch_t *batch = rh->unfinished_interrupt_transfer; 265 rh->unfinished_interrupt_transfer = NULL; 266 if (batch) { 267 const usb_target_t target = {{ 268 .address = batch->ep->address, 269 .endpoint = batch->ep->endpoint, 270 }}; 271 batch->error = virthub_base_request(&rh->base, target, 272 usb_transfer_batch_direction(batch), 273 (void*)batch->setup_buffer, 274 batch->buffer, batch->buffer_size, &batch->transfered_size); 275 usb_transfer_batch_finish(batch, NULL); 276 usb_transfer_batch_destroy(batch); 277 } 278 return EOK; 279 } 280 281 /** Hub status request handler. 282 * @param device Virtual hub device 283 * @param setup_packet USB setup stage data. 284 * @param[out] data destination data buffer, size must be at least 285 * setup_packet->length bytes 286 * @param[out] act_size Sized of the valid response part of the buffer. 287 * @return Error code. 288 */ 289 static int req_get_status(usbvirt_device_t *device, 290 const usb_device_request_setup_packet_t *setup_packet, 291 uint8_t *data, size_t *act_size) 292 { 293 /* TODO: Implement me! */ 294 usb_log_debug2("Called req_get_status()."); 295 return EOK; 296 } 297 298 /** Hub set feature request handler. 299 * @param device Virtual hub device 300 * @param setup_packet USB setup stage data. 301 * @param[out] data destination data buffer, size must be at least 302 * setup_packet->length bytes 303 * @param[out] act_size Sized of the valid response part of the buffer. 304 * @return Error code. 305 */ 306 static int req_clear_hub_feature(usbvirt_device_t *device, 307 const usb_device_request_setup_packet_t *setup_packet, 308 uint8_t *data, size_t *act_size) 309 { 310 /* TODO: Implement me! */ 311 usb_log_debug2("Called req_clear_hub_feature()."); 312 return EOK; 313 } 314 315 /** Port status request handler. 316 * @param device Virtual hub device 317 * @param setup_packet USB setup stage data. 318 * @param[out] data destination data buffer, size must be at least 319 * setup_packet->length bytes 320 * @param[out] act_size Sized of the valid response part of the buffer. 321 * @return Error code. 322 */ 323 static int req_get_port_status(usbvirt_device_t *device, 324 const usb_device_request_setup_packet_t *setup_packet, 325 uint8_t *data, size_t *act_size) 326 { 327 /* TODO: Implement me! */ 328 usb_log_debug2("Called req_get_port_status()."); 329 return EOK; 330 } 331 332 /** Port clear feature request handler. 333 * @param device Virtual hub device 334 * @param setup_packet USB setup stage data. 335 * @param[out] data destination data buffer, size must be at least 336 * setup_packet->length bytes 337 * @param[out] act_size Sized of the valid response part of the buffer. 338 * @return Error code. 339 */ 340 static int req_clear_port_feature(usbvirt_device_t *device, 341 const usb_device_request_setup_packet_t *setup_packet, 342 uint8_t *data, size_t *act_size) 343 { 344 /* TODO: Implement me! */ 345 usb_log_debug2("Called req_clear_port_feature()."); 346 return EOK; 347 } 348 349 /** Port set feature request handler. 350 * @param device Virtual hub device 351 * @param setup_packet USB setup stage data. 352 * @param[out] data destination data buffer, size must be at least 353 * setup_packet->length bytes 354 * @param[out] act_size Sized of the valid response part of the buffer. 355 * @return Error code. 356 */ 357 static int req_set_port_feature(usbvirt_device_t *device, 358 const usb_device_request_setup_packet_t *setup_packet, 359 uint8_t *data, size_t *act_size) 360 { 361 /* TODO: Implement me! */ 362 usb_log_debug2("Called req_set_port_feature()."); 363 return EOK; 364 } 365 366 /** Status change handler. 367 * @param device Virtual hub device 368 * @param endpoint Endpoint number 369 * @param tr_type Transfer type 370 * @param buffer Response destination 371 * @param buffer_size Bytes available in buffer 372 * @param actual_size Size us the used part of the dest buffer. 373 * 374 * Produces status mask. Bit 0 indicates hub status change the other bits 375 * represent port status change. Endian does not matter as UHCI root hubs 376 * only need 1 byte. 377 */ 378 static int req_status_change_handler(usbvirt_device_t *device, 379 usb_endpoint_t endpoint, usb_transfer_type_t tr_type, 380 void *buffer, size_t buffer_size, size_t *actual_size) 381 { 382 /* TODO: Implement me! */ 383 usb_log_debug2("Called req_status_change_handler()."); 232 384 return EOK; 233 385 } … … 236 388 { 237 389 /* TODO: Implement me! */ 238 return EOK; 239 } 390 usb_log_debug2("Called xhci_rh_fini()."); 391 return EOK; 392 } 393 394 /** XHCI root hub request handlers */ 395 static const usbvirt_control_request_handler_t control_transfer_handlers[] = { 396 { 397 STD_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_GET_DESCRIPTOR), 398 .name = "GetDescriptor", 399 .callback = virthub_base_get_hub_descriptor, 400 }, 401 { 402 CLASS_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_GET_DESCRIPTOR), 403 .name = "GetDescriptor", 404 .callback = virthub_base_get_hub_descriptor, 405 }, 406 { 407 CLASS_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_HUB_REQUEST_GET_DESCRIPTOR), 408 .name = "GetHubDescriptor", 409 .callback = virthub_base_get_hub_descriptor, 410 }, 411 { 412 CLASS_REQ_IN(USB_REQUEST_RECIPIENT_OTHER, USB_HUB_REQUEST_GET_STATUS), 413 .name = "GetPortStatus", 414 .callback = req_get_port_status, 415 }, 416 { 417 CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_DEVICE, USB_HUB_REQUEST_CLEAR_FEATURE), 418 .name = "ClearHubFeature", 419 .callback = req_clear_hub_feature, 420 }, 421 { 422 CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_OTHER, USB_HUB_REQUEST_CLEAR_FEATURE), 423 .name = "ClearPortFeature", 424 .callback = req_clear_port_feature, 425 }, 426 { 427 CLASS_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_HUB_REQUEST_GET_STATUS), 428 .name = "GetHubStatus", 429 .callback = req_get_status, 430 }, 431 { 432 CLASS_REQ_IN(USB_REQUEST_RECIPIENT_OTHER, USB_HUB_REQUEST_GET_STATUS), 433 .name = "GetPortStatus", 434 .callback = req_get_port_status, 435 }, 436 { 437 CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_DEVICE, USB_HUB_REQUEST_SET_FEATURE), 438 .name = "SetHubFeature", 439 .callback = req_nop, 440 }, 441 { 442 CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_OTHER, USB_HUB_REQUEST_SET_FEATURE), 443 .name = "SetPortFeature", 444 .callback = req_set_port_feature, 445 }, 446 { 447 .callback = NULL 448 } 449 }; 450 451 /** Virtual XHCI root hub ops */ 452 static usbvirt_device_ops_t ops = { 453 .control = control_transfer_handlers, 454 .data_in[HUB_STATUS_CHANGE_PIPE] = req_status_change_handler, 455 }; 240 456 241 457 -
uspace/drv/bus/usb/xhci/rh.h
rd32d51d r07c08ea 40 40 #include <usbvirt/virthub_base.h> 41 41 42 enum { 43 XHCI_MAX_PORTS = 255, 44 }; 45 42 46 /* XHCI root hub instance */ 43 47 typedef struct { 44 48 /** Virtual hub instance */ 45 49 virthub_base_t base; 50 /** USB hub descriptor describing the XHCI root hub */ 51 struct { 52 usb_hub_descriptor_header_t header; 53 uint8_t rempow[STATUS_BYTES(XHCI_MAX_PORTS) * 2]; 54 } __attribute__((packed)) hub_descriptor; 55 /** Interrupt transfer waiting for an actual interrupt to occur */ 56 usb_transfer_batch_t *unfinished_interrupt_transfer; 46 57 } xhci_rh_t; 47 58 … … 52 63 int xhci_reset_hub_port(xhci_hc_t *, uint8_t); 53 64 int xhci_rh_schedule(xhci_rh_t *, usb_transfer_batch_t *); 65 int xhci_rh_interrupt(xhci_rh_t *); 54 66 55 67 #endif
Note:
See TracChangeset
for help on using the changeset viewer.