Changeset 0212751 in mainline
- Timestamp:
- 2011-09-23T19:06:37Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- aefa0d5
- Parents:
- 4559d89
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhub/port.c
r4559d89 r0212751 128 128 * @param port port number, starting from 1 129 129 */ 130 void usb_hub_port_process_interrupt(usb_hub_info_t *hub, size_t port) 131 { 132 usb_log_debug("Interrupt at port %zu\n", port); 130 void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub) 131 { 132 assert(port); 133 assert(hub); 134 usb_log_debug("Interrupt at port %zu\n", port->port_number); 133 135 134 136 usb_port_status_t status; 135 const int opResult = 136 get_port_status(&hub->ports[port], &status); 137 const int opResult = get_port_status(port, &status); 137 138 if (opResult != EOK) { 138 139 usb_log_error("Failed to get port %zu status: %s.\n", 139 port , str_error(opResult));140 port->port_number, str_error(opResult)); 140 141 return; 141 142 } … … 143 144 /* Connection change */ 144 145 if (status & USB_HUB_PORT_C_STATUS_CONNECTION) { 145 const bool device_connected =146 const bool connected = 146 147 (status & USB_HUB_PORT_STATUS_CONNECTION) != 0; 147 148 usb_log_debug("Connection change on port %zu: device %s.\n", 148 port , device_connected ? "attached" : "removed");149 port->port_number, connected ? "attached" : "removed"); 149 150 /* ACK the change */ 150 const int opResult = 151 usb_hub_port_clear_feature(&hub->ports[port], 152 USB_HUB_FEATURE_C_PORT_CONNECTION); 151 const int opResult = usb_hub_port_clear_feature(port, 152 USB_HUB_FEATURE_C_PORT_CONNECTION); 153 153 if (opResult != EOK) { 154 usb_log_warning("Failed to clear " 155 "port-change-connection flag: %s.\n", 156 str_error(opResult)); 157 } 158 159 if (device_connected) { 160 const int opResult = create_add_device_fibril(hub, port, 161 usb_port_speed(status)); 154 usb_log_warning("Failed to clear port-change-connection" 155 " flag: %s.\n", str_error(opResult)); 156 } 157 158 if (connected) { 159 const int opResult = create_add_device_fibril(hub, 160 port->port_number, usb_port_speed(status)); 162 161 if (opResult != EOK) { 163 162 usb_log_error( 164 163 "Cannot handle change on port %zu: %s.\n", 165 port , str_error(opResult));164 port->port_number, str_error(opResult)); 166 165 } 167 166 } else { 168 usb_hub_port_removed_device( &hub->ports[port]);167 usb_hub_port_removed_device(port); 169 168 } 170 169 } … … 172 171 /* Enable change, ports are automatically disabled on errors. */ 173 172 if (status & USB_HUB_PORT_C_STATUS_ENABLED) { 174 // TODO: Remove device that was connected 175 // TODO: Clear feature C_PORT_ENABLE 173 usb_hub_port_removed_device(port); 174 const int rc = usb_hub_port_clear_feature(port, 175 USB_HUB_FEATURE_C_PORT_ENABLE); 176 if (rc != EOK) { 177 usb_log_error( 178 "Failed to clear port %zu enable change feature: " 179 "%s.\n", port->port_number, str_error(rc)); 180 } 176 181 177 182 } … … 180 185 if (status & USB_HUB_PORT_C_STATUS_SUSPEND) { 181 186 usb_log_error("Port %zu went to suspend state, this should" 182 "NOT happen as we do not support suspend state!", port); 183 // TODO: Clear feature C_PORT_SUSPEND 187 "NOT happen as we do not support suspend state!", 188 port->port_number); 189 const int rc = usb_hub_port_clear_feature(port, 190 USB_HUB_FEATURE_C_PORT_SUSPEND); 191 if (rc != EOK) { 192 usb_log_error( 193 "Failed to clear port %zu suspend change feature: " 194 "%s.\n", port->port_number, str_error(rc)); 195 } 184 196 } 185 197 … … 190 202 * Hub device is responsible for putting port in power off 191 203 * mode. USB system software is responsible for powering port 192 * back on when the over-curent condition is gone */ 204 * back on when the over-current condition is gone */ 205 const int rc = usb_hub_port_clear_feature(port, 206 USB_HUB_FEATURE_C_PORT_OVER_CURRENT); 207 if (rc != EOK) { 208 usb_log_error( 209 "Failed to clear port %zu OC change feature: %s.\n", 210 port->port_number, str_error(rc)); 211 } 193 212 if (!(status & ~USB_HUB_PORT_STATUS_OC)) { 194 // TODO: Power port on, this will cause connect 195 // change and device initialization. 196 } 197 // TODO: Ack over-power change. 213 const int rc = usb_hub_port_set_feature( 214 port, USB_HUB_FEATURE_PORT_POWER); 215 if (rc != EOK) { 216 usb_log_error( 217 "Failed to set port %d power after OC:" 218 " %s.\n", port->port_number, str_error(rc)); 219 } 220 } 198 221 } 199 222 200 223 /* Port reset, set on port reset complete. */ 201 224 if (status & USB_HUB_PORT_C_STATUS_RESET) { 202 usb_hub_port_reset_completed(&hub->ports[port], status); 203 } 204 205 usb_log_debug("Port %zu status 0x%08" PRIx32 "\n", port, status); 225 usb_hub_port_reset_completed(port, status); 226 } 227 228 usb_log_debug("Port %zu status 0x%08" PRIx32 "\n", 229 port->port_number, status); 206 230 } 207 231 -
uspace/drv/bus/usb/usbhub/port.h
r4559d89 r0212751 79 79 80 80 void usb_hub_port_reset_fail(usb_hub_port_t *port); 81 void usb_hub_port_process_interrupt(usb_hub_ info_t *hub, size_t port);81 void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub); 82 82 int usb_hub_port_clear_feature( 83 83 usb_hub_port_t *port, usb_hub_class_feature_t feature); -
uspace/drv/bus/usb/usbhub/usbhub.c
r4559d89 r0212751 170 170 usb_log_debug("hub_port_changes_callback\n"); 171 171 usb_hub_info_t *hub = arg; 172 173 /* FIXME: check that we received enough bytes. */ 172 assert(hub); 173 174 /* It is an error condition if we didn't receive enough data */ 174 175 if (change_bitmap_size == 0) { 175 goto leave;176 return false; 176 177 } 177 178 … … 187 188 const bool change = (change_bitmap[port / 8] >> (port % 8)) & 1; 188 189 if (change) { 189 usb_hub_port_process_interrupt( hub, port);190 usb_hub_port_process_interrupt(&hub->ports[port], hub); 190 191 } 191 192 } 192 leave:193 /* FIXME: proper interval. */194 // TODO Interval should be handled by USB HC scheduler not here195 async_usleep(1000 * 250);196 197 193 return true; 198 194 } … … 256 252 hub_info->port_count = descriptor.port_count; 257 253 258 // TODO Why +1 ?254 // TODO: +1 hack is no longer necessary 259 255 hub_info->ports = 260 256 malloc(sizeof(usb_hub_port_t) * (hub_info->port_count + 1)); … … 349 345 { 350 346 if (status & USB_HUB_STATUS_OVER_CURRENT) { 351 /* Over-current detected on one or all ports, 352 * switch them all off to prevent damage. */ 353 //TODO Consider ganged power switching here. 354 //TODO Hub should have turned the ports off already, 355 //this is redundant. 356 size_t port; 357 for (port = 1; port <= hub_info->port_count; ++port) { 358 const int opResult = usb_hub_port_clear_feature( 359 &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER); 360 if (opResult != EOK) { 361 usb_log_warning( 362 "HUB OVER-CURRENT: Cannot power off port" 363 " %d: %s\n", 364 port, str_error(opResult)); 365 } 366 } 347 /* Hub should remove power from all ports if it detects OC */ 348 usb_log_warning("Detected hub over-current condition, " 349 "all ports should be powered off."); 367 350 } else { 368 351 /* Over-current condition is gone, it is safe to turn the … … 379 362 } 380 363 } 364 } 365 const int opResult = usb_request_clear_feature( 366 &hub_info->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS, 367 USB_REQUEST_RECIPIENT_DEVICE, 368 USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0); 369 if (opResult != EOK) { 370 usb_log_error( 371 "Failed to clear hub over-current change flag: %s.\n", 372 str_error(opResult)); 381 373 } 382 374 } -
uspace/lib/usb/include/usb/classes/hub.h
r4559d89 r0212751 76 76 #define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1) 77 77 /* Unused part of characteristics field */ 78 uint8_t characteristics_reserve red;78 uint8_t characteristics_reserved; 79 79 /** Time from power-on to stabilization of current on the port. */ 80 80 uint8_t power_good_time;
Note:
See TracChangeset
for help on using the changeset viewer.