Changeset 25696fea in mainline for uspace/drv/bus/usb/uhcirh/port.c
- Timestamp:
- 2011-10-15T20:05:00Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 22ceff3a
- Parents:
- 1ccc32f (diff), 721d4b6e (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
r1ccc32f r25696fea 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; … … 256 264 usb_log_debug("%s: Detected new device.\n", port->id_string); 257 265 258 int ret, count = 0; 259 usb_address_t dev_addr; 266 int ret, count = MAX_ERROR_COUNT; 260 267 do { 261 268 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); 269 speed, uhci_port_reset_enable, port, 270 &port->attached_device.address, NULL, NULL, 271 &port->attached_device.fun); 272 } while (ret != EOK && count-- > 0); 265 273 266 274 if (ret != EOK) { … … 271 279 } 272 280 273 usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n", 274 port->number, dev_addr, port->attached_device); 281 usb_log_info("%s: New device, address %d (handle %" PRIun ").\n", 282 port->id_string, port->attached_device.address, 283 port->attached_device.fun->handle); 275 284 return EOK; 276 285 } … … 278 287 /** Remove device. 279 288 * 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). 289 * @param[in] port Port instance to use. 290 * @return Error code. 286 291 */ 287 292 int uhci_port_remove_device(uhci_port_t *port) 288 293 { 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; 294 assert(port); 295 /* There is nothing to remove. */ 296 if (port->attached_device.fun == NULL) { 297 usb_log_warning("%s: Removed a ghost device.\n", 298 port->id_string); 299 assert(port->attached_device.address == -1); 300 return EOK; 301 } 302 303 usb_log_debug("%s: Removing device.\n", port->id_string); 304 305 /* Stop driver first */ 306 int ret = ddf_fun_unbind(port->attached_device.fun); 307 if (ret != EOK) { 308 usb_log_error("%s: Failed to remove child function: %s.\n", 309 port->id_string, str_error(ret)); 310 return ret; 311 } 312 ddf_fun_destroy(port->attached_device.fun); 313 port->attached_device.fun = NULL; 314 315 /* Driver stopped, free used address */ 316 ret = usb_hc_unregister_device(&port->hc_connection, 317 port->attached_device.address); 318 if (ret != EOK) { 319 usb_log_error("%s: Failed to unregister address of removed " 320 "device: %s.\n", port->id_string, str_error(ret)); 321 return ret; 322 } 323 port->attached_device.address = -1; 324 325 usb_log_info("%s: Removed attached device.\n", port->id_string); 326 return EOK; 293 327 } 294 328 /*----------------------------------------------------------------------------*/
Note:
See TracChangeset
for help on using the changeset viewer.