Changeset 275bf456 in mainline for uspace/drv/uhci-rhd/port.c
- Timestamp:
- 2011-03-07T16:02:26Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0d3167e
- Parents:
- 13927cf
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-rhd/port.c
r13927cf r275bf456 46 46 #include "port_status.h" 47 47 48 static int uhci_port_new_device(uhci_port_t *port, u int16_t status);48 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed); 49 49 static int uhci_port_remove_device(uhci_port_t *port); 50 50 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled); 51 51 static int uhci_port_check(void *port); 52 static int new_device_enable_port(int portno, void *arg); 53 54 int uhci_port_init( 55 uhci_port_t *port, port_status_t *address, unsigned number, 56 unsigned usec, ddf_dev_t *rh) 52 static int uhci_port_reset_enable(int portno, void *arg); 53 /*----------------------------------------------------------------------------*/ 54 /** Initializes UHCI root hub port instance. 55 * 56 * @param[in] port Memory structure to use. 57 * @param[in] addr Address of I/O register. 58 * @param[in] number Port number. 59 * @param[in] usec Polling interval. 60 * @param[in] rh Pointer to ddf instance fo the root hub driver. 61 * @return Error code. 62 * 63 * Starts the polling fibril. 64 */ 65 int uhci_port_init(uhci_port_t *port, 66 port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh) 57 67 { 58 68 assert(port); 69 59 70 port->address = address; 60 71 port->number = number; … … 62 73 port->attached_device = 0; 63 74 port->rh = rh; 75 64 76 int rc = usb_hc_connection_initialize_from_device( 65 77 &port->hc_connection, rh); … … 75 87 return ENOMEM; 76 88 } 89 77 90 fibril_add_ready(port->checker); 78 91 usb_log_debug("Port(%p - %d): Added fibril. %x\n", … … 81 94 } 82 95 /*----------------------------------------------------------------------------*/ 96 /** Finishes UHCI root hub port instance. 97 * 98 * @param[in] port Memory structure to use. 99 * 100 * Stops the polling fibril. 101 */ 83 102 void uhci_port_fini(uhci_port_t *port) 84 103 { 85 // TODO: destroy fibril 86 // TODO: hangup phone 87 // fibril_teardown(port->checker); 104 /* TODO: Kill fibril here */ 88 105 return; 89 106 } 90 107 /*----------------------------------------------------------------------------*/ 108 /** Periodically checks port status and reports new devices. 109 * 110 * @param[in] port Memory structure to use. 111 * @return Error code. 112 */ 91 113 int uhci_port_check(void *port) 92 114 { 93 uhci_port_t * port_instance = port;94 assert( port_instance);95 // port_status_write(port_instance->address, 0); 96 115 uhci_port_t *instance = port; 116 assert(instance); 117 118 /* Iteration count, for debug purposes only */ 97 119 unsigned count = 0; 98 120 99 121 while (1) { 100 async_usleep( port_instance->wait_period_usec);122 async_usleep(instance->wait_period_usec); 101 123 102 124 /* read register value */ 103 port_status_t port_status = 104 port_status_read(port_instance->address); 105 106 /* debug print */107 static fibril_mutex_t dbg_mtx =FIBRIL_MUTEX_INITIALIZER(dbg_mtx);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); 108 130 fibril_mutex_lock(&dbg_mtx); 109 131 usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n", 110 port_instance->address, port_instance->number, port_status, count++);132 instance->address, instance->number, port_status, count++); 111 133 // print_port_status(port_status); 112 134 fibril_mutex_unlock(&dbg_mtx); 113 135 114 if ((port_status & STATUS_CONNECTED_CHANGED) != 0) { 115 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n", 116 port_instance->address, port_instance->number, port_status); 117 118 119 int rc = usb_hc_connection_open( 120 &port_instance->hc_connection); 121 if (rc != EOK) { 122 usb_log_error("Port(%p - %d): Failed to connect to HC.", 123 port_instance->address, port_instance->number); 124 continue; 125 } 126 127 /* remove any old device */ 128 if (port_instance->attached_device) { 129 usb_log_debug("Port(%p - %d): Removing device.\n", 130 port_instance->address, port_instance->number); 131 uhci_port_remove_device(port_instance); 132 } 133 134 if ((port_status & STATUS_CONNECTED) != 0) { 135 /* new device */ 136 uhci_port_new_device(port_instance, port_status); 137 } else { 138 /* ack changes by writing one to WC bits */ 139 port_status_write(port_instance->address, port_status); 140 usb_log_debug("Port(%p - %d): Change status ACK.\n", 141 port_instance->address, port_instance->number); 142 } 143 144 rc = usb_hc_connection_close( 145 &port_instance->hc_connection); 146 if (rc != EOK) { 147 usb_log_error("Port(%p - %d): Failed to disconnect from HC.", 148 port_instance->address, port_instance->number); 149 } 150 } 151 } 152 return EOK; 153 } 154 136 if ((port_status & STATUS_CONNECTED_CHANGED) == 0) 137 continue; 138 139 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n", 140 instance->address, instance->number, port_status); 141 142 int rc = 143 usb_hc_connection_open(&instance->hc_connection); 144 if (rc != EOK) { 145 usb_log_error("Port(%p - %d): Failed to connect to HC.", 146 instance->address, instance->number); 147 continue; 148 } 149 150 /* Remove any old device */ 151 if (instance->attached_device) { 152 usb_log_debug2("Port(%p - %d): Removing device.\n", 153 instance->address, instance->number); 154 uhci_port_remove_device(instance); 155 } 156 157 if ((port_status & STATUS_CONNECTED) != 0) { 158 /* New device */ 159 const usb_speed_t speed = 160 ((port_status & STATUS_LOW_SPEED) != 0) ? 161 USB_SPEED_LOW : USB_SPEED_FULL; 162 uhci_port_new_device(instance, speed); 163 } else { 164 /* Write one to WC bits, to ack changes */ 165 port_status_write(instance->address, port_status); 166 usb_log_debug("Port(%p - %d): Change status ACK.\n", 167 instance->address, instance->number); 168 } 169 170 rc = usb_hc_connection_close(&instance->hc_connection); 171 if (rc != EOK) { 172 usb_log_error("Port(%p - %d): Failed to disconnect.", 173 instance->address, instance->number); 174 } 175 } 176 return EOK; 177 } 178 /*----------------------------------------------------------------------------*/ 155 179 /** Callback for enabling port during adding a new device. 156 180 * … … 159 183 * @return Error code. 160 184 */ 161 static int new_device_enable_port(int portno, void *arg)185 int uhci_port_reset_enable(int portno, void *arg) 162 186 { 163 187 uhci_port_t *port = (uhci_port_t *) arg; … … 184 208 port_status_write(port->address, port_status); 185 209 async_usleep(10000); 186 port_status = 187 port_status_read(port->address); 210 port_status = port_status_read(port->address); 188 211 port_status &= ~STATUS_IN_RESET; 189 212 port_status_write(port->address, port_status); … … 194 217 /* Enable the port. */ 195 218 uhci_port_set_enabled(port, true); 196 197 return EOK; 198 } 199 200 /*----------------------------------------------------------------------------*/ 201 static int uhci_port_new_device(uhci_port_t *port, uint16_t status) 219 return EOK; 220 } 221 /*----------------------------------------------------------------------------*/ 222 /** Initializes and reports connected device. 223 * 224 * @param[in] port Memory structure to use. 225 * @param[in] speed Detected speed. 226 * @return Error code. 227 * 228 * Uses libUSB function to do the actual work. 229 */ 230 int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed) 202 231 { 203 232 assert(port); … … 209 238 usb_address_t dev_addr; 210 239 int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 211 ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL, 212 new_device_enable_port, port->number, port, 240 speed, uhci_port_reset_enable, port->number, port, 213 241 &dev_addr, &port->attached_device, NULL, NULL, NULL); 214 242 215 243 if (rc != EOK) { 216 usb_log_error("Port(%p-%d): Failed(%d) adding newdevice: %s.\n",244 usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n", 217 245 port->address, port->number, rc, str_error(rc)); 218 246 uhci_port_set_enabled(port, false); … … 225 253 return EOK; 226 254 } 227 228 /*----------------------------------------------------------------------------*/ 229 static int uhci_port_remove_device(uhci_port_t *port) 255 /*----------------------------------------------------------------------------*/ 256 /** Removes device. 257 * 258 * @param[in] port Memory structure to use. 259 * @return Error code. 260 * 261 * Does not work DDF does not support device removal. 262 */ 263 int uhci_port_remove_device(uhci_port_t *port) 230 264 { 231 265 usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n", 232 port->address, port->number, (unsigned int)port->attached_device); 233 // uhci_port_set_enabled(port, false); 234 return EOK; 235 } 236 /*----------------------------------------------------------------------------*/ 237 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled) 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. 273 * @return Error code. (Always EOK) 274 */ 275 int uhci_port_set_enabled(uhci_port_t *port, bool enabled) 238 276 { 239 277 assert(port); 240 278 241 /* read register value */ 242 port_status_t port_status 243 = port_status_read(port->address); 244 245 /* enable port: register write */ 279 /* Read register value */ 280 port_status_t port_status = port_status_read(port->address); 281 282 /* Set enabled bit */ 246 283 if (enabled) { 247 284 port_status |= STATUS_ENABLED; … … 249 286 port_status &= ~STATUS_ENABLED; 250 287 } 288 289 /* Write new value. */ 251 290 port_status_write(port->address, port_status); 252 291
Note:
See TracChangeset
for help on using the changeset viewer.