Changeset a209648 in mainline for uspace/drv/usbhub/usbhub.c
- Timestamp:
- 2011-04-05T20:27:38Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e5ccfd1
- Parents:
- 3dba1ca
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
r3dba1ca ra209648 60 60 usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor); 61 61 62 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev); 63 64 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info); 65 66 static int usb_hub_set_configuration(usb_hub_info_t * hub_info); 67 68 69 static int usb_hub_trigger_connecting_non_removable_devices( 70 usb_hub_info_t * hub, 71 usb_hub_descriptor_t * descriptor); 72 73 static int usb_hub_release_default_address(usb_hub_info_t * hub); 74 75 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port, 76 usb_speed_t speed); 77 78 static void usb_hub_finalize_add_device(usb_hub_info_t * hub, 79 uint16_t port, usb_speed_t speed); 80 81 static void usb_hub_removed_device( 82 usb_hub_info_t * hub, uint16_t port); 83 84 static void usb_hub_port_over_current(usb_hub_info_t * hub, 85 uint16_t port, uint32_t status); 86 87 static void usb_hub_process_interrupt(usb_hub_info_t * hub, 88 uint16_t port); 89 90 static int usb_process_hub_over_current(usb_hub_info_t * hub_info, 91 usb_hub_status_t status); 92 93 static int usb_process_hub_power_change(usb_hub_info_t * hub_info, 94 usb_hub_status_t status); 95 96 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info); 97 98 static int initialize_non_removable(usb_hub_info_t * hub_info, 99 unsigned int port); 100 62 101 /** 63 102 * control loop running in hub`s fibril … … 89 128 // 90 129 // hub driver code, initialization 130 // 131 //********************************************* 132 133 134 135 /** 136 * Initialize hub device driver fibril 137 * 138 * Creates hub representation and fibril that periodically checks hub`s status. 139 * Hub representation is passed to the fibril. 140 * @param usb_dev generic usb device information 141 * @return error code 142 */ 143 int usb_hub_add_device(usb_device_t * usb_dev) { 144 if (!usb_dev) return EINVAL; 145 usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev); 146 //create hc connection 147 usb_log_debug("Initializing USB wire abstraction.\n"); 148 int opResult = usb_hc_connection_initialize_from_device( 149 &hub_info->connection, 150 hub_info->usb_device->ddf_dev); 151 if (opResult != EOK) { 152 usb_log_error("could not initialize connection to device, " 153 "errno %d\n", 154 opResult); 155 free(hub_info); 156 return opResult; 157 } 158 159 usb_pipe_start_session(hub_info->control_pipe); 160 //set hub configuration 161 opResult = usb_hub_set_configuration(hub_info); 162 if (opResult != EOK) { 163 usb_log_error("could not set hub configuration, errno %d\n", 164 opResult); 165 free(hub_info); 166 return opResult; 167 } 168 //get port count and create attached_devs 169 opResult = usb_hub_process_hub_specific_info(hub_info); 170 if (opResult != EOK) { 171 usb_log_error("could not set hub configuration, errno %d\n", 172 opResult); 173 free(hub_info); 174 return opResult; 175 } 176 usb_pipe_end_session(hub_info->control_pipe); 177 178 179 /// \TODO what is this? 180 usb_log_debug("Creating `hub' function.\n"); 181 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev, 182 fun_exposed, "hub"); 183 assert(hub_fun != NULL); 184 hub_fun->ops = NULL; 185 186 int rc = ddf_fun_bind(hub_fun); 187 assert(rc == EOK); 188 rc = ddf_fun_add_to_class(hub_fun, "hub"); 189 assert(rc == EOK); 190 191 //create fibril for the hub control loop 192 fid_t fid = fibril_create(usb_hub_control_loop, hub_info); 193 if (fid == 0) { 194 usb_log_error("failed to start monitoring fibril for new" 195 " hub.\n"); 196 return ENOMEM; 197 } 198 fibril_add_ready(fid); 199 usb_log_debug("Hub fibril created.\n"); 200 201 usb_log_info("Controlling hub `%s' (%d ports).\n", 202 hub_info->usb_device->ddf_dev->name, hub_info->port_count); 203 return EOK; 204 } 205 206 207 //********************************************* 208 // 209 // hub driver code, main loop and port handling 210 // 211 //********************************************* 212 213 /** 214 * check changes on hub 215 * 216 * Handles changes on each port with a status change. 217 * @param hub_info hub representation 218 * @return error code 219 */ 220 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) { 221 int opResult; 222 opResult = usb_pipe_start_session( 223 hub_info->status_change_pipe); 224 //this might not be necessary - if all non-removables are ok, it is 225 //not needed here 226 opResult = usb_pipe_start_session(hub_info->control_pipe); 227 if (opResult != EOK) { 228 usb_log_error("could not initialize communication for hub; %d\n", 229 opResult); 230 return opResult; 231 } 232 233 size_t port_count = hub_info->port_count; 234 //first check non-removable devices 235 { 236 unsigned int port; 237 for (port = 1; port <= port_count; ++port) { 238 bool is_non_removable = 239 hub_info->not_initialized_non_removables[port/8] 240 & (1 << (port % 8)); 241 if (is_non_removable) { 242 opResult = initialize_non_removable(hub_info, 243 port); 244 } 245 } 246 } 247 248 249 /// FIXME: count properly 250 size_t byte_length = ((port_count + 1) / 8) + 1; 251 void *change_bitmap = malloc(byte_length); 252 size_t actual_size; 253 254 /* 255 * Send the request. 256 */ 257 opResult = usb_pipe_read( 258 hub_info->status_change_pipe, 259 change_bitmap, byte_length, &actual_size 260 ); 261 262 if (opResult != EOK) { 263 free(change_bitmap); 264 usb_log_warning("something went wrong while getting the" 265 "status of hub\n"); 266 usb_pipe_end_session(hub_info->status_change_pipe); 267 return opResult; 268 } 269 unsigned int port; 270 271 if (opResult != EOK) { 272 usb_log_error("could not start control pipe session %d\n", 273 opResult); 274 usb_pipe_end_session(hub_info->status_change_pipe); 275 return opResult; 276 } 277 opResult = usb_hc_connection_open(&hub_info->connection); 278 if (opResult != EOK) { 279 usb_log_error("could not start host controller session %d\n", 280 opResult); 281 usb_pipe_end_session(hub_info->control_pipe); 282 usb_pipe_end_session(hub_info->status_change_pipe); 283 return opResult; 284 } 285 286 ///todo, opresult check, pre obe konekce 287 bool interrupt; 288 interrupt = ((uint8_t*)change_bitmap)[0] & 1; 289 if(interrupt){ 290 usb_hub_process_global_interrupt(hub_info); 291 } 292 for (port = 1; port < port_count + 1; ++port) { 293 interrupt = 294 ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8)); 295 if (interrupt) { 296 usb_hub_process_interrupt( 297 hub_info, port); 298 } 299 } 300 /// \todo check hub status 301 usb_hc_connection_close(&hub_info->connection); 302 usb_pipe_end_session(hub_info->control_pipe); 303 usb_pipe_end_session(hub_info->status_change_pipe); 304 free(change_bitmap); 305 return EOK; 306 } 307 308 //********************************************* 309 // 310 // support functions 91 311 // 92 312 //********************************************* … … 108 328 return result; 109 329 } 330 110 331 111 332 /** … … 226 447 } 227 448 228 /**229 * Initialize hub device driver fibril230 *231 * Creates hub representation and fibril that periodically checks hub`s status.232 * Hub representation is passed to the fibril.233 * @param usb_dev generic usb device information234 * @return error code235 */236 int usb_hub_add_device(usb_device_t * usb_dev) {237 if (!usb_dev) return EINVAL;238 usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);239 //create hc connection240 usb_log_debug("Initializing USB wire abstraction.\n");241 int opResult = usb_hc_connection_initialize_from_device(242 &hub_info->connection,243 hub_info->usb_device->ddf_dev);244 if (opResult != EOK) {245 usb_log_error("could not initialize connection to device, "246 "errno %d\n",247 opResult);248 free(hub_info);249 return opResult;250 }251 252 usb_pipe_start_session(hub_info->control_pipe);253 //set hub configuration254 opResult = usb_hub_set_configuration(hub_info);255 if (opResult != EOK) {256 usb_log_error("could not set hub configuration, errno %d\n",257 opResult);258 free(hub_info);259 return opResult;260 }261 //get port count and create attached_devs262 opResult = usb_hub_process_hub_specific_info(hub_info);263 if (opResult != EOK) {264 usb_log_error("could not set hub configuration, errno %d\n",265 opResult);266 free(hub_info);267 return opResult;268 }269 usb_pipe_end_session(hub_info->control_pipe);270 271 272 /// \TODO what is this?273 usb_log_debug("Creating `hub' function.\n");274 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,275 fun_exposed, "hub");276 assert(hub_fun != NULL);277 hub_fun->ops = NULL;278 279 int rc = ddf_fun_bind(hub_fun);280 assert(rc == EOK);281 rc = ddf_fun_add_to_class(hub_fun, "hub");282 assert(rc == EOK);283 284 //create fibril for the hub control loop285 fid_t fid = fibril_create(usb_hub_control_loop, hub_info);286 if (fid == 0) {287 usb_log_error("failed to start monitoring fibril for new"288 " hub.\n");289 return ENOMEM;290 }291 fibril_add_ready(fid);292 usb_log_debug("Hub fibril created.\n");293 294 usb_log_info("Controlling hub `%s' (%d ports).\n",295 hub_info->usb_device->ddf_dev->name, hub_info->port_count);296 return EOK;297 }298 299 300 //*********************************************301 //302 // hub driver code, main loop and port handling303 //304 //*********************************************305 449 306 450 /** … … 875 1019 /** 876 1020 * this is an attempt to initialize non-removable devices in the hub 877 * 1021 * 878 1022 * @param hub_info hub instance 879 1023 * @param port port number, counting from 1 … … 917 1061 } 918 1062 919 /**920 * check changes on hub921 *922 * Handles changes on each port with a status change.923 * @param hub_info hub representation924 * @return error code925 */926 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) {927 int opResult;928 opResult = usb_pipe_start_session(929 hub_info->status_change_pipe);930 //this might not be necessary - if all non-removables are ok, it is931 //not needed here932 opResult = usb_pipe_start_session(hub_info->control_pipe);933 if (opResult != EOK) {934 usb_log_error("could not initialize communication for hub; %d\n",935 opResult);936 return opResult;937 }938 939 size_t port_count = hub_info->port_count;940 //first check non-removable devices941 {942 unsigned int port;943 for (port = 1; port <= port_count; ++port) {944 bool is_non_removable =945 hub_info->not_initialized_non_removables[port/8]946 & (1 << (port % 8));947 if (is_non_removable) {948 opResult = initialize_non_removable(hub_info,949 port);950 }951 }952 }953 954 955 /// FIXME: count properly956 size_t byte_length = ((port_count + 1) / 8) + 1;957 void *change_bitmap = malloc(byte_length);958 size_t actual_size;959 960 /*961 * Send the request.962 */963 opResult = usb_pipe_read(964 hub_info->status_change_pipe,965 change_bitmap, byte_length, &actual_size966 );967 968 if (opResult != EOK) {969 free(change_bitmap);970 usb_log_warning("something went wrong while getting the"971 "status of hub\n");972 usb_pipe_end_session(hub_info->status_change_pipe);973 return opResult;974 }975 unsigned int port;976 977 if (opResult != EOK) {978 usb_log_error("could not start control pipe session %d\n",979 opResult);980 usb_pipe_end_session(hub_info->status_change_pipe);981 return opResult;982 }983 opResult = usb_hc_connection_open(&hub_info->connection);984 if (opResult != EOK) {985 usb_log_error("could not start host controller session %d\n",986 opResult);987 usb_pipe_end_session(hub_info->control_pipe);988 usb_pipe_end_session(hub_info->status_change_pipe);989 return opResult;990 }991 992 ///todo, opresult check, pre obe konekce993 bool interrupt;994 interrupt = ((uint8_t*)change_bitmap)[0] & 1;995 if(interrupt){996 usb_hub_process_global_interrupt(hub_info);997 }998 for (port = 1; port < port_count + 1; ++port) {999 interrupt =1000 ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8));1001 if (interrupt) {1002 usb_hub_process_interrupt(1003 hub_info, port);1004 }1005 }1006 /// \todo check hub status1007 usb_hc_connection_close(&hub_info->connection);1008 usb_pipe_end_session(hub_info->control_pipe);1009 usb_pipe_end_session(hub_info->status_change_pipe);1010 free(change_bitmap);1011 return EOK;1012 }1013 1014 1063 1015 1064
Note:
See TracChangeset
for help on using the changeset viewer.