Changeset 0b90f49 in mainline
- Timestamp:
- 2018-01-12T11:32:53Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b233821
- Parents:
- 46c5dc2
- Location:
- uspace/drv/bus/usb/usbhub
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhub/usbhub.c
r46c5dc2 r0b90f49 89 89 bool was_error, void *data); 90 90 91 static bool usb_hub_polling_error_callback(usb_device_t *dev, int err_code, void *arg) 92 { 93 assert(dev); 94 assert(arg); 95 usb_hub_dev_t *hub = arg; 96 97 usb_log_error("Device %s polling error: %s", usb_device_get_name(dev), 98 str_error(err_code)); 99 100 /* Continue polling until the device is about to be removed. */ 101 return hub->running && !hub->poll_stop; 102 } 103 91 104 /** 92 105 * Initialize hub device driver structure. … … 110 123 hub_dev->pending_ops_count = 0; 111 124 hub_dev->running = false; 125 hub_dev->poll_stop = false; 112 126 fibril_mutex_initialize(&hub_dev->pending_ops_mutex); 127 fibril_mutex_initialize(&hub_dev->poll_guard); 113 128 fibril_condvar_initialize(&hub_dev->pending_ops_cv); 129 fibril_condvar_initialize(&hub_dev->poll_cv); 114 130 115 131 /* Set hub's first configuration. (There should be only one) */ … … 151 167 &hub_status_change_endpoint_description, 152 168 hub_port_changes_callback, ((hub_dev->port_count + 1 + 7) / 8), 153 -1, NULL, usb_hub_polling_terminated_callback, hub_dev); 169 -1, usb_hub_polling_error_callback, 170 usb_hub_polling_terminated_callback, hub_dev); 154 171 if (opResult != EOK) { 155 172 /* Function is already bound */ … … 176 193 int usb_hub_device_remove(usb_device_t *usb_dev) 177 194 { 178 /* TODO: Implement me! */ 195 assert(usb_dev); 196 usb_hub_dev_t *hub = usb_device_data_get(usb_dev); 197 assert(hub); 198 199 usb_log_info("(%p) USB hub will be removed.", hub); 200 201 /* Instruct the hub to stop once endpoints are unregistered. */ 202 hub->poll_stop = true; 179 203 return EOK; 180 204 } 181 205 206 static int usb_hub_cleanup(usb_hub_dev_t *hub) 207 { 208 assert(!hub->running); 209 210 for (size_t port = 0; port < hub->port_count; ++port) { 211 const int ret = usb_hub_port_fini(&hub->ports[port], hub); 212 if (ret != EOK) 213 return ret; 214 } 215 free(hub->ports); 216 217 const int ret = ddf_fun_unbind(hub->hub_fun); 218 if (ret != EOK) { 219 usb_log_error("(%p) Failed to unbind '%s' function: %s.", 220 hub, HUB_FNC_NAME, str_error(ret)); 221 return ret; 222 } 223 ddf_fun_destroy(hub->hub_fun); 224 225 usb_log_info("(%p) USB hub driver stopped and cleaned.", hub); 226 227 /* Device data (usb_hub_dev_t) will be freed by usbdev. */ 228 return EOK; 229 } 230 182 231 int usb_hub_device_removed(usb_device_t *usb_dev) 183 232 { 184 /* TODO: Implement me! */ 185 return EOK; 233 assert(usb_dev); 234 usb_hub_dev_t *hub = usb_device_data_get(usb_dev); 235 assert(hub); 236 237 usb_log_info("(%p) USB hub was removed, joining polling fibril.", hub); 238 239 /* Join polling fibril. */ 240 fibril_mutex_lock(&hub->poll_guard); 241 while (hub->running) 242 fibril_condvar_wait(&hub->poll_cv, &hub->poll_guard); 243 fibril_mutex_unlock(&hub->poll_guard); 244 245 usb_log_info("(%p) USB hub polling stopped, freeing memory.", hub); 246 247 /* Destroy hub. */ 248 return usb_hub_cleanup(hub); 186 249 } 187 250 … … 196 259 usb_hub_dev_t *hub = usb_device_data_get(usb_dev); 197 260 assert(hub); 261 262 hub->poll_stop = true; 263 usb_log_info("(%p) USB hub gone, joining polling fibril.", hub); 264 265 // TODO: Join the polling fibril in a better way? 198 266 unsigned tries = 10; 199 267 while (hub->running) { … … 206 274 } 207 275 208 assert(!hub->running); 209 210 for (size_t port = 0; port < hub->port_count; ++port) { 211 const int ret = usb_hub_port_fini(&hub->ports[port], hub); 212 if (ret != EOK) 213 return ret; 214 } 215 free(hub->ports); 216 217 const int ret = ddf_fun_unbind(hub->hub_fun); 218 if (ret != EOK) { 219 usb_log_error("(%p) Failed to unbind '%s' function: %s.", 220 hub, HUB_FNC_NAME, str_error(ret)); 221 return ret; 222 } 223 ddf_fun_destroy(hub->hub_fun); 224 225 usb_log_info("(%p) USB hub driver stopped and cleaned.", hub); 226 return EOK; 276 return usb_hub_cleanup(hub); 227 277 } 228 278 … … 534 584 fibril_mutex_unlock(&hub->pending_ops_mutex); 535 585 hub->running = false; 586 587 /* Signal polling end to joining thread. */ 588 fibril_mutex_lock(&hub->poll_guard); 589 fibril_condvar_signal(&hub->poll_cv); 590 fibril_mutex_unlock(&hub->poll_guard); 536 591 } 537 592 /** -
uspace/drv/bus/usb/usbhub/usbhub.h
r46c5dc2 r0b90f49 74 74 ddf_fun_t *hub_fun; 75 75 /** Status indicator */ 76 bool running;76 volatile bool running; 77 77 /** Hub supports port power switching. */ 78 78 bool power_switched; 79 79 /** Each port is switched individually. */ 80 80 bool per_port_power; 81 /** True if the device should stop running as soon as possible. */ 82 volatile bool poll_stop; 83 fibril_mutex_t poll_guard; 84 fibril_condvar_t poll_cv; 81 85 }; 82 86
Note:
See TracChangeset
for help on using the changeset viewer.