Changes in uspace/drv/uhci-rhd/port.c [275bf456:f123909] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-rhd/port.c
r275bf456 rf123909 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcirh 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver 33 */ 32 * @brief UHCI root hub port routines 33 */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 34 35 #include <errno.h> 35 36 #include <str_error.h> … … 37 38 38 39 #include <usb/usb.h> /* usb_address_t */ 39 #include <usb/usbdevice.h>40 40 #include <usb/hub.h> 41 #include <usb/request.h>42 41 #include <usb/debug.h> 43 #include <usb/recognise.h>44 42 45 43 #include "port.h" 46 #include "port_status.h"47 44 48 45 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed); … … 51 48 static int uhci_port_check(void *port); 52 49 static int uhci_port_reset_enable(int portno, void *arg); 53 /*----------------------------------------------------------------------------*/ 54 /** Initializes UHCI root hub port instance. 50 static void uhci_port_print_status( 51 uhci_port_t *port, const port_status_t value); 52 53 /** Register reading helper function. 54 * 55 * @param[in] port Structure to use. 56 * @return Error code. (Always EOK) 57 */ 58 static inline port_status_t uhci_port_read_status(uhci_port_t *port) 59 { 60 assert(port); 61 return pio_read_16(port->address); 62 } 63 /*----------------------------------------------------------------------------*/ 64 /** Register writing helper function. 65 * 66 * @param[in] port Structure to use. 67 * @param[in] value New register value. 68 * @return Error code. (Always EOK) 69 */ 70 static inline void uhci_port_write_status( 71 uhci_port_t *port, port_status_t value) 72 { 73 assert(port); 74 pio_write_16(port->address, value); 75 } 76 77 /*----------------------------------------------------------------------------*/ 78 /** Initialize UHCI root hub port instance. 55 79 * 56 80 * @param[in] port Memory structure to use. … … 61 85 * @return Error code. 62 86 * 63 * Starts the polling fibril.87 * Creates and starts the polling fibril. 64 88 */ 65 89 int uhci_port_init(uhci_port_t *port, … … 67 91 { 68 92 assert(port); 93 asprintf(&port->id_string, "Port (%p - %d)", port, number); 94 if (port->id_string == NULL) { 95 return ENOMEM; 96 } 69 97 70 98 port->address = address; … … 83 111 port->checker = fibril_create(uhci_port_check, port); 84 112 if (port->checker == 0) { 85 usb_log_error(" Port(%p - %d): failed to launch root hubfibril.",86 port-> address, port->number);113 usb_log_error("%s: failed to create polling fibril.", 114 port->id_string); 87 115 return ENOMEM; 88 116 } 89 117 90 118 fibril_add_ready(port->checker); 91 usb_log_debug(" Port(%p - %d): Added fibril. %x\n",92 port-> address, port->number, port->checker);93 return EOK; 94 } 95 /*----------------------------------------------------------------------------*/ 96 /** FinishesUHCI root hub port instance.119 usb_log_debug("%s: Started polling fibril(%x).\n", 120 port->id_string, port->checker); 121 return EOK; 122 } 123 /*----------------------------------------------------------------------------*/ 124 /** Cleanup UHCI root hub port instance. 97 125 * 98 126 * @param[in] port Memory structure to use. … … 102 130 void uhci_port_fini(uhci_port_t *port) 103 131 { 132 assert(port); 133 free(port->id_string); 104 134 /* TODO: Kill fibril here */ 105 135 return; … … 108 138 /** Periodically checks port status and reports new devices. 109 139 * 110 * @param[in] port Memorystructure to use.140 * @param[in] port Port structure to use. 111 141 * @return Error code. 112 142 */ … … 116 146 assert(instance); 117 147 118 /* Iteration count, for debug purposes only */119 unsigned count = 0;120 121 148 while (1) { 122 149 async_usleep(instance->wait_period_usec); 123 150 124 /* read register value */ 125 port_status_t port_status = port_status_read(instance->address); 126 127 /* debug print mutex */ 128 static fibril_mutex_t dbg_mtx = 129 FIBRIL_MUTEX_INITIALIZER(dbg_mtx); 130 fibril_mutex_lock(&dbg_mtx); 131 usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n", 132 instance->address, instance->number, port_status, count++); 133 // print_port_status(port_status); 134 fibril_mutex_unlock(&dbg_mtx); 151 /* Read register value */ 152 port_status_t port_status = uhci_port_read_status(instance); 153 154 /* Print the value if it's interesting */ 155 if (port_status & ~STATUS_ALWAYS_ONE) 156 uhci_port_print_status(instance, port_status); 135 157 136 158 if ((port_status & STATUS_CONNECTED_CHANGED) == 0) 137 159 continue; 138 160 139 usb_log_debug(" Port(%p - %d): Connected change detected: %x.\n",140 instance-> address, instance->number, port_status);161 usb_log_debug("%s: Connected change detected: %x.\n", 162 instance->id_string, port_status); 141 163 142 164 int rc = 143 165 usb_hc_connection_open(&instance->hc_connection); 144 166 if (rc != EOK) { 145 usb_log_error(" Port(%p - %d): Failed to connect to HC.",146 instance-> address, instance->number);167 usb_log_error("%s: Failed to connect to HC.", 168 instance->id_string); 147 169 continue; 148 170 } … … 150 172 /* Remove any old device */ 151 173 if (instance->attached_device) { 152 usb_log_debug2(" Port(%p - %d): Removing device.\n",153 instance-> address, instance->number);174 usb_log_debug2("%s: Removing device.\n", 175 instance->id_string); 154 176 uhci_port_remove_device(instance); 155 177 } … … 163 185 } else { 164 186 /* Write one to WC bits, to ack changes */ 165 port_status_write(instance->address, port_status);166 usb_log_debug(" Port(%p - %d): Change statusACK.\n",167 instance-> address, instance->number);187 uhci_port_write_status(instance, port_status); 188 usb_log_debug("%s: status change ACK.\n", 189 instance->id_string); 168 190 } 169 191 170 192 rc = usb_hc_connection_close(&instance->hc_connection); 171 193 if (rc != EOK) { 172 usb_log_error(" Port(%p - %d): Failed to disconnect.",173 instance-> address, instance->number);194 usb_log_error("%s: Failed to disconnect.", 195 instance->id_string); 174 196 } 175 197 } … … 182 204 * @param arg Pointer to uhci_port_t of port with the new device. 183 205 * @return Error code. 206 * 207 * Resets and enables the ub port. 184 208 */ 185 209 int uhci_port_reset_enable(int portno, void *arg) … … 187 211 uhci_port_t *port = (uhci_port_t *) arg; 188 212 189 usb_log_debug2("Port(%p - %d): new_device_enable_port.\n", 190 port->address, port->number); 213 usb_log_debug2("%s: new_device_enable_port.\n", port->id_string); 191 214 192 215 /* … … 196 219 async_usleep(100000); 197 220 198 199 /* The hub maintains the reset signal to that port for 10 ms 200 * (See Section 11.5.1.5) 221 /* 222 * Resets from root ports should be nominally 50ms 201 223 */ 202 224 { 203 usb_log_debug("Port(%p - %d): Reset Signal start.\n", 204 port->address, port->number); 205 port_status_t port_status = 206 port_status_read(port->address); 225 usb_log_debug("%s: Reset Signal start.\n", port->id_string); 226 port_status_t port_status = uhci_port_read_status(port); 207 227 port_status |= STATUS_IN_RESET; 208 port_status_write(port->address, port_status);209 async_usleep( 10000);210 port_status = port_status_read(port->address);228 uhci_port_write_status(port, port_status); 229 async_usleep(50000); 230 port_status = uhci_port_read_status(port); 211 231 port_status &= ~STATUS_IN_RESET; 212 port_status_write(port->address, port_status); 213 usb_log_debug("Port(%p - %d): Reset Signal stop.\n", 214 port->address, port->number); 215 } 232 uhci_port_write_status(port, port_status); 233 usb_log_debug("%s: Reset Signal stop.\n", port->id_string); 234 } 235 236 /* the reset recovery time 10ms */ 237 async_usleep(10000); 216 238 217 239 /* Enable the port. */ 218 240 uhci_port_set_enabled(port, true); 219 return EOK; 220 } 221 /*----------------------------------------------------------------------------*/ 222 /** Initializes and reports connected device. 223 * 224 * @param[in] port Memory structure to use. 241 242 return EOK; 243 } 244 /*----------------------------------------------------------------------------*/ 245 /** Initialize and report connected device. 246 * 247 * @param[in] port Port structure to use. 225 248 * @param[in] speed Detected speed. 226 249 * @return Error code. … … 233 256 assert(usb_hc_connection_is_opened(&port->hc_connection)); 234 257 235 usb_log_info("Port(%p-%d): Detected new device.\n", 236 port->address, port->number); 258 usb_log_info("%s: Detected new device.\n", port->id_string); 237 259 238 260 usb_address_t dev_addr; … … 242 264 243 265 if (rc != EOK) { 244 usb_log_error(" Port(%p-%d): Failed(%d) to add device: %s.\n",245 port-> address, port->number, rc, str_error(rc));266 usb_log_error("%s: Failed(%d) to add device: %s.\n", 267 port->id_string, rc, str_error(rc)); 246 268 uhci_port_set_enabled(port, false); 247 269 return rc; 248 270 } 249 271 250 usb_log_info(" Port(%p-%d): New device has address %d (handle %zu).\n",251 port-> address, port->number, dev_addr, port->attached_device);252 253 return EOK; 254 } 255 /*----------------------------------------------------------------------------*/ 256 /** Remove sdevice.272 usb_log_info("%s: New device has address %d (handle %zu).\n", 273 port->id_string, dev_addr, port->attached_device); 274 275 return EOK; 276 } 277 /*----------------------------------------------------------------------------*/ 278 /** Remove device. 257 279 * 258 280 * @param[in] port Memory structure to use. 259 281 * @return Error code. 260 282 * 261 * Does not work DDF does not support device removal. 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). 262 286 */ 263 287 int uhci_port_remove_device(uhci_port_t *port) 264 288 { 265 usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n", 266 port->address, port->number, (unsigned int)port->attached_device); 267 return EOK; 268 } 269 /*----------------------------------------------------------------------------*/ 270 /** Enables and disables port. 271 * 272 * @param[in] port Memory structure to use. 289 usb_log_error("%s: Don't know how to remove device %d.\n", 290 port->id_string, (unsigned int)port->attached_device); 291 return EOK; 292 } 293 /*----------------------------------------------------------------------------*/ 294 /** Enable or disable root hub port. 295 * 296 * @param[in] port Port structure to use. 297 * @param[in] enabled Port status to set. 273 298 * @return Error code. (Always EOK) 274 299 */ … … 278 303 279 304 /* Read register value */ 280 port_status_t port_status = port_status_read(port->address);305 port_status_t port_status = uhci_port_read_status(port); 281 306 282 307 /* Set enabled bit */ … … 288 313 289 314 /* Write new value. */ 290 port_status_write(port->address, port_status); 291 292 usb_log_info("Port(%p-%d): %sabled port.\n", 293 port->address, port->number, enabled ? "En" : "Dis"); 294 return EOK; 295 } 296 /*----------------------------------------------------------------------------*/ 315 uhci_port_write_status(port, port_status); 316 317 usb_log_info("%s: %sabled port.\n", 318 port->id_string, enabled ? "En" : "Dis"); 319 return EOK; 320 } 321 /*----------------------------------------------------------------------------*/ 322 /** Print the port status value in a human friendly way 323 * 324 * @param[in] port Port structure to use. 325 * @param[in] value Port register value to print. 326 * @return Error code. (Always EOK) 327 */ 328 void uhci_port_print_status(uhci_port_t *port, const port_status_t value) 329 { 330 assert(port); 331 usb_log_debug2("%s Port status(%#x):%s%s%s%s%s%s%s%s%s%s%s.\n", 332 port->id_string, value, 333 (value & STATUS_SUSPEND) ? " SUSPENDED," : "", 334 (value & STATUS_RESUME) ? " IN RESUME," : "", 335 (value & STATUS_IN_RESET) ? " IN RESET," : "", 336 (value & STATUS_LINE_D_MINUS) ? " VD-," : "", 337 (value & STATUS_LINE_D_PLUS) ? " VD+," : "", 338 (value & STATUS_LOW_SPEED) ? " LOWSPEED," : "", 339 (value & STATUS_ENABLED_CHANGED) ? " ENABLED-CHANGE," : "", 340 (value & STATUS_ENABLED) ? " ENABLED," : "", 341 (value & STATUS_CONNECTED_CHANGED) ? " CONNECTED-CHANGE," : "", 342 (value & STATUS_CONNECTED) ? " CONNECTED," : "", 343 (value & STATUS_ALWAYS_ONE) ? " ALWAYS ONE" : " ERROR: NO ALWAYS ONE" 344 ); 345 } 297 346 /** 298 347 * @}
Note:
See TracChangeset
for help on using the changeset viewer.