Changeset 00aece0 in mainline for uspace/drv/bus/usb/uhcirh/port.c
- Timestamp:
- 2012-02-18T16:47:38Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4449c6c
- Parents:
- bd5f3b7 (diff), f943dd3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhcirh/port.c
rbd5f3b7 r00aece0 37 37 #include <str_error.h> 38 38 #include <async.h> 39 #include <devman.h> 39 40 40 41 #include <usb/usb.h> /* usb_address_t */ 41 #include <usb/dev/hub.h> /* usb_hc_new_device_wrapper */42 42 #include <usb/debug.h> 43 43 44 44 #include "port.h" 45 45 46 #define MAX_ERROR_COUNT 5 47 46 48 static int uhci_port_check(void *port); 47 static int uhci_port_reset_enable( int portno,void *arg);49 static int uhci_port_reset_enable(void *arg); 48 50 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed); 49 51 static int uhci_port_remove_device(uhci_port_t *port); … … 100 102 port->number = number; 101 103 port->wait_period_usec = usec; 102 port->attached_device = 0; 104 port->attached_device.fun = NULL; 105 port->attached_device.address = -1; 103 106 port->rh = rh; 104 107 … … 150 153 assert(instance); 151 154 155 unsigned allowed_failures = MAX_ERROR_COUNT; 156 #define CHECK_RET_FAIL(ret, msg...) \ 157 if (ret != EOK) { \ 158 usb_log_error(msg); \ 159 if (!(allowed_failures-- > 0)) { \ 160 usb_log_fatal( \ 161 "Maximum number of failures reached, " \ 162 "bailing out.\n"); \ 163 return ret; \ 164 } \ 165 continue; \ 166 } else (void)0 167 152 168 while (1) { 153 169 async_usleep(instance->wait_period_usec); … … 167 183 instance->id_string, port_status); 168 184 185 int ret = usb_hc_connection_open(&instance->hc_connection); 186 CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n", 187 instance->id_string, str_error(ret)); 188 169 189 /* Remove any old device */ 170 if (instance->attached_device) { 171 usb_log_debug2("%s: Removing device.\n", 172 instance->id_string); 190 if (instance->attached_device.fun) { 173 191 uhci_port_remove_device(instance); 174 192 } 175 193 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 194 if ((port_status & STATUS_CONNECTED) != 0) { 185 /* New device */195 /* New device, this will take care of WC bits */ 186 196 const usb_speed_t speed = 187 197 ((port_status & STATUS_LOW_SPEED) != 0) ? … … 196 206 197 207 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 } 208 CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n", 209 instance->id_string, str_error(ret)); 202 210 } 203 211 return EOK; … … 212 220 * Resets and enables the ub port. 213 221 */ 214 int uhci_port_reset_enable( int portno,void *arg)222 int uhci_port_reset_enable(void *arg) 215 223 { 216 224 uhci_port_t *port = arg; … … 252 260 { 253 261 assert(port); 254 assert(usb_hc_connection_is_opened(&port->hc_connection));255 262 256 263 usb_log_debug("%s: Detected new device.\n", port->id_string); 257 264 258 int ret, count = 0; 259 usb_address_t dev_addr; 265 int ret, count = MAX_ERROR_COUNT; 260 266 do { 261 267 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); 268 speed, uhci_port_reset_enable, port, 269 &port->attached_device.address, NULL, NULL, 270 &port->attached_device.fun); 271 } while (ret != EOK && count-- > 0); 265 272 266 273 if (ret != EOK) { … … 271 278 } 272 279 273 usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n", 274 port->number, dev_addr, port->attached_device); 280 usb_log_info("%s: New device, address %d (handle %" PRIun ").\n", 281 port->id_string, port->attached_device.address, 282 port->attached_device.fun->handle); 275 283 return EOK; 276 284 } … … 278 286 /** Remove device. 279 287 * 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). 288 * @param[in] port Port instance to use. 289 * @return Error code. 286 290 */ 287 291 int uhci_port_remove_device(uhci_port_t *port) 288 292 { 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; 293 assert(port); 294 /* There is nothing to remove. */ 295 if (port->attached_device.fun == NULL) { 296 usb_log_warning("%s: Removed a ghost device.\n", 297 port->id_string); 298 assert(port->attached_device.address == -1); 299 return EOK; 300 } 301 302 usb_log_debug("%s: Removing device.\n", port->id_string); 303 304 /* Stop driver first */ 305 int ret = ddf_fun_unbind(port->attached_device.fun); 306 if (ret != EOK) { 307 usb_log_error("%s: Failed to remove child function: %s.\n", 308 port->id_string, str_error(ret)); 309 return ret; 310 } 311 ddf_fun_destroy(port->attached_device.fun); 312 port->attached_device.fun = NULL; 313 314 /* Driver stopped, free used address */ 315 ret = usb_hub_unregister_device(&port->hc_connection, 316 &port->attached_device); 317 if (ret != EOK) { 318 usb_log_error("%s: Failed to unregister address of removed " 319 "device: %s.\n", port->id_string, str_error(ret)); 320 return ret; 321 } 322 port->attached_device.address = -1; 323 324 usb_log_info("%s: Removed attached device.\n", port->id_string); 325 return EOK; 293 326 } 294 327 /*----------------------------------------------------------------------------*/
Note:
See TracChangeset
for help on using the changeset viewer.