Changeset 442fa6b in mainline
- Timestamp:
- 2011-09-23T14:17:59Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3b617579
- Parents:
- c0587d90
- Location:
- uspace/drv/bus/usb/usbhub
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhub/port.c
rc0587d90 r442fa6b 54 54 }; 55 55 56 static void usb_hub_removed_device(usb_hub_info_t *hub, size_t port); 57 static void usb_hub_port_reset_completed(const usb_hub_info_t *hub, 58 size_t port, usb_port_status_t status); 59 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port, 60 usb_port_status_t *status); 56 static void usb_hub_port_removed_device(usb_hub_port_t *port); 57 static void usb_hub_port_reset_completed(usb_hub_port_t *port, 58 usb_port_status_t status); 59 static int get_port_status(usb_hub_port_t *port, usb_port_status_t *status); 61 60 static int enable_port_callback(int port_no, void *arg); 62 61 static int add_device_phase1_worker_fibril(void *arg); … … 73 72 * @return Operation result 74 73 */ 75 int usb_hub_ clear_port_feature(74 int usb_hub_port_clear_feature( 76 75 usb_hub_port_t *port, usb_hub_class_feature_t feature) 77 76 { … … 97 96 * @return Operation result 98 97 */ 99 int usb_hub_ set_port_feature(98 int usb_hub_port_set_feature( 100 99 usb_hub_port_t *port, usb_hub_class_feature_t feature) 101 100 { … … 111 110 sizeof(clear_request), NULL, 0); 112 111 } 113 112 /*----------------------------------------------------------------------------*/ 113 void usb_hub_port_reset_fail(usb_hub_port_t *port) 114 { 115 assert(port); 116 fibril_mutex_lock(&port->mutex); 117 port->reset_completed = true; 118 port->reset_okay = false; 119 fibril_condvar_broadcast(&port->reset_cv); 120 fibril_mutex_unlock(&port->mutex); 121 } 122 /*----------------------------------------------------------------------------*/ 114 123 /** 115 124 * Process interrupts on given hub port … … 119 128 * @param port port number, starting from 1 120 129 */ 121 void usb_hub_p rocess_port_interrupt(usb_hub_info_t *hub, size_t port)130 void usb_hub_port_process_interrupt(usb_hub_info_t *hub, size_t port) 122 131 { 123 132 usb_log_debug("Interrupt at port %zu\n", port); … … 125 134 usb_port_status_t status; 126 135 const int opResult = 127 get_port_status(&hub-> usb_device->ctrl_pipe, port, &status);136 get_port_status(&hub->ports[port], &status); 128 137 if (opResult != EOK) { 129 138 usb_log_error("Failed to get port %zu status: %s.\n", … … 140 149 /* ACK the change */ 141 150 const int opResult = 142 usb_hub_ clear_port_feature(&hub->ports[port],151 usb_hub_port_clear_feature(&hub->ports[port], 143 152 USB_HUB_FEATURE_C_PORT_CONNECTION); 144 153 if (opResult != EOK) { … … 157 166 } 158 167 } else { 159 usb_hub_ removed_device(hub, port);168 usb_hub_port_removed_device(&hub->ports[port]); 160 169 } 161 170 } … … 191 200 /* Port reset, set on port reset complete. */ 192 201 if (status & USB_HUB_PORT_C_STATUS_RESET) { 193 usb_hub_port_reset_completed( hub, port, status);202 usb_hub_port_reset_completed(&hub->ports[port], status); 194 203 } 195 204 … … 206 215 * @param port port number, starting from 1 207 216 */ 208 static void usb_hub_removed_device(usb_hub_info_t *hub, size_t port) 209 { 210 /** \TODO remove device from device manager - not yet implemented in 211 * devide manager 212 */ 213 usb_hub_port_t *the_port = hub->ports + port; 214 215 fibril_mutex_lock(&hub->port_mutex); 216 217 if (the_port->attached_device.address >= 0) { 217 static void usb_hub_port_removed_device(usb_hub_port_t *port) 218 { 219 assert(port); 220 // TODO remove device from device manager 221 222 223 if (port->attached_device.address >= 0) { 224 #if 0 218 225 usb_log_warning("Device unplug on `%s' (port %zu): " \ 219 226 "not implemented.\n", hub->usb_device->ddf_dev->name, 220 227 (size_t) port); 221 the_port->attached_device.address = -1; 222 the_port->attached_device.handle = 0; 228 #endif 229 fibril_mutex_lock(&port->mutex); 230 port->attached_device.address = -1; 231 port->attached_device.handle = 0; 232 fibril_mutex_unlock(&port->mutex); 223 233 } else { 224 234 usb_log_warning("Device removed before being registered.\n"); … … 229 239 * port reset callback from new device wrapper. 230 240 */ 231 fibril_mutex_lock(&the_port->reset_mutex); 232 the_port->reset_completed = true; 233 the_port->reset_okay = false; 234 fibril_condvar_broadcast(&the_port->reset_cv); 235 fibril_mutex_unlock(&the_port->reset_mutex); 236 } 237 238 fibril_mutex_unlock(&hub->port_mutex); 241 usb_hub_port_reset_fail(port); 242 } 239 243 } 240 244 … … 248 252 * @param status 249 253 */ 250 static void usb_hub_port_reset_completed( const usb_hub_info_t *hub,251 size_t port,usb_port_status_t status)252 { 253 usb_hub_port_t *the_port = hub->ports + port;254 fibril_mutex_lock(& the_port->reset_mutex);254 static void usb_hub_port_reset_completed(usb_hub_port_t *port, 255 usb_port_status_t status) 256 { 257 assert(port); 258 fibril_mutex_lock(&port->mutex); 255 259 /* Finalize device adding. */ 256 the_port->reset_completed = true;257 the_port->reset_okay = (status & USB_HUB_PORT_STATUS_ENABLED) != 0;258 259 if ( the_port->reset_okay) {260 usb_log_debug("Port %zu reset complete.\n", port );260 port->reset_completed = true; 261 port->reset_okay = (status & USB_HUB_PORT_STATUS_ENABLED) != 0; 262 263 if (port->reset_okay) { 264 usb_log_debug("Port %zu reset complete.\n", port->port_number); 261 265 } else { 262 266 usb_log_warning( 263 "Port %zu reset complete but port not enabled.\n", port); 264 } 265 fibril_condvar_broadcast(&the_port->reset_cv); 266 fibril_mutex_unlock(&the_port->reset_mutex); 267 "Port %zu reset complete but port not enabled.\n", 268 port->port_number); 269 } 270 fibril_condvar_broadcast(&port->reset_cv); 271 fibril_mutex_unlock(&port->mutex); 267 272 268 273 /* Clear the port reset change. */ 269 int rc = usb_hub_clear_port_feature(&hub->ports[port], 270 USB_HUB_FEATURE_C_PORT_RESET); 274 int rc = usb_hub_port_clear_feature(port, USB_HUB_FEATURE_C_PORT_RESET); 271 275 if (rc != EOK) { 272 usb_log_error("Failed to clear port %d reset feature: %s.\n", 273 port, str_error(rc)); 276 usb_log_error( 277 "Failed to clear port %d reset change feature: %s.\n", 278 port->port_number, str_error(rc)); 274 279 } 275 280 } … … 282 287 * @return Error code. 283 288 */ 284 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port, 285 usb_port_status_t *status) 286 { 287 size_t recv_size; 288 usb_port_status_t status_tmp; 289 static int get_port_status(usb_hub_port_t *port, usb_port_status_t *status) 290 { 291 assert(port); 289 292 /* USB hub specific GET_PORT_STATUS request. See USB Spec 11.16.2.6 290 293 * Generic GET_STATUS request cannot be used because of the difference … … 294 297 .request = USB_HUB_REQUEST_GET_STATUS, 295 298 .value = 0, 296 .index = port ,299 .index = port->port_number, 297 300 .length = sizeof(usb_port_status_t), 298 301 }; 299 300 const int rc = usb_pipe_control_read(ctrl_pipe, 302 size_t recv_size; 303 usb_port_status_t status_tmp; 304 305 const int rc = usb_pipe_control_read(port->control_pipe, 301 306 &request, sizeof(usb_device_request_setup_packet_t), 302 307 &status_tmp, sizeof(status_tmp), &recv_size); … … 329 334 usb_hub_port_t *port = arg; 330 335 const int rc = 331 usb_hub_ set_port_feature(port, USB_HUB_FEATURE_PORT_RESET);336 usb_hub_port_set_feature(port, USB_HUB_FEATURE_PORT_RESET); 332 337 if (rc != EOK) { 333 338 usb_log_warning("Port reset failed: %s.\n", str_error(rc)); … … 338 343 * Wait until reset completes. 339 344 */ 340 fibril_mutex_lock(&port-> reset_mutex);345 fibril_mutex_lock(&port->mutex); 341 346 while (!port->reset_completed) { 342 fibril_condvar_wait(&port->reset_cv, &port-> reset_mutex);343 } 344 fibril_mutex_unlock(&port-> reset_mutex);347 fibril_condvar_wait(&port->reset_cv, &port->mutex); 348 } 349 fibril_mutex_unlock(&port->mutex); 345 350 346 351 if (port->reset_okay) { … … 380 385 } 381 386 382 fibril_mutex_lock(&data->hub->port _mutex);387 fibril_mutex_lock(&data->hub->ports[data->port].mutex); 383 388 data->hub->ports[data->port].attached_device.handle = child_handle; 384 389 data->hub->ports[data->port].attached_device.address = new_address; 385 fibril_mutex_unlock(&data->hub->port _mutex);390 fibril_mutex_unlock(&data->hub->ports[data->port].mutex); 386 391 387 392 usb_log_info("Detected new device on `%s' (port %zu), " … … 426 431 usb_hub_port_t *the_port = hub->ports + port; 427 432 428 fibril_mutex_lock(&the_port-> reset_mutex);433 fibril_mutex_lock(&the_port->mutex); 429 434 the_port->reset_completed = false; 430 fibril_mutex_unlock(&the_port-> reset_mutex);435 fibril_mutex_unlock(&the_port->mutex); 431 436 432 437 fid_t fibril = fibril_create(add_device_phase1_worker_fibril, data); -
uspace/drv/bus/usb/usbhub/port.h
rc0587d90 r442fa6b 46 46 size_t port_number; 47 47 usb_pipe_t *control_pipe; 48 /** Mutex needed by CV for checking port reset. */49 fibril_mutex_t reset_mutex;48 /** Mutex needed not only by CV for checking port reset. */ 49 fibril_mutex_t mutex; 50 50 /** CV for waiting to port reset completion. */ 51 51 fibril_condvar_t reset_cv; … … 73 73 port->port_number = port_number; 74 74 port->control_pipe = control_pipe; 75 fibril_mutex_initialize(&port-> reset_mutex);75 fibril_mutex_initialize(&port->mutex); 76 76 fibril_condvar_initialize(&port->reset_cv); 77 77 } 78 78 79 void usb_hub_port_reset_fail(usb_hub_port_t *port); 79 80 80 void usb_hub_p rocess_port_interrupt(usb_hub_info_t *hub, size_t port);81 int usb_hub_ clear_port_feature(81 void usb_hub_port_process_interrupt(usb_hub_info_t *hub, size_t port); 82 int usb_hub_port_clear_feature( 82 83 usb_hub_port_t *port, usb_hub_class_feature_t feature); 83 int usb_hub_ set_port_feature(84 int usb_hub_port_set_feature( 84 85 usb_hub_port_t *port, usb_hub_class_feature_t feature); 85 86 -
uspace/drv/bus/usb/usbhub/usbhub.c
rc0587d90 r442fa6b 187 187 const bool change = (change_bitmap[port / 8] >> (port % 8)) & 1; 188 188 if (change) { 189 usb_hub_p rocess_port_interrupt(hub, port);189 usb_hub_port_process_interrupt(hub, port); 190 190 } 191 191 } … … 217 217 info->ports = NULL; 218 218 info->port_count = -1; 219 fibril_mutex_initialize(&info->port_mutex);220 219 fibril_mutex_initialize(&info->pending_ops_mutex); 221 220 fibril_condvar_initialize(&info->pending_ops_cv); … … 289 288 for (port = 1; port <= hub_info->port_count; ++port) { 290 289 usb_log_debug("Powering port %zu.\n", port); 291 opResult = usb_hub_ set_port_feature(290 opResult = usb_hub_port_set_feature( 292 291 &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER); 293 292 if (opResult != EOK) { … … 365 364 * switch them all off to prevent damage. */ 366 365 //TODO Consider ganged power switching here. 366 //TODO Hub should have turned the ports off already, 367 //this is redundant. 367 368 size_t port; 368 369 for (port = 1; port <= hub_info->port_count; ++port) { 369 const int opResult = usb_hub_ clear_port_feature(370 const int opResult = usb_hub_port_clear_feature( 370 371 &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER); 371 372 if (opResult != EOK) { … … 381 382 size_t port; 382 383 for (port = 1; port <= hub_info->port_count; ++port) { 383 const int opResult = usb_hub_ set_port_feature(384 const int opResult = usb_hub_port_set_feature( 384 385 &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER); 385 386 if (opResult != EOK) { … … 478 479 */ 479 480 if (hub->pending_ops_count > 0) { 480 fibril_mutex_lock(&hub->port_mutex);481 481 size_t port; 482 482 for (port = 0; port < hub->port_count; port++) { 483 usb_hub_port_t *the_port = hub->ports + port; 484 fibril_mutex_lock(&the_port->reset_mutex); 485 the_port->reset_completed = true; 486 the_port->reset_okay = false; 487 fibril_condvar_broadcast(&the_port->reset_cv); 488 fibril_mutex_unlock(&the_port->reset_mutex); 483 usb_hub_port_reset_fail(&hub->ports[port]); 489 484 } 490 fibril_mutex_unlock(&hub->port_mutex);491 485 } 492 486 /* And now wait for them. */ -
uspace/drv/bus/usb/usbhub/usbhub.h
rc0587d90 r442fa6b 59 59 usb_hub_port_t *ports; 60 60 61 fibril_mutex_t port_mutex;62 63 61 /** Connection to hcd */ 64 62 usb_hc_connection_t connection;
Note:
See TracChangeset
for help on using the changeset viewer.