source: mainline/uspace/drv/usbhub/usbhub.c@ 233e68d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 233e68d was eb1a2f4, checked in by Vojtech Horky <vojtechhorky@…>, 15 years ago

Merge mainline changes (DDF refactoring)

This merge includes DDF refactoring that brought multifunctional devices
(i.e. ddf_dev_t and ddf_fun_t). Please, see ticket #295 at HelenOS
upstream Trac.

The conflicts themselves were easy to solve (merely several renamings).

Changes to USB subsystem:

  • drivers uses ddf_dev_t and ddf_fun_t
  • different signatures of many library functions
  • several hacks around communication with parent device (now the communication is clearer and somehow what we have now is hack about other hacks)
    • will repair and clean later
  • maybe added some extra debugging messages (the diff has about 240K, and I admit I have no energy to double check that)

WARNING:

  • the diff is VERY long, recommended is viewing partial diffs of the merge (i.e. merges in mainline branch that lead to the parent one)
  • merging with your branches might involve huge renamings, sorry, no other way is possible

BUGS:

  • hub driver will not work (no function created)

GOOD NEWS:

  • QEMU keyboard seems to work with QEMU 0.13 and 0.14
  • we are up-to-date with mainline again
  • Property mode set to 100644
File size: 19.4 KB
Line 
1/*
2 * Copyright (c) 2010 Matus Dekanek
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28/** @addtogroup drvusbhub
29 * @{
30 */
31/** @file
32 * @brief usb hub main functionality
33 */
34
35#include <ddf/driver.h>
36#include <bool.h>
37#include <errno.h>
38#include <str_error.h>
39
40#include <usb_iface.h>
41#include <usb/ddfiface.h>
42#include <usb/descriptor.h>
43#include <usb/recognise.h>
44#include <usb/request.h>
45#include <usb/classes/hub.h>
46
47#include "usbhub.h"
48#include "usbhub_private.h"
49#include "port_status.h"
50#include "usb/usb.h"
51#include "usb/pipes.h"
52#include "usb/classes/classes.h"
53
54static ddf_dev_ops_t hub_device_ops = {
55 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
56};
57
58/** Hub status-change endpoint description */
59static usb_endpoint_description_t status_change_endpoint_description = {
60 .transfer_type = USB_TRANSFER_INTERRUPT,
61 .direction = USB_DIRECTION_IN,
62 .interface_class = USB_CLASS_HUB,
63 .flags = 0
64};
65
66
67//*********************************************
68//
69// hub driver code, initialization
70//
71//*********************************************
72
73/**
74 * Initialize connnections to host controller, device, and device
75 * control endpoint
76 * @param hub
77 * @param device
78 * @return
79 */
80static int usb_hub_init_communication(usb_hub_info_t * hub){
81 usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle);
82 int opResult;
83 opResult = usb_device_connection_initialize_from_device(
84 &hub->device_connection,
85 hub->device);
86 if(opResult != EOK){
87 dprintf(USB_LOG_LEVEL_ERROR,
88 "could not initialize connection to hc, errno %d",opResult);
89 return opResult;
90 }
91 usb_log_debug("Initializing USB wire abstraction.\n");
92 opResult = usb_hc_connection_initialize_from_device(&hub->connection,
93 hub->device);
94 if(opResult != EOK){
95 dprintf(USB_LOG_LEVEL_ERROR,
96 "could not initialize connection to device, errno %d",opResult);
97 return opResult;
98 }
99 usb_log_debug("Initializing default control pipe.\n");
100 opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
101 &hub->device_connection);
102 if(opResult != EOK){
103 dprintf(USB_LOG_LEVEL_ERROR,
104 "could not initialize connection to device endpoint, errno %d",opResult);
105 }
106 return opResult;
107}
108
109/**
110 * When entering this function, hub->endpoints.control should be active.
111 * @param hub
112 * @return
113 */
114static int usb_hub_process_configuration_descriptors(
115 usb_hub_info_t * hub){
116 if(hub==NULL) {
117 return EINVAL;
118 }
119 int opResult;
120
121 //device descriptor
122 usb_standard_device_descriptor_t std_descriptor;
123 opResult = usb_request_get_device_descriptor(&hub->endpoints.control,
124 &std_descriptor);
125 if(opResult!=EOK){
126 dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult);
127 return opResult;
128 }
129 dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations",
130 std_descriptor.configuration_count);
131 if(std_descriptor.configuration_count<1){
132 dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE");
133 //shouldn`t I return?
134 }
135
136 //configuration descriptor
137 /// \TODO check other configurations
138 usb_standard_configuration_descriptor_t config_descriptor;
139 opResult = usb_request_get_bare_configuration_descriptor(
140 &hub->endpoints.control, 0,
141 &config_descriptor);
142 if(opResult!=EOK){
143 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
144 return opResult;
145 }
146 //set configuration
147 opResult = usb_request_set_configuration(&hub->endpoints.control,
148 config_descriptor.configuration_number);
149
150 if (opResult != EOK) {
151 dprintf(USB_LOG_LEVEL_ERROR,
152 "something went wrong when setting hub`s configuration, %d",
153 opResult);
154 return opResult;
155 }
156 dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",
157 config_descriptor.configuration_number);
158
159 //full configuration descriptor
160 size_t transferred = 0;
161 uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length);
162 if (descriptors == NULL) {
163 dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory");
164 return ENOMEM;
165 }
166 opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control,
167 0, descriptors,
168 config_descriptor.total_length, &transferred);
169 if(opResult!=EOK){
170 free(descriptors);
171 dprintf(USB_LOG_LEVEL_ERROR,
172 "could not get full configuration descriptor, %d",opResult);
173 return opResult;
174 }
175 if (transferred != config_descriptor.total_length) {
176 dprintf(USB_LOG_LEVEL_ERROR,
177 "received incorrect full configuration descriptor");
178 return ELIMIT;
179 }
180
181 /**
182 * Initialize the interrupt in endpoint.
183 * \TODO this code should be checked...
184 */
185 usb_endpoint_mapping_t endpoint_mapping[1] = {
186 {
187 .pipe = &hub->endpoints.status_change,
188 .description = &status_change_endpoint_description,
189 .interface_no =
190 usb_device_get_assigned_interface(hub->device)
191 }
192 };
193 opResult = usb_endpoint_pipe_initialize_from_configuration(
194 endpoint_mapping, 1,
195 descriptors, config_descriptor.total_length,
196 &hub->device_connection);
197 if (opResult != EOK) {
198 dprintf(USB_LOG_LEVEL_ERROR,
199 "Failed to initialize status change pipe: %s",
200 str_error(opResult));
201 return opResult;
202 }
203 if (!endpoint_mapping[0].present) {
204 dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \
205 "cannot understand what is happenning");
206 return EREFUSED;
207 }
208
209 free(descriptors);
210 return EOK;
211
212
213 // Initialize the interrupt(=status change) endpoint.
214 /*usb_endpoint_pipe_initialize(
215 &result->endpoints->status_change,
216 &result->device_connection, );USB_TRANSFER_INTERRUPT
217 USB_DIRECTION_IN*/
218
219}
220
221
222/**
223 * Create hub representation from device information.
224 * @param device
225 * @return pointer to created structure or NULL in case of error
226 */
227usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
228 usb_hub_info_t* result = usb_new(usb_hub_info_t);
229 result->device = device;
230 int opResult;
231 opResult = usb_hub_init_communication(result);
232 if(opResult != EOK){
233 free(result);
234 return NULL;
235 }
236
237 //result->device = device;
238 result->port_count = -1;
239 result->device = device;
240
241 //result->usb_device = usb_new(usb_hcd_attached_device_info_t);
242 size_t received_size;
243
244 // get hub descriptor
245 dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton");
246 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
247 usb_hub_descriptor_t * descriptor;
248 dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction");
249 usb_endpoint_pipe_start_session(&result->endpoints.control);
250 opResult = usb_request_get_descriptor(&result->endpoints.control,
251 USB_REQUEST_TYPE_CLASS,
252 USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
253 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
254 usb_endpoint_pipe_end_session(&result->endpoints.control);
255
256 if (opResult != EOK) {
257 dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult);
258 free(serialized_descriptor);
259 return result;
260 }
261 dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor");
262 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
263 if(descriptor==NULL){
264 dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor ");
265 result->port_count = 1;///\TODO this code is only for debug!!!
266 return result;
267 }
268
269
270 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
271 result->port_count = descriptor->ports_count;
272 result->attached_devs = (usb_hc_attached_device_t*)
273 malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t));
274 int i;
275 for(i=0;i<result->port_count+1;++i){
276 result->attached_devs[i].handle=0;
277 result->attached_devs[i].address=0;
278 }
279 dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data");
280 free(serialized_descriptor);
281 free(descriptor->devices_removable);
282 free(descriptor);
283
284 //finish
285
286 dprintf(USB_LOG_LEVEL_INFO, "hub info created");
287
288 return result;
289}
290
291/**
292 * Create hub representation and add it into hub list
293 * @param dev
294 * @return
295 */
296int usb_add_hub_device(ddf_dev_t *dev) {
297 dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle);
298
299 //dev->ops = &hub_device_ops;
300 (void) hub_device_ops;
301
302 usb_hub_info_t * hub_info = usb_create_hub_info(dev);
303
304 int opResult;
305
306 //perform final configurations
307 usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
308 // process descriptors
309 opResult = usb_hub_process_configuration_descriptors(hub_info);
310 if(opResult != EOK){
311 dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d",
312 opResult);
313 return opResult;
314 }
315 //power ports
316 usb_device_request_setup_packet_t request;
317 int port;
318 for (port = 1; port < hub_info->port_count+1; ++port) {
319 usb_hub_set_power_port_request(&request, port);
320 opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control,
321 &request,sizeof(usb_device_request_setup_packet_t), NULL, 0);
322 dprintf(USB_LOG_LEVEL_INFO, "powering port %d",port);
323 if (opResult != EOK) {
324 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port);
325 }
326 }
327 //ports powered, hub seems to be enabled
328 usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
329
330 //add the hub to list
331 fibril_mutex_lock(&usb_hub_list_lock);
332 usb_lst_append(&usb_hub_list, hub_info);
333 fibril_mutex_unlock(&usb_hub_list_lock);
334
335 dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list");
336 //(void)hub_info;
337 usb_hub_check_hub_changes();
338
339 dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
340 //address is lost...
341 dprintf(USB_LOG_LEVEL_DEBUG, "\taddress %d, has %d ports ",
342 //hub_info->endpoints.control.,
343 hub_info->port_count);
344
345 return EOK;
346 //return ENOTSUP;
347}
348
349
350//*********************************************
351//
352// hub driver code, main loop
353//
354//*********************************************
355
356/**
357 * Reset the port with new device and reserve the default address.
358 * @param hc
359 * @param port
360 * @param target
361 */
362static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) {
363 usb_device_request_setup_packet_t request;
364 int opResult;
365 dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
366 assert(hub->endpoints.control.hc_phone);
367 //get default address
368 //opResult = usb_drv_reserve_default_address(hc);
369 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
370
371 if (opResult != EOK) {
372 dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used");
373 return;
374 }
375 //reset port
376 usb_hub_set_reset_port_request(&request, port);
377 opResult = usb_endpoint_pipe_control_write(
378 &hub->endpoints.control,
379 &request,sizeof(usb_device_request_setup_packet_t),
380 NULL, 0
381 );
382 if (opResult != EOK) {
383 dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port");
384 //usb_hub_release_default_address(hc);
385 usb_hc_release_default_address(&hub->connection);
386 }
387}
388
389/**
390 * Finalize adding new device after port reset
391 * @param hc
392 * @param port
393 * @param target
394 */
395static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
396 uint16_t port) {
397
398 int opResult;
399 dprintf(USB_LOG_LEVEL_INFO, "finalizing add device");
400 opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
401 port, USB_HUB_FEATURE_C_PORT_RESET);
402
403 if (opResult != EOK) {
404 dprintf(USB_LOG_LEVEL_ERROR, "failed to clear port reset feature");
405 usb_hc_release_default_address(&hub->connection);
406 return;
407 }
408 //create connection to device
409 usb_endpoint_pipe_t new_device_pipe;
410 usb_device_connection_t new_device_connection;
411 usb_device_connection_initialize_on_default_address(
412 &new_device_connection,
413 &hub->connection
414 );
415 usb_endpoint_pipe_initialize_default_control(
416 &new_device_pipe,
417 &new_device_connection);
418 /// \TODO get highspeed info
419
420
421
422
423
424 /* Request address from host controller. */
425 usb_address_t new_device_address = usb_hc_request_address(
426 &hub->connection,
427 USB_SPEED_LOW/// \TODO fullspeed??
428 );
429 if (new_device_address < 0) {
430 dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address");
431 opResult = new_device_address;
432 usb_hc_release_default_address(&hub->connection);
433 return;
434 }
435 dprintf(USB_LOG_LEVEL_INFO, "setting new address %d",new_device_address);
436 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
437 // new_device_address);
438 opResult = usb_request_set_address(&new_device_pipe,new_device_address);
439
440 if (opResult != EOK) {
441 dprintf(USB_LOG_LEVEL_ERROR, "could not set address for new device");
442 usb_hc_release_default_address(&hub->connection);
443 return;
444 }
445
446
447 //opResult = usb_hub_release_default_address(hc);
448 opResult = usb_hc_release_default_address(&hub->connection);
449 if(opResult!=EOK){
450 return;
451 }
452
453 devman_handle_t child_handle;
454 //??
455 opResult = usb_device_register_child_in_devman(new_device_address,
456 hub->connection.hc_handle, hub->device, &child_handle,
457 NULL, NULL, NULL);
458
459 if (opResult != EOK) {
460 dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device");
461 return;
462 }
463 hub->attached_devs[port].handle = child_handle;
464 hub->attached_devs[port].address = new_device_address;
465
466 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
467 opResult = usb_hc_register_device(
468 &hub->connection,
469 &hub->attached_devs[port]);
470 if (opResult != EOK) {
471 dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd");
472 return;
473 }
474 dprintf(USB_LOG_LEVEL_INFO, "new device address %d, handle %zu",
475 new_device_address, child_handle);
476
477}
478
479/**
480 * Unregister device address in hc
481 * @param hc
482 * @param port
483 * @param target
484 */
485static void usb_hub_removed_device(
486 usb_hub_info_t * hub,uint16_t port) {
487 //usb_device_request_setup_packet_t request;
488 int opResult;
489
490 /** \TODO remove device from device manager - not yet implemented in
491 * devide manager
492 */
493
494 //close address
495 if(hub->attached_devs[port].address!=0){
496 //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
497 opResult = usb_hc_unregister_device(
498 &hub->connection, hub->attached_devs[port].address);
499 if(opResult != EOK) {
500 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
501 "removed device: %d", opResult);
502 }
503 hub->attached_devs[port].address = 0;
504 hub->attached_devs[port].handle = 0;
505 }else{
506 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address");
507 //device was disconnected before it`s port was reset - return default address
508 //usb_drv_release_default_address(hc);
509 usb_hc_release_default_address(&hub->connection);
510 }
511}
512
513/**
514 * Process interrupts on given hub port
515 * @param hc
516 * @param port
517 * @param target
518 */
519static void usb_hub_process_interrupt(usb_hub_info_t * hub,
520 uint16_t port) {
521 dprintf(USB_LOG_LEVEL_DEBUG, "interrupt at port %d", port);
522 //determine type of change
523 usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
524 int opResult = usb_endpoint_pipe_start_session(pipe);
525
526 if(opResult != EOK){
527 dprintf(USB_LOG_LEVEL_ERROR, "cannot open pipe %d", opResult);
528 }
529
530 /*
531 usb_target_t target;
532 target.address=address;
533 target.endpoint=0;
534 */
535
536 usb_port_status_t status;
537 size_t rcvd_size;
538 usb_device_request_setup_packet_t request;
539 //int opResult;
540 usb_hub_set_port_status_request(&request, port);
541 //endpoint 0
542
543 opResult = usb_endpoint_pipe_control_read(
544 pipe,
545 &request, sizeof(usb_device_request_setup_packet_t),
546 &status, 4, &rcvd_size
547 );
548 if (opResult != EOK) {
549 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: could not get port status");
550 return;
551 }
552 if (rcvd_size != sizeof (usb_port_status_t)) {
553 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: received status has incorrect size");
554 return;
555 }
556 //something connected/disconnected
557 if (usb_port_connect_change(&status)) {
558 opResult = usb_hub_clear_port_feature(pipe,
559 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
560 // TODO: check opResult
561 if (usb_port_dev_connected(&status)) {
562 dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
563 usb_hub_init_add_device(hub, port);
564 } else {
565 usb_hub_removed_device(hub, port);
566 }
567 }
568 //port reset
569 if (usb_port_reset_completed(&status)) {
570 dprintf(USB_LOG_LEVEL_INFO, "port reset complete");
571 if (usb_port_enabled(&status)) {
572 usb_hub_finalize_add_device(hub, port);
573 } else {
574 dprintf(USB_LOG_LEVEL_WARNING, "ERROR: port reset, but port still not enabled");
575 }
576 }
577
578 usb_port_set_connect_change(&status, false);
579 usb_port_set_reset(&status, false);
580 usb_port_set_reset_completed(&status, false);
581 usb_port_set_dev_connected(&status, false);
582 if (status>>16) {
583 dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status);
584
585 }
586 /// \TODO handle other changes
587 /// \TODO debug log for various situations
588 usb_endpoint_pipe_end_session(pipe);
589
590
591}
592
593/**
594 * Check changes on all known hubs.
595 */
596void usb_hub_check_hub_changes(void) {
597 /*
598 * Iterate through all hubs.
599 */
600 usb_general_list_t * lst_item;
601 fibril_mutex_lock(&usb_hub_list_lock);
602 for (lst_item = usb_hub_list.next;
603 lst_item != &usb_hub_list;
604 lst_item = lst_item->next) {
605 fibril_mutex_unlock(&usb_hub_list_lock);
606 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
607 int opResult;
608
609 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
610 if(opResult != EOK){
611 continue;
612 }
613 /*
614 * Check status change pipe of this hub.
615 */
616 /*
617 usb_target_t target;
618 target.address = hub_info->address;
619 target.endpoint = 1;/// \TODO get from endpoint descriptor
620 dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d",
621 target.address);
622 */
623 size_t port_count = hub_info->port_count;
624
625 /*
626 * Connect to respective HC.
627 *
628 int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
629 if (hc < 0) {
630 continue;
631 }*/
632
633 /// FIXME: count properly
634 size_t byte_length = ((port_count+1) / 8) + 1;
635
636 void *change_bitmap = malloc(byte_length);
637 size_t actual_size;
638 //usb_handle_t handle;
639
640 /*
641 * Send the request.
642 */
643 opResult = usb_endpoint_pipe_read(
644 &hub_info->endpoints.status_change,
645 change_bitmap, byte_length, &actual_size
646 );
647
648 //usb_drv_async_wait_for(handle);
649
650 if (opResult != EOK) {
651 free(change_bitmap);
652 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
653 continue;
654 }
655 unsigned int port;
656 for (port = 1; port < port_count+1; ++port) {
657 bool interrupt =
658 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
659 if (interrupt) {
660 usb_hub_process_interrupt(
661 hub_info, port);
662 }
663 }
664 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
665 free(change_bitmap);
666
667
668 //async_hangup(hc);
669 fibril_mutex_lock(&usb_hub_list_lock);
670 }
671 fibril_mutex_unlock(&usb_hub_list_lock);
672}
673
674
675
676
677
678/**
679 * @}
680 */
Note: See TracBrowser for help on using the repository browser.