Changes in uspace/drv/bus/usb/uhcirh/port.c [5203e256:e882e3a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhcirh/port.c
r5203e256 re882e3a 39 39 40 40 #include <usb/usb.h> /* usb_address_t */ 41 #include <usb/dev/hub.h> /* usb_hc_new_device_wrapper */42 41 #include <usb/debug.h> 43 42 44 43 #include "port.h" 45 44 45 #define MAX_ERROR_COUNT 5 46 46 47 static int uhci_port_check(void *port); 47 static int uhci_port_reset_enable( int portno,void *arg);48 static int uhci_port_reset_enable(void *arg); 48 49 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed); 49 50 static int uhci_port_remove_device(uhci_port_t *port); … … 100 101 port->number = number; 101 102 port->wait_period_usec = usec; 102 port->attached_device = 0; 103 port->attached_device.fun = NULL; 104 port->attached_device.address = -1; 103 105 port->rh = rh; 104 106 … … 150 152 assert(instance); 151 153 154 unsigned allowed_failures = MAX_ERROR_COUNT; 155 #define CHECK_RET_FAIL(ret, msg...) \ 156 if (ret != EOK) { \ 157 usb_log_error(msg); \ 158 if (!(allowed_failures-- > 0)) { \ 159 usb_log_fatal( \ 160 "Maximum number of failures reached, " \ 161 "bailing out.\n"); \ 162 return ret; \ 163 } \ 164 continue; \ 165 } else (void)0 166 152 167 while (1) { 153 168 async_usleep(instance->wait_period_usec); … … 167 182 instance->id_string, port_status); 168 183 184 int ret = usb_hc_connection_open(&instance->hc_connection); 185 CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n", 186 instance->id_string, str_error(ret)); 187 169 188 /* Remove any old device */ 170 if (instance->attached_device) { 171 usb_log_debug2("%s: Removing device.\n", 172 instance->id_string); 189 if (instance->attached_device.fun) { 173 190 uhci_port_remove_device(instance); 174 191 } 175 192 176 int ret =177 usb_hc_connection_open(&instance->hc_connection);178 if (ret != EOK) {179 usb_log_error("%s: Failed to connect to HC.",180 instance->id_string);181 continue;182 }183 184 193 if ((port_status & STATUS_CONNECTED) != 0) { 185 /* New device */194 /* New device, this will take care of WC bits */ 186 195 const usb_speed_t speed = 187 196 ((port_status & STATUS_LOW_SPEED) != 0) ? … … 196 205 197 206 ret = usb_hc_connection_close(&instance->hc_connection); 198 if (ret != EOK) { 199 usb_log_error("%s: Failed to disconnect.", 200 instance->id_string); 201 } 207 CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n", 208 instance->id_string, str_error(ret)); 202 209 } 203 210 return EOK; … … 212 219 * Resets and enables the ub port. 213 220 */ 214 int uhci_port_reset_enable( int portno,void *arg)221 int uhci_port_reset_enable(void *arg) 215 222 { 216 223 uhci_port_t *port = arg; … … 252 259 { 253 260 assert(port); 254 assert(usb_hc_connection_is_opened(&port->hc_connection));255 261 256 262 usb_log_debug("%s: Detected new device.\n", port->id_string); 257 263 258 int ret, count = 0; 259 usb_address_t dev_addr; 264 int ret, count = MAX_ERROR_COUNT; 260 265 do { 261 266 ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 262 speed, uhci_port_reset_enable, port->number, port, 263 &dev_addr, &port->attached_device, NULL, NULL, NULL); 264 } while (ret != EOK && ++count < 4); 267 speed, uhci_port_reset_enable, port, 268 &port->attached_device.address, NULL, NULL, 269 &port->attached_device.fun); 270 } while (ret != EOK && count-- > 0); 265 271 266 272 if (ret != EOK) { … … 271 277 } 272 278 273 usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n", 274 port->number, dev_addr, port->attached_device); 279 usb_log_info("%s: New device, address %d (handle %" PRIun ").\n", 280 port->id_string, port->attached_device.address, 281 port->attached_device.fun->handle); 275 282 return EOK; 276 283 } … … 278 285 /** Remove device. 279 286 * 280 * @param[in] port Memory structure to use. 281 * @return Error code. 282 * 283 * Does not work, DDF does not support device removal. 284 * Does not even free used USB address (it would be dangerous if tis driver 285 * is still running). 287 * @param[in] port Port instance to use. 288 * @return Error code. 286 289 */ 287 290 int uhci_port_remove_device(uhci_port_t *port) 288 291 { 289 usb_log_error("%s: Don't know how to remove device %" PRIun ".\n", 290 port->id_string, port->attached_device); 291 port->attached_device = 0; 292 return ENOTSUP; 292 assert(port); 293 /* There is nothing to remove. */ 294 if (port->attached_device.fun == NULL) { 295 usb_log_warning("%s: Removed a ghost device.\n", 296 port->id_string); 297 assert(port->attached_device.address == -1); 298 return EOK; 299 } 300 301 usb_log_debug("%s: Removing device.\n", port->id_string); 302 303 /* Stop driver first */ 304 int ret = ddf_fun_unbind(port->attached_device.fun); 305 if (ret != EOK) { 306 usb_log_error("%s: Failed to remove child function: %s.\n", 307 port->id_string, str_error(ret)); 308 return ret; 309 } 310 ddf_fun_destroy(port->attached_device.fun); 311 port->attached_device.fun = NULL; 312 313 /* Driver stopped, free used address */ 314 ret = usb_hub_unregister_device(&port->hc_connection, 315 &port->attached_device); 316 if (ret != EOK) { 317 usb_log_error("%s: Failed to unregister address of removed " 318 "device: %s.\n", port->id_string, str_error(ret)); 319 return ret; 320 } 321 port->attached_device.address = -1; 322 323 usb_log_info("%s: Removed attached device.\n", port->id_string); 324 return EOK; 293 325 } 294 326 /*----------------------------------------------------------------------------*/
Note:
See TracChangeset
for help on using the changeset viewer.