source: mainline/uspace/drv/usbhub/usbhub.c@ fbefd0e

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

USB drivers less verbose on info level

  • Property mode set to 100644
File size: 17.9 KB
RevLine 
[e080332]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 */
[281ebae]28/** @addtogroup drvusbhub
[e080332]29 * @{
30 */
31/** @file
32 * @brief usb hub main functionality
33 */
34
[eb1a2f4]35#include <ddf/driver.h>
[e080332]36#include <bool.h>
37#include <errno.h>
[4e8e1f5]38#include <str_error.h>
[e080332]39
[71ed4849]40#include <usb_iface.h>
[357a302]41#include <usb/ddfiface.h>
[e080332]42#include <usb/descriptor.h>
[4e8e1f5]43#include <usb/recognise.h>
[d81ef61c]44#include <usb/request.h>
[e080332]45#include <usb/classes/hub.h>
[cd4b184]46#include <stdio.h>
[e080332]47
48#include "usbhub.h"
49#include "usbhub_private.h"
50#include "port_status.h"
[f40a1e2]51#include "usb/usb.h"
[d81ef61c]52#include "usb/pipes.h"
[15b0432]53#include "usb/classes/classes.h"
[e080332]54
[cd4b184]55int usb_hub_control_loop(void * hub_info_param){
56 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
[42a3a57]57 int errorCode = EOK;
58
59 while(errorCode == EOK){
60 errorCode = usb_hub_check_hub_changes(hub_info);
[cd4b184]61 async_usleep(1000 * 1000 );/// \TODO proper number once
62 }
[09daa8b]63 usb_log_error("something in ctrl loop went wrong, errno %d\n",errorCode);
[b495a93]64
[cd4b184]65 return 0;
66}
67
[15b0432]68
[e080332]69//*********************************************
70//
71// hub driver code, initialization
72//
73//*********************************************
74
[15b0432]75/**
[09daa8b]76 * create usb_hub_info_t structure
77 *
78 * Does only basic copying of known information into new structure.
79 * @param usb_dev usb device structure
80 * @return basic usb_hub_info_t structure
[15b0432]81 */
[09daa8b]82static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
83 usb_hub_info_t * result = usb_new(usb_hub_info_t);
84 if(!result) return NULL;
85 result->usb_device = usb_dev;
86 result->status_change_pipe = usb_dev->pipes[0].pipe;
87 result->control_pipe = &usb_dev->ctrl_pipe;
88 result->is_default_address_used = false;
89 return result;
90}
91
92/**
93 * Load hub-specific information into hub_info structure.
94 *
95 * Particularly read port count and initialize structure holding port
96 * information.
97 * This function is hub-specific and should be run only after the hub is
98 * configured using usb_hub_set_configuration function.
99 * @param hub_info pointer to structure with usb hub data
100 * @return error code
101 */
102static int usb_hub_get_hub_specific_info(usb_hub_info_t * hub_info){
103 // get hub descriptor
104 usb_log_debug("creating serialized descriptor\n");
105 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
106 usb_hub_descriptor_t * descriptor;
107
108 /* this was one fix of some bug, should not be needed anymore
109 int opResult = usb_request_set_configuration(&result->endpoints.control, 1);
110 if(opResult!=EOK){
111 usb_log_error("could not set default configuration, errno %d",opResult);
[15b0432]112 return opResult;
113 }
[09daa8b]114 */
115 size_t received_size;
116 int opResult = usb_request_get_descriptor(&hub_info->usb_device->ctrl_pipe,
117 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
118 USB_DESCTYPE_HUB,
119 0, 0, serialized_descriptor,
120 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
121
122 if (opResult != EOK) {
123 usb_log_error("failed when receiving hub descriptor, badcode = %d\n",
[b495a93]124 opResult);
[09daa8b]125 free(serialized_descriptor);
[15b0432]126 return opResult;
127 }
[09daa8b]128 usb_log_debug2("deserializing descriptor\n");
129 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
130 if(descriptor==NULL){
131 usb_log_warning("could not deserialize descriptor \n");
[206f71a]132 return opResult;
[15b0432]133 }
[fbefd0e]134 usb_log_debug("setting port count to %d\n",descriptor->ports_count);
[09daa8b]135 hub_info->port_count = descriptor->ports_count;
136 hub_info->attached_devs = (usb_hc_attached_device_t*)
137 malloc((hub_info->port_count+1) * sizeof(usb_hc_attached_device_t));
138 int i;
139 for(i=0;i<hub_info->port_count+1;++i){
140 hub_info->attached_devs[i].handle=0;
141 hub_info->attached_devs[i].address=0;
[15b0432]142 }
[09daa8b]143 usb_log_debug2("freeing data\n");
144 free(serialized_descriptor);
145 free(descriptor->devices_removable);
146 free(descriptor);
[206f71a]147 return EOK;
[15b0432]148}
149/**
[09daa8b]150 * Set configuration of hub
151 *
152 * Check whether there is at least one configuration and sets the first one.
153 * This function should be run prior to running any hub-specific action.
154 * @param hub_info
[15b0432]155 * @return
156 */
[09daa8b]157static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
[15b0432]158 //device descriptor
[625f1ba]159 usb_standard_device_descriptor_t *std_descriptor
160 = &hub_info->usb_device->descriptors.device;
[fbefd0e]161 usb_log_debug("hub has %d configurations\n",
[625f1ba]162 std_descriptor->configuration_count);
163 if(std_descriptor->configuration_count<1){
[09daa8b]164 usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE\n");
[15b0432]165 //shouldn`t I return?
[625f1ba]166 //definitely
167 return EINVAL;
[15b0432]168 }
169
[d70e0a3c]170 usb_standard_configuration_descriptor_t *config_descriptor
[625f1ba]171 = (usb_standard_configuration_descriptor_t *)
172 hub_info->usb_device->descriptors.configuration;
[d70e0a3c]173
174 /* Set configuration. */
[625f1ba]175 int opResult = usb_request_set_configuration(
176 &hub_info->usb_device->ctrl_pipe,
[d70e0a3c]177 config_descriptor->configuration_number);
[15b0432]178
179 if (opResult != EOK) {
[d70e0a3c]180 usb_log_error("Failed to set hub configuration: %s.\n",
181 str_error(opResult));
[15b0432]182 return opResult;
183 }
[09daa8b]184 usb_log_debug("\tused configuration %d\n",
[d70e0a3c]185 config_descriptor->configuration_number);
[625f1ba]186
[15b0432]187 return EOK;
188}
189
190/**
[09daa8b]191 * Initialize hub device driver fibril
192 *
193 * Creates hub representation and fibril that periodically checks hub`s status.
194 * Hub representation is passed to the fibril.
195 * @param usb_dev generic usb device information
196 * @return error code
[15b0432]197 */
[09daa8b]198int usb_hub_add_device(usb_device_t * usb_dev){
199 if(!usb_dev) return EINVAL;
200 usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
201 //create hc connection
202 usb_log_debug("Initializing USB wire abstraction.\n");
203 int opResult = usb_hc_connection_initialize_from_device(
204 &hub_info->connection,
205 hub_info->usb_device->ddf_dev);
[15b0432]206 if(opResult != EOK){
[09daa8b]207 usb_log_error("could not initialize connection to device, errno %d\n",
[b495a93]208 opResult);
[09daa8b]209 free(hub_info);
210 return opResult;
[332f860]211 }
[09daa8b]212
[3954a63b]213 usb_pipe_start_session(hub_info->control_pipe);
[09daa8b]214 //set hub configuration
215 opResult = usb_hub_set_configuration(hub_info);
216 if(opResult!=EOK){
217 usb_log_error("could not set hub configuration, errno %d\n",opResult);
218 free(hub_info);
[e080332]219 return opResult;
220 }
[09daa8b]221 //get port count and create attached_devs
222 opResult = usb_hub_get_hub_specific_info(hub_info);
223 if(opResult!=EOK){
224 usb_log_error("could not set hub configuration, errno %d\n",opResult);
225 free(hub_info);
226 return opResult;
[e080332]227 }
[3954a63b]228 usb_pipe_end_session(hub_info->control_pipe);
[e080332]229
[cd4b184]230
[09daa8b]231 /// \TODO what is this?
[625f1ba]232 usb_log_debug("Creating `hub' function.\n");
[09daa8b]233 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
234 fun_exposed, "hub");
[cc34f32f]235 assert(hub_fun != NULL);
236 hub_fun->ops = NULL;
237
238 int rc = ddf_fun_bind(hub_fun);
239 assert(rc == EOK);
240 rc = ddf_fun_add_to_class(hub_fun, "hub");
241 assert(rc == EOK);
242
[09daa8b]243 //create fibril for the hub control loop
[cd4b184]244 fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
245 if (fid == 0) {
[625f1ba]246 usb_log_error("failed to start monitoring fibril for new hub.\n");
[cd4b184]247 return ENOMEM;
248 }
249 fibril_add_ready(fid);
[625f1ba]250 usb_log_debug("Hub fibril created.\n");
251
252 usb_log_info("Controlling hub `%s' (%d ports).\n",
253 hub_info->usb_device->ddf_dev->name, hub_info->port_count);
[e080332]254 return EOK;
255}
256
257
258//*********************************************
259//
260// hub driver code, main loop
261//
262//*********************************************
263
[a83e138]264/**
265 * release default address used by given hub
266 *
267 * Also unsets hub->is_default_address_used. Convenience wrapper function.
268 * @note hub->connection MUST be open for communication
269 * @param hub hub representation
270 * @return error code
271 */
272static int usb_hub_release_default_address(usb_hub_info_t * hub){
273 int opResult = usb_hc_release_default_address(&hub->connection);
274 if(opResult!=EOK){
[09daa8b]275 usb_log_error("could not release default address, errno %d\n",opResult);
[a83e138]276 return opResult;
277 }
278 hub->is_default_address_used = false;
279 return EOK;
280}
281
[e080332]282/**
[f40a1e2]283 * Reset the port with new device and reserve the default address.
[e080332]284 * @param hc
285 * @param port
286 * @param target
287 */
[42a3a57]288static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
[a7528a16]289 usb_speed_t speed) {
[a83e138]290 //if this hub already uses default address, it cannot request it once more
291 if(hub->is_default_address_used) return;
[fbefd0e]292 usb_log_debug("some connection changed\n");
[09daa8b]293 assert(hub->control_pipe->hc_phone);
294 int opResult = usb_hub_clear_port_feature(hub->control_pipe,
[e93e319]295 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
296 if(opResult != EOK){
[09daa8b]297 usb_log_warning("could not clear port-change-connection flag\n");
[e93e319]298 }
[e080332]299 usb_device_request_setup_packet_t request;
[09daa8b]300
[e080332]301 //get default address
[42a3a57]302 opResult = usb_hc_reserve_default_address(&hub->connection, speed);
[cd4b184]303
[e080332]304 if (opResult != EOK) {
[09daa8b]305 usb_log_warning("cannot assign default address, it is probably used %d\n",
[b495a93]306 opResult);
[e080332]307 return;
308 }
[a83e138]309 hub->is_default_address_used = true;
[e080332]310 //reset port
311 usb_hub_set_reset_port_request(&request, port);
[3954a63b]312 opResult = usb_pipe_control_write(
[09daa8b]313 hub->control_pipe,
[6bb83c7]314 &request,sizeof(usb_device_request_setup_packet_t),
[e080332]315 NULL, 0
316 );
317 if (opResult != EOK) {
[09daa8b]318 usb_log_error("something went wrong when reseting a port %d\n",opResult);
[6bb83c7]319 //usb_hub_release_default_address(hc);
[a83e138]320 usb_hub_release_default_address(hub);
[e080332]321 }
[e93e319]322 return;
[e080332]323}
324
325/**
[f40a1e2]326 * Finalize adding new device after port reset
[e080332]327 * @param hc
328 * @param port
329 * @param target
330 */
331static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
[09daa8b]332 uint16_t port, usb_speed_t speed) {
[e080332]333
334 int opResult;
[fbefd0e]335 usb_log_debug("finalizing add device\n");
[09daa8b]336 opResult = usb_hub_clear_port_feature(hub->control_pipe,
[e080332]337 port, USB_HUB_FEATURE_C_PORT_RESET);
[6bb83c7]338
[e080332]339 if (opResult != EOK) {
[09daa8b]340 usb_log_error("failed to clear port reset feature\n");
[a83e138]341 usb_hub_release_default_address(hub);
[e080332]342 return;
343 }
[6bb83c7]344 //create connection to device
[a372663]345 usb_pipe_t new_device_pipe;
[6bb83c7]346 usb_device_connection_t new_device_connection;
347 usb_device_connection_initialize_on_default_address(
348 &new_device_connection,
349 &hub->connection
350 );
[3954a63b]351 usb_pipe_initialize_default_control(
[6bb83c7]352 &new_device_pipe,
353 &new_device_connection);
[3954a63b]354 usb_pipe_probe_default_control(&new_device_pipe);
[6bb83c7]355
356 /* Request address from host controller. */
357 usb_address_t new_device_address = usb_hc_request_address(
358 &hub->connection,
[3e7b7cd]359 speed
[6bb83c7]360 );
[e080332]361 if (new_device_address < 0) {
[09daa8b]362 usb_log_error("failed to get free USB address\n");
[e080332]363 opResult = new_device_address;
[a83e138]364 usb_hub_release_default_address(hub);
[e080332]365 return;
366 }
[fbefd0e]367 usb_log_debug("setting new address %d\n",new_device_address);
[6bb83c7]368 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
369 // new_device_address);
[3954a63b]370 usb_pipe_start_session(&new_device_pipe);
[6bb83c7]371 opResult = usb_request_set_address(&new_device_pipe,new_device_address);
[3954a63b]372 usb_pipe_end_session(&new_device_pipe);
[e080332]373 if (opResult != EOK) {
[09daa8b]374 usb_log_error("could not set address for new device %d\n",opResult);
[a83e138]375 usb_hub_release_default_address(hub);
[e080332]376 return;
377 }
378
379
[6bb83c7]380 //opResult = usb_hub_release_default_address(hc);
[a83e138]381 opResult = usb_hub_release_default_address(hub);
[e080332]382 if(opResult!=EOK){
383 return;
384 }
385
386 devman_handle_t child_handle;
[6bb83c7]387 //??
388 opResult = usb_device_register_child_in_devman(new_device_address,
[09daa8b]389 hub->connection.hc_handle, hub->usb_device->ddf_dev, &child_handle,
[eb1a2f4]390 NULL, NULL, NULL);
[6bb83c7]391
[e080332]392 if (opResult != EOK) {
[09daa8b]393 usb_log_error("could not start driver for new device %d\n",opResult);
[e080332]394 return;
395 }
[6bb83c7]396 hub->attached_devs[port].handle = child_handle;
[e080332]397 hub->attached_devs[port].address = new_device_address;
398
[6bb83c7]399 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
400 opResult = usb_hc_register_device(
401 &hub->connection,
402 &hub->attached_devs[port]);
[e080332]403 if (opResult != EOK) {
[09daa8b]404 usb_log_error("could not assign address of device in hcd %d\n",opResult);
[e080332]405 return;
406 }
[fbefd0e]407 usb_log_info("Detected new device on `%s' (port %d), " \
408 "address %d (handle %llu).\n",
409 hub->usb_device->ddf_dev->name, (int) port,
[e080332]410 new_device_address, child_handle);
411}
412
413/**
[f40a1e2]414 * Unregister device address in hc
[e080332]415 * @param hc
416 * @param port
417 * @param target
418 */
419static void usb_hub_removed_device(
[6bb83c7]420 usb_hub_info_t * hub,uint16_t port) {
[e93e319]421
[09daa8b]422 int opResult = usb_hub_clear_port_feature(hub->control_pipe,
[e93e319]423 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
424 if(opResult != EOK){
[09daa8b]425 usb_log_warning("could not clear port-change-connection flag\n");
[e93e319]426 }
[f40a1e2]427 /** \TODO remove device from device manager - not yet implemented in
428 * devide manager
429 */
[6bb83c7]430
[e080332]431 //close address
432 if(hub->attached_devs[port].address!=0){
[42a3a57]433 /*uncomment this code to use it when DDF allows device removal
[6bb83c7]434 opResult = usb_hc_unregister_device(
435 &hub->connection, hub->attached_devs[port].address);
[e080332]436 if(opResult != EOK) {
[103a3626]437 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
[0cfc68f0]438 "removed device: %d", opResult);
[e080332]439 }
440 hub->attached_devs[port].address = 0;
[6bb83c7]441 hub->attached_devs[port].handle = 0;
[42a3a57]442 */
[e080332]443 }else{
[09daa8b]444 usb_log_warning("this is strange, disconnected device had no address\n");
[e080332]445 //device was disconnected before it`s port was reset - return default address
[a83e138]446 usb_hub_release_default_address(hub);
[e080332]447 }
448}
449
[cd4b184]450
451/**
[b495a93]452 * Process over current condition on port.
[cd4b184]453 *
454 * Turn off the power on the port.
455 *
456 * @param hub
457 * @param port
458 */
459static void usb_hub_over_current( usb_hub_info_t * hub,
460 uint16_t port){
461 int opResult;
[09daa8b]462 opResult = usb_hub_clear_port_feature(hub->control_pipe,
[cd4b184]463 port, USB_HUB_FEATURE_PORT_POWER);
464 if(opResult!=EOK){
[09daa8b]465 usb_log_error("cannot power off port %d; %d\n",
[cd4b184]466 port, opResult);
467 }
468}
469
[e080332]470/**
[f40a1e2]471 * Process interrupts on given hub port
[e080332]472 * @param hc
473 * @param port
474 * @param target
475 */
[d81ef61c]476static void usb_hub_process_interrupt(usb_hub_info_t * hub,
477 uint16_t port) {
[09daa8b]478 usb_log_debug("interrupt at port %d\n", port);
[e080332]479 //determine type of change
[a372663]480 usb_pipe_t *pipe = hub->control_pipe;
[6bb83c7]481
[cd4b184]482 int opResult;
[d81ef61c]483
[e080332]484 usb_port_status_t status;
485 size_t rcvd_size;
486 usb_device_request_setup_packet_t request;
[d81ef61c]487 //int opResult;
[e080332]488 usb_hub_set_port_status_request(&request, port);
489 //endpoint 0
490
[3954a63b]491 opResult = usb_pipe_control_read(
[d81ef61c]492 pipe,
493 &request, sizeof(usb_device_request_setup_packet_t),
[e080332]494 &status, 4, &rcvd_size
495 );
496 if (opResult != EOK) {
[09daa8b]497 usb_log_error("could not get port status\n");
[e080332]498 return;
499 }
500 if (rcvd_size != sizeof (usb_port_status_t)) {
[09daa8b]501 usb_log_error("received status has incorrect size\n");
[e080332]502 return;
503 }
504 //something connected/disconnected
505 if (usb_port_connect_change(&status)) {
506 if (usb_port_dev_connected(&status)) {
[fbefd0e]507 usb_log_debug("some connection changed\n");
[a7528a16]508 usb_hub_init_add_device(hub, port, usb_port_speed(&status));
[e080332]509 } else {
[d81ef61c]510 usb_hub_removed_device(hub, port);
[e080332]511 }
512 }
[cd4b184]513 //over current
514 if (usb_port_overcurrent_change(&status)) {
515 //check if it was not auto-resolved
516 if(usb_port_over_current(&status)){
517 usb_hub_over_current(hub,port);
518 }else{
[fbefd0e]519 usb_log_debug("over current condition was auto-resolved on port %d\n",
[b495a93]520 port);
[cd4b184]521 }
522 }
[e080332]523 //port reset
524 if (usb_port_reset_completed(&status)) {
[fbefd0e]525 usb_log_debug("port reset complete\n");
[e080332]526 if (usb_port_enabled(&status)) {
[09daa8b]527 usb_hub_finalize_add_device(hub, port, usb_port_speed(&status));
[e080332]528 } else {
[09daa8b]529 usb_log_warning("port reset, but port still not enabled\n");
[e080332]530 }
531 }
532
533 usb_port_set_connect_change(&status, false);
534 usb_port_set_reset(&status, false);
535 usb_port_set_reset_completed(&status, false);
536 usb_port_set_dev_connected(&status, false);
[f40a1e2]537 if (status>>16) {
[09daa8b]538 usb_log_info("there was some unsupported change on port %d: %X\n",
[b495a93]539 port,status);
[f40a1e2]540
[e080332]541 }
542}
543
[f40a1e2]544/**
[cd4b184]545 * Check changes on particular hub
[42a3a57]546 * @param hub_info_param pointer to usb_hub_info_t structure
547 * @return error code if there is problem when initializing communication with
548 * hub, EOK otherwise
[e080332]549 */
[42a3a57]550int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
[cd4b184]551 int opResult;
[3954a63b]552 opResult = usb_pipe_start_session(
[09daa8b]553 hub_info->status_change_pipe);
[cd4b184]554 if(opResult != EOK){
[09daa8b]555 usb_log_error("could not initialize communication for hub; %d\n",
[b495a93]556 opResult);
[42a3a57]557 return opResult;
[cd4b184]558 }
559
560 size_t port_count = hub_info->port_count;
[e080332]561
[cd4b184]562 /// FIXME: count properly
563 size_t byte_length = ((port_count+1) / 8) + 1;
[e080332]564 void *change_bitmap = malloc(byte_length);
[cd4b184]565 size_t actual_size;
[e080332]566
[cd4b184]567 /*
568 * Send the request.
569 */
[3954a63b]570 opResult = usb_pipe_read(
[09daa8b]571 hub_info->status_change_pipe,
[cd4b184]572 change_bitmap, byte_length, &actual_size
573 );
[e080332]574
[cd4b184]575 if (opResult != EOK) {
[5097bed4]576 free(change_bitmap);
[09daa8b]577 usb_log_warning("something went wrong while getting status of hub\n");
[3954a63b]578 usb_pipe_end_session(hub_info->status_change_pipe);
[42a3a57]579 return opResult;
[cd4b184]580 }
581 unsigned int port;
[3954a63b]582 opResult = usb_pipe_start_session(hub_info->control_pipe);
[dff940f8]583 if(opResult!=EOK){
[09daa8b]584 usb_log_error("could not start control pipe session %d\n", opResult);
[3954a63b]585 usb_pipe_end_session(hub_info->status_change_pipe);
[42a3a57]586 return opResult;
[dff940f8]587 }
588 opResult = usb_hc_connection_open(&hub_info->connection);
589 if(opResult!=EOK){
[09daa8b]590 usb_log_error("could not start host controller session %d\n",
[dff940f8]591 opResult);
[3954a63b]592 usb_pipe_end_session(hub_info->control_pipe);
593 usb_pipe_end_session(hub_info->status_change_pipe);
[42a3a57]594 return opResult;
[dff940f8]595 }
[cd4b184]596
597 ///todo, opresult check, pre obe konekce
598 for (port = 1; port < port_count+1; ++port) {
599 bool interrupt =
600 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
601 if (interrupt) {
602 usb_hub_process_interrupt(
603 hub_info, port);
604 }
605 }
606 usb_hc_connection_close(&hub_info->connection);
[3954a63b]607 usb_pipe_end_session(hub_info->control_pipe);
608 usb_pipe_end_session(hub_info->status_change_pipe);
[cd4b184]609 free(change_bitmap);
[42a3a57]610 return EOK;
[cd4b184]611}
[e080332]612
613
614
615/**
616 * @}
[71ed4849]617 */
Note: See TracBrowser for help on using the repository browser.