source: mainline/uspace/drv/usbhub/usbhub.c@ 4fb6d9ee

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4fb6d9ee was e93e319, checked in by Matus Dekanek <smekideki@…>, 14 years ago

second check of bug 138 (multiple new devices)

  • Property mode set to 100644
File size: 20.8 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#include <stdio.h>
47
48#include "usbhub.h"
49#include "usbhub_private.h"
50#include "port_status.h"
51#include "usb/usb.h"
52#include "usb/pipes.h"
53#include "usb/classes/classes.h"
54
55static ddf_dev_ops_t hub_device_ops = {
56 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
57};
58
59/** Hub status-change endpoint description
60 *
61 * For more see usb hub specification in 11.15.1 of
62 */
63static usb_endpoint_description_t status_change_endpoint_description = {
64 .transfer_type = USB_TRANSFER_INTERRUPT,
65 .direction = USB_DIRECTION_IN,
66 .interface_class = USB_CLASS_HUB,
67 .interface_subclass = 0,
68 .interface_protocol = 0,
69 .flags = 0
70};
71
72int usb_hub_control_loop(void * hub_info_param){
73 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
74 int errorCode = EOK;
75
76 while(errorCode == EOK){
77 errorCode = usb_hub_check_hub_changes(hub_info);
78 async_usleep(1000 * 1000 );/// \TODO proper number once
79 }
80 usb_log_error("something in ctrl loop went wrong, errno %d",errorCode);
81
82 return 0;
83}
84
85
86//*********************************************
87//
88// hub driver code, initialization
89//
90//*********************************************
91
92/**
93 * Initialize connnections to host controller, device, and device
94 * control endpoint
95 * @param hub
96 * @param device
97 * @return
98 */
99static int usb_hub_init_communication(usb_hub_info_t * hub){
100 usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle);
101 int opResult;
102 opResult = usb_device_connection_initialize_from_device(
103 &hub->device_connection,
104 hub->device);
105 if(opResult != EOK){
106 usb_log_error("could not initialize connection to hc, errno %d",opResult);
107 return opResult;
108 }
109 usb_log_debug("Initializing USB wire abstraction.\n");
110 opResult = usb_hc_connection_initialize_from_device(&hub->connection,
111 hub->device);
112 if(opResult != EOK){
113 usb_log_error("could not initialize connection to device, errno %d",
114 opResult);
115 return opResult;
116 }
117 usb_log_debug("Initializing default control pipe.\n");
118 opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
119 &hub->device_connection);
120 if(opResult != EOK){
121 usb_log_error("could not initialize connection to device endpoint, errno %d",
122 opResult);
123 return opResult;
124 }
125
126 opResult = usb_endpoint_pipe_probe_default_control(&hub->endpoints.control);
127 if (opResult != EOK) {
128 usb_log_error("failed probing endpoint 0, %d", opResult);
129 return opResult;
130 }
131
132 return EOK;
133}
134
135/**
136 * When entering this function, hub->endpoints.control should be active.
137 * @param hub
138 * @return
139 */
140static int usb_hub_process_configuration_descriptors(
141 usb_hub_info_t * hub){
142 if(hub==NULL) {
143 return EINVAL;
144 }
145 int opResult;
146
147 //device descriptor
148 usb_standard_device_descriptor_t std_descriptor;
149 opResult = usb_request_get_device_descriptor(&hub->endpoints.control,
150 &std_descriptor);
151 if(opResult!=EOK){
152 usb_log_error("could not get device descriptor, %d",opResult);
153 return opResult;
154 }
155 usb_log_info("hub has %d configurations",
156 std_descriptor.configuration_count);
157 if(std_descriptor.configuration_count<1){
158 usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE");
159 //shouldn`t I return?
160 }
161
162 /* Retrieve full configuration descriptor. */
163 uint8_t *descriptors = NULL;
164 size_t descriptors_size = 0;
165 opResult = usb_request_get_full_configuration_descriptor_alloc(
166 &hub->endpoints.control, 0,
167 (void **) &descriptors, &descriptors_size);
168 if (opResult != EOK) {
169 usb_log_error("Could not get configuration descriptor: %s.\n",
170 str_error(opResult));
171 return opResult;
172 }
173 usb_standard_configuration_descriptor_t *config_descriptor
174 = (usb_standard_configuration_descriptor_t *) descriptors;
175
176 /* Set configuration. */
177 opResult = usb_request_set_configuration(&hub->endpoints.control,
178 config_descriptor->configuration_number);
179
180 if (opResult != EOK) {
181 usb_log_error("Failed to set hub configuration: %s.\n",
182 str_error(opResult));
183 return opResult;
184 }
185 usb_log_debug("\tused configuration %d",
186 config_descriptor->configuration_number);
187
188 usb_endpoint_mapping_t endpoint_mapping[1] = {
189 {
190 .pipe = &hub->endpoints.status_change,
191 .description = &status_change_endpoint_description,
192 .interface_no =
193 usb_device_get_assigned_interface(hub->device)
194 }
195 };
196 opResult = usb_endpoint_pipe_initialize_from_configuration(
197 endpoint_mapping, 1,
198 descriptors, descriptors_size,
199 &hub->device_connection);
200 if (opResult != EOK) {
201 usb_log_error("Failed to initialize status change pipe: %s",
202 str_error(opResult));
203 return opResult;
204 }
205 if (!endpoint_mapping[0].present) {
206 usb_log_error("Not accepting device, " \
207 "cannot understand what is happenning");
208 return EREFUSED;
209 }
210
211 free(descriptors);
212 return EOK;
213
214}
215
216
217/**
218 * Create hub representation from device information.
219 * @param device
220 * @return pointer to created structure or NULL in case of error
221 */
222usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
223 usb_hub_info_t* result = usb_new(usb_hub_info_t);
224 result->device = device;
225 int opResult;
226 opResult = usb_hub_init_communication(result);
227 if(opResult != EOK){
228 free(result);
229 return NULL;
230 }
231
232 //result->device = device;
233 result->port_count = -1;
234 result->device = device;
235 result->is_default_address_used = false;
236
237 //result->usb_device = usb_new(usb_hcd_attached_device_info_t);
238 size_t received_size;
239
240 // get hub descriptor
241 usb_log_debug("creating serialized descripton");
242 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
243 usb_hub_descriptor_t * descriptor;
244 usb_log_debug("starting control transaction");
245 usb_endpoint_pipe_start_session(&result->endpoints.control);
246 opResult = usb_request_set_configuration(&result->endpoints.control, 1);
247 assert(opResult == EOK);
248
249 opResult = usb_request_get_descriptor(&result->endpoints.control,
250 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
251 USB_DESCTYPE_HUB,
252 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 usb_log_error("failed when receiving hub descriptor, badcode = %d",
258 opResult);
259 free(serialized_descriptor);
260 free(result);
261 return NULL;
262 }
263 usb_log_debug2("deserializing descriptor");
264 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
265 if(descriptor==NULL){
266 usb_log_warning("could not deserialize descriptor ");
267 free(result);
268 return NULL;
269 }
270
271 usb_log_info("setting port count to %d",descriptor->ports_count);
272 result->port_count = descriptor->ports_count;
273 result->attached_devs = (usb_hc_attached_device_t*)
274 malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t));
275 int i;
276 for(i=0;i<result->port_count+1;++i){
277 result->attached_devs[i].handle=0;
278 result->attached_devs[i].address=0;
279 }
280 usb_log_debug2("freeing data");
281 free(serialized_descriptor);
282 free(descriptor->devices_removable);
283 free(descriptor);
284
285 //finish
286
287 usb_log_info("hub info created");
288
289 return result;
290}
291
292/**
293 * Create hub representation and add it into hub list
294 * @param dev
295 * @return
296 */
297int usb_add_hub_device(ddf_dev_t *dev) {
298 usb_log_info("add_hub_device(handle=%d)", (int) dev->handle);
299
300 //dev->ops = &hub_device_ops;
301 (void) hub_device_ops;
302
303 usb_hub_info_t * hub_info = usb_create_hub_info(dev);
304 if(!hub_info){
305 return EINTR;
306 }
307
308 int opResult;
309
310 //perform final configurations
311 usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
312 // process descriptors
313 opResult = usb_hub_process_configuration_descriptors(hub_info);
314 if(opResult != EOK){
315 usb_log_error("could not get configuration descriptors, %d",
316 opResult);
317 return opResult;
318 }
319 //power ports
320 usb_device_request_setup_packet_t request;
321 int port;
322 for (port = 1; port < hub_info->port_count+1; ++port) {
323 usb_hub_set_power_port_request(&request, port);
324 opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control,
325 &request,sizeof(usb_device_request_setup_packet_t), NULL, 0);
326 usb_log_info("powering port %d",port);
327 if (opResult != EOK) {
328 usb_log_warning("something went wrong when setting hub`s %dth port", port);
329 }
330 }
331 //ports powered, hub seems to be enabled
332 usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
333
334 //add the hub to list
335 //is this needed now?
336 fibril_mutex_lock(&usb_hub_list_lock);
337 usb_lst_append(&usb_hub_list, hub_info);
338 fibril_mutex_unlock(&usb_hub_list_lock);
339 usb_log_debug("hub info added to list");
340
341 usb_log_debug("adding to ddf");
342 ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub");
343 assert(hub_fun != NULL);
344 hub_fun->ops = NULL;
345
346 int rc = ddf_fun_bind(hub_fun);
347 assert(rc == EOK);
348 rc = ddf_fun_add_to_class(hub_fun, "hub");
349 assert(rc == EOK);
350
351 fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
352 if (fid == 0) {
353 usb_log_error("failed to start monitoring fibril for new hub");
354 return ENOMEM;
355 }
356 fibril_add_ready(fid);
357
358 usb_log_debug("hub fibril created");
359 //(void)hub_info;
360 //usb_hub_check_hub_changes();
361
362 usb_log_info("hub dev added");
363 //address is lost...
364 usb_log_debug("\taddress %d, has %d ports ",
365 //hub_info->endpoints.control.,
366 hub_info->port_count);
367
368 return EOK;
369 //return ENOTSUP;
370}
371
372
373//*********************************************
374//
375// hub driver code, main loop
376//
377//*********************************************
378
379/**
380 * release default address used by given hub
381 *
382 * Also unsets hub->is_default_address_used. Convenience wrapper function.
383 * @note hub->connection MUST be open for communication
384 * @param hub hub representation
385 * @return error code
386 */
387static int usb_hub_release_default_address(usb_hub_info_t * hub){
388 int opResult = usb_hc_release_default_address(&hub->connection);
389 if(opResult!=EOK){
390 usb_log_error("could not release default address, errno %d",opResult);
391 return opResult;
392 }
393 hub->is_default_address_used = false;
394 return EOK;
395}
396
397/**
398 * Reset the port with new device and reserve the default address.
399 * @param hc
400 * @param port
401 * @param target
402 */
403static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
404 usb_speed_t speed) {
405 //if this hub already uses default address, it cannot request it once more
406 if(hub->is_default_address_used) return;
407 int opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
408 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
409 if(opResult != EOK){
410 usb_log_warning("could not clear port-change-connection flag");
411 }
412
413 usb_device_request_setup_packet_t request;
414 usb_log_info("some connection changed");
415 assert(hub->endpoints.control.hc_phone);
416 //get default address
417 opResult = usb_hc_reserve_default_address(&hub->connection, speed);
418
419 if (opResult != EOK) {
420 usb_log_warning("cannot assign default address, it is probably used %d",
421 opResult);
422 return;
423 }
424 hub->is_default_address_used = true;
425 //reset port
426 usb_hub_set_reset_port_request(&request, port);
427 opResult = usb_endpoint_pipe_control_write(
428 &hub->endpoints.control,
429 &request,sizeof(usb_device_request_setup_packet_t),
430 NULL, 0
431 );
432 if (opResult != EOK) {
433 usb_log_error("something went wrong when reseting a port %d",opResult);
434 //usb_hub_release_default_address(hc);
435 usb_hub_release_default_address(hub);
436 }
437 return;
438}
439
440/**
441 * Finalize adding new device after port reset
442 * @param hc
443 * @param port
444 * @param target
445 */
446static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
447 uint16_t port, bool isLowSpeed) {
448
449 int opResult;
450 usb_log_info("finalizing add device");
451 opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
452 port, USB_HUB_FEATURE_C_PORT_RESET);
453
454 if (opResult != EOK) {
455 usb_log_error("failed to clear port reset feature");
456 usb_hub_release_default_address(hub);
457 return;
458 }
459 //create connection to device
460 usb_endpoint_pipe_t new_device_pipe;
461 usb_device_connection_t new_device_connection;
462 usb_device_connection_initialize_on_default_address(
463 &new_device_connection,
464 &hub->connection
465 );
466 usb_endpoint_pipe_initialize_default_control(
467 &new_device_pipe,
468 &new_device_connection);
469 usb_endpoint_pipe_probe_default_control(&new_device_pipe);
470 /// \TODO get highspeed info
471 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
472
473
474 /* Request address from host controller. */
475 usb_address_t new_device_address = usb_hc_request_address(
476 &hub->connection,
477 speed
478 );
479 if (new_device_address < 0) {
480 usb_log_error("failed to get free USB address");
481 opResult = new_device_address;
482 usb_hub_release_default_address(hub);
483 return;
484 }
485 usb_log_info("setting new address %d",new_device_address);
486 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
487 // new_device_address);
488 usb_endpoint_pipe_start_session(&new_device_pipe);
489 opResult = usb_request_set_address(&new_device_pipe,new_device_address);
490 usb_endpoint_pipe_end_session(&new_device_pipe);
491 if (opResult != EOK) {
492 usb_log_error("could not set address for new device %d",opResult);
493 usb_hub_release_default_address(hub);
494 return;
495 }
496
497
498 //opResult = usb_hub_release_default_address(hc);
499 opResult = usb_hub_release_default_address(hub);
500 if(opResult!=EOK){
501 return;
502 }
503
504 devman_handle_t child_handle;
505 //??
506 opResult = usb_device_register_child_in_devman(new_device_address,
507 hub->connection.hc_handle, hub->device, &child_handle,
508 NULL, NULL, NULL);
509
510 if (opResult != EOK) {
511 usb_log_error("could not start driver for new device %d",opResult);
512 return;
513 }
514 hub->attached_devs[port].handle = child_handle;
515 hub->attached_devs[port].address = new_device_address;
516
517 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
518 opResult = usb_hc_register_device(
519 &hub->connection,
520 &hub->attached_devs[port]);
521 if (opResult != EOK) {
522 usb_log_error("could not assign address of device in hcd %d",opResult);
523 return;
524 }
525 usb_log_info("new device address %d, handle %zu",
526 new_device_address, child_handle);
527
528}
529
530/**
531 * Unregister device address in hc
532 * @param hc
533 * @param port
534 * @param target
535 */
536static void usb_hub_removed_device(
537 usb_hub_info_t * hub,uint16_t port) {
538
539 int opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
540 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
541 if(opResult != EOK){
542 usb_log_warning("could not clear port-change-connection flag");
543 }
544 /** \TODO remove device from device manager - not yet implemented in
545 * devide manager
546 */
547
548 //close address
549 if(hub->attached_devs[port].address!=0){
550 /*uncomment this code to use it when DDF allows device removal
551 opResult = usb_hc_unregister_device(
552 &hub->connection, hub->attached_devs[port].address);
553 if(opResult != EOK) {
554 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
555 "removed device: %d", opResult);
556 }
557 hub->attached_devs[port].address = 0;
558 hub->attached_devs[port].handle = 0;
559 */
560 }else{
561 usb_log_warning("this is strange, disconnected device had no address");
562 //device was disconnected before it`s port was reset - return default address
563 usb_hub_release_default_address(hub);
564 }
565}
566
567
568/**
569 * Process over current condition on port.
570 *
571 * Turn off the power on the port.
572 *
573 * @param hub
574 * @param port
575 */
576static void usb_hub_over_current( usb_hub_info_t * hub,
577 uint16_t port){
578 int opResult;
579 opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
580 port, USB_HUB_FEATURE_PORT_POWER);
581 if(opResult!=EOK){
582 usb_log_error("cannot power off port %d; %d",
583 port, opResult);
584 }
585}
586
587/**
588 * Process interrupts on given hub port
589 * @param hc
590 * @param port
591 * @param target
592 */
593static void usb_hub_process_interrupt(usb_hub_info_t * hub,
594 uint16_t port) {
595 usb_log_debug("interrupt at port %d", port);
596 //determine type of change
597 usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
598
599 int opResult;
600
601 usb_port_status_t status;
602 size_t rcvd_size;
603 usb_device_request_setup_packet_t request;
604 //int opResult;
605 usb_hub_set_port_status_request(&request, port);
606 //endpoint 0
607
608 opResult = usb_endpoint_pipe_control_read(
609 pipe,
610 &request, sizeof(usb_device_request_setup_packet_t),
611 &status, 4, &rcvd_size
612 );
613 if (opResult != EOK) {
614 usb_log_error("could not get port status");
615 return;
616 }
617 if (rcvd_size != sizeof (usb_port_status_t)) {
618 usb_log_error("received status has incorrect size");
619 return;
620 }
621 //something connected/disconnected
622 if (usb_port_connect_change(&status)) {
623 if (usb_port_dev_connected(&status)) {
624 usb_log_info("some connection changed");
625 usb_hub_init_add_device(hub, port, usb_port_speed(&status));
626 } else {
627 usb_hub_removed_device(hub, port);
628 }
629 }
630 //over current
631 if (usb_port_overcurrent_change(&status)) {
632 //check if it was not auto-resolved
633 if(usb_port_over_current(&status)){
634 usb_hub_over_current(hub,port);
635 }else{
636 usb_log_info("over current condition was auto-resolved on port %d",
637 port);
638 }
639 }
640 //port reset
641 if (usb_port_reset_completed(&status)) {
642 usb_log_info("port reset complete");
643 if (usb_port_enabled(&status)) {
644 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status));
645 } else {
646 usb_log_warning("port reset, but port still not enabled");
647 }
648 }
649
650 usb_port_set_connect_change(&status, false);
651 usb_port_set_reset(&status, false);
652 usb_port_set_reset_completed(&status, false);
653 usb_port_set_dev_connected(&status, false);
654 if (status>>16) {
655 usb_log_info("there was some unsupported change on port %d: %X",
656 port,status);
657
658 }
659 /// \TODO handle other changes - is there any?
660}
661
662/**
663 * Check changes on particular hub
664 * @param hub_info_param pointer to usb_hub_info_t structure
665 * @return error code if there is problem when initializing communication with
666 * hub, EOK otherwise
667 */
668int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
669 int opResult;
670 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
671 if(opResult != EOK){
672 usb_log_error("could not initialize communication for hub; %d",
673 opResult);
674 return opResult;
675 }
676
677 size_t port_count = hub_info->port_count;
678
679 /// FIXME: count properly
680 size_t byte_length = ((port_count+1) / 8) + 1;
681 void *change_bitmap = malloc(byte_length);
682 size_t actual_size;
683
684 /*
685 * Send the request.
686 */
687 opResult = usb_endpoint_pipe_read(
688 &hub_info->endpoints.status_change,
689 change_bitmap, byte_length, &actual_size
690 );
691
692 if (opResult != EOK) {
693 free(change_bitmap);
694 usb_log_warning("something went wrong while getting status of hub");
695 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
696 return opResult;
697 }
698 unsigned int port;
699 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
700 if(opResult!=EOK){
701 usb_log_error("could not start control pipe session %d", opResult);
702 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
703 return opResult;
704 }
705 opResult = usb_hc_connection_open(&hub_info->connection);
706 if(opResult!=EOK){
707 usb_log_error("could not start host controller session %d",
708 opResult);
709 usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
710 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
711 return opResult;
712 }
713
714 ///todo, opresult check, pre obe konekce
715 for (port = 1; port < port_count+1; ++port) {
716 bool interrupt =
717 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
718 if (interrupt) {
719 usb_hub_process_interrupt(
720 hub_info, port);
721 }
722 }
723 usb_hc_connection_close(&hub_info->connection);
724 usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
725 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
726 free(change_bitmap);
727 return EOK;
728}
729
730
731
732/**
733 * @}
734 */
Note: See TracBrowser for help on using the repository browser.