Changeset 75732da in mainline for uspace/drv/vhc/hubops.c
- Timestamp:
- 2010-12-13T07:20:20Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 309dea52
- Parents:
- 84439d7 (diff), 37f7cfe (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/vhc/hubops.c
r84439d7 r75732da 59 59 static int on_get_descriptor(struct usbvirt_device *dev, 60 60 usb_device_request_setup_packet_t *request, uint8_t *data); 61 static int on_set_configuration(struct usbvirt_device *dev, 62 usb_device_request_setup_packet_t *request, uint8_t *data); 61 63 static int on_class_request(struct usbvirt_device *dev, 62 64 usb_device_request_setup_packet_t *request, uint8_t *data); … … 64 66 usb_endpoint_t endpoint, 65 67 void *buffer, size_t size, size_t *actual_size); 68 static void set_port_state(hub_port_t *, hub_port_state_t); 69 static void clear_port_status_change_nl(hub_port_t *, uint16_t); 70 static void set_port_state_nl(hub_port_t *, hub_port_state_t); 66 71 67 72 /** Hub operations. */ 68 73 usbvirt_device_ops_t hub_ops = { 69 74 .on_standard_request[USB_DEVREQ_GET_DESCRIPTOR] = on_get_descriptor, 75 .on_standard_request[USB_DEVREQ_SET_CONFIGURATION] = on_set_configuration, 70 76 .on_class_device_request = on_class_request, 71 77 .on_data = NULL, … … 87 93 } 88 94 95 /** Callback for SET_CONFIGURATION request. */ 96 int on_set_configuration(struct usbvirt_device *dev, 97 usb_device_request_setup_packet_t *request, uint8_t *data) 98 { 99 /* We must suspend power source to all ports. */ 100 size_t i; 101 for (i = 0; i < HUB_PORT_COUNT; i++) { 102 hub_port_t *port = &hub_dev.ports[i]; 103 104 set_port_state(port, HUB_PORT_STATE_POWERED_OFF); 105 } 106 107 /* Let the framework handle the rest of the job. */ 108 return EFORWARD; 109 } 110 111 struct delay_port_state_change { 112 suseconds_t delay; 113 hub_port_state_t old_state; 114 hub_port_state_t new_state; 115 hub_port_t *port; 116 }; 117 118 static int set_port_state_delayed_fibril(void *arg) 119 { 120 struct delay_port_state_change *change 121 = (struct delay_port_state_change *) arg; 122 123 async_usleep(change->delay); 124 125 fibril_mutex_lock(&change->port->guard); 126 if (change->port->state == change->old_state) { 127 set_port_state_nl(change->port, change->new_state); 128 } 129 fibril_mutex_unlock(&change->port->guard); 130 131 free(change); 132 133 return EOK; 134 } 135 136 static void set_port_state_delayed(hub_port_t *port, 137 suseconds_t delay_time, 138 hub_port_state_t old_state, hub_port_state_t new_state) 139 { 140 struct delay_port_state_change *change 141 = malloc(sizeof(struct delay_port_state_change)); 142 change->port = port; 143 change->delay = delay_time; 144 change->old_state = old_state; 145 change->new_state = new_state; 146 fid_t fibril = fibril_create(set_port_state_delayed_fibril, change); 147 if (fibril == 0) { 148 printf("Failed to create fibril\n"); 149 return; 150 } 151 fibril_add_ready(fibril); 152 } 153 89 154 /** Change port status and updates status change status fields. 90 155 */ 91 static void set_port_state(hub_port_t *port, hub_port_state_t state) 92 { 156 void set_port_state(hub_port_t *port, hub_port_state_t state) 157 { 158 fibril_mutex_lock(&port->guard); 159 set_port_state_nl(port, state); 160 fibril_mutex_unlock(&port->guard); 161 } 162 163 void set_port_state_nl(hub_port_t *port, hub_port_state_t state) 164 { 165 166 dprintf(2, "setting port %d state to %d (%c) from %c (change=%u)", 167 port->index, 168 state, hub_port_state_as_char(state), 169 hub_port_state_as_char(port->state), 170 (unsigned int) port->status_change); 171 172 if (state == HUB_PORT_STATE_POWERED_OFF) { 173 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION); 174 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_ENABLE); 175 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET); 176 } 177 if (state == HUB_PORT_STATE_RESUMING) { 178 set_port_state_delayed(port, 10*1000, 179 HUB_PORT_STATE_RESUMING, HUB_PORT_STATE_ENABLED); 180 } 181 if (state == HUB_PORT_STATE_RESETTING) { 182 set_port_state_delayed(port, 10*1000, 183 HUB_PORT_STATE_RESETTING, HUB_PORT_STATE_ENABLED); 184 } 185 if ((port->state == HUB_PORT_STATE_RESETTING) 186 && (state == HUB_PORT_STATE_ENABLED)) { 187 set_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET); 188 } 189 93 190 port->state = state; 94 if (state == HUB_PORT_STATE_POWERED_OFF) {95 clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);96 clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE);97 clear_port_status_change(port, HUB_STATUS_C_PORT_RESET);98 }99 if (state == HUB_PORT_STATE_RESUMING) {100 async_usleep(10*1000);101 if (port->state == state) {102 set_port_state(port, HUB_PORT_STATE_ENABLED);103 }104 }105 if (state == HUB_PORT_STATE_RESETTING) {106 async_usleep(10*1000);107 if (port->state == state) {108 set_port_status_change(port, HUB_STATUS_C_PORT_RESET);109 set_port_state(port, HUB_PORT_STATE_ENABLED);110 }111 }112 191 } 113 192 … … 122 201 } \ 123 202 } while (false); \ 124 hub_port_t *portvar = &hub_dev.ports[index ]203 hub_port_t *portvar = &hub_dev.ports[index-1] 125 204 126 205 … … 134 213 _GET_PORT(port, portindex); 135 214 215 fibril_mutex_lock(&port->guard); 216 int rc = ENOTSUP; 217 136 218 switch (feature) { 137 219 case USB_HUB_FEATURE_PORT_ENABLE: 138 220 if ((port->state != HUB_PORT_STATE_NOT_CONFIGURED) 139 221 && (port->state != HUB_PORT_STATE_POWERED_OFF)) { 140 set_port_state(port, HUB_PORT_STATE_DISABLED); 141 } 142 return EOK; 222 set_port_state_nl(port, HUB_PORT_STATE_DISABLED); 223 } 224 rc = EOK; 225 break; 143 226 144 227 case USB_HUB_FEATURE_PORT_SUSPEND: 145 228 if (port->state != HUB_PORT_STATE_SUSPENDED) { 146 return EOK; 147 } 148 set_port_state(port, HUB_PORT_STATE_RESUMING); 149 return EOK; 229 rc = EOK; 230 break; 231 } 232 set_port_state_nl(port, HUB_PORT_STATE_RESUMING); 233 rc = EOK; 234 break; 150 235 151 236 case USB_HUB_FEATURE_PORT_POWER: 152 237 if (port->state != HUB_PORT_STATE_NOT_CONFIGURED) { 153 set_port_state(port, HUB_PORT_STATE_POWERED_OFF); 154 } 155 return EOK; 238 set_port_state_nl(port, HUB_PORT_STATE_POWERED_OFF); 239 } 240 rc = EOK; 241 break; 156 242 157 243 case USB_HUB_FEATURE_C_PORT_CONNECTION: 158 clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION); 159 return EOK; 244 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION); 245 rc = EOK; 246 break; 160 247 161 248 case USB_HUB_FEATURE_C_PORT_ENABLE: 162 clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE); 163 return EOK; 249 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_ENABLE); 250 rc = EOK; 251 break; 164 252 165 253 case USB_HUB_FEATURE_C_PORT_SUSPEND: 166 clear_port_status_change(port, HUB_STATUS_C_PORT_SUSPEND); 167 return EOK; 254 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_SUSPEND); 255 rc = EOK; 256 break; 168 257 169 258 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: 170 clear_port_status_change(port, HUB_STATUS_C_PORT_OVER_CURRENT); 171 return EOK; 172 } 173 259 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_OVER_CURRENT); 260 rc = EOK; 261 break; 262 263 case USB_HUB_FEATURE_C_PORT_RESET: 264 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET); 265 rc = EOK; 266 break; 267 } 268 269 fibril_mutex_unlock(&port->guard); 270 271 return rc; 272 } 273 274 static int get_bus_state(uint16_t portindex) 275 { 174 276 return ENOTSUP; 175 277 } 176 278 177 static int get_bus_state(uint16_t portindex) 178 { 179 return ENOTSUP; 180 } 181 182 static int get_hub_descriptor(uint8_t descriptor_type, 183 uint8_t descriptor_index, uint16_t length) 184 { 279 static int get_hub_descriptor(struct usbvirt_device *dev, 280 uint8_t descriptor_index, 281 uint8_t descriptor_type, uint16_t length) 282 { 283 if (descriptor_type == USB_DESCTYPE_HUB) { 284 int rc = dev->control_transfer_reply(dev, 0, 285 &hub_descriptor, hub_descriptor.length); 286 287 return rc; 288 289 } 290 185 291 return ENOTSUP; 186 292 } … … 198 304 _GET_PORT(port, portindex); 199 305 306 fibril_mutex_lock(&port->guard); 307 200 308 uint32_t status; 201 309 status = MAKE_BYTE( … … 225 333 status |= (port->status_change << 16); 226 334 335 fibril_mutex_unlock(&port->guard); 336 337 dprintf(2, "GetPortStatus(port=%d, status=%u)\n", (int)portindex, 338 (unsigned int) status); 227 339 return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4); 228 340 } … … 238 350 _GET_PORT(port, portindex); 239 351 352 fibril_mutex_lock(&port->guard); 353 354 int rc = ENOTSUP; 355 240 356 switch (feature) { 241 357 case USB_HUB_FEATURE_PORT_RESET: 242 358 if (port->state != HUB_PORT_STATE_POWERED_OFF) { 243 set_port_state(port, HUB_PORT_STATE_RESETTING); 244 } 245 return EOK; 359 set_port_state_nl(port, HUB_PORT_STATE_RESETTING); 360 } 361 rc = EOK; 362 break; 246 363 247 364 case USB_HUB_FEATURE_PORT_SUSPEND: 248 365 if (port->state == HUB_PORT_STATE_ENABLED) { 249 set_port_state(port, HUB_PORT_STATE_SUSPENDED); 250 } 251 return EOK; 366 set_port_state_nl(port, HUB_PORT_STATE_SUSPENDED); 367 } 368 rc = EOK; 369 break; 252 370 253 371 case USB_HUB_FEATURE_PORT_POWER: 254 372 if (port->state == HUB_PORT_STATE_POWERED_OFF) { 255 set_port_state(port, HUB_PORT_STATE_DISCONNECTED); 256 } 257 return EOK; 258 } 259 return ENOTSUP; 373 set_port_state_nl(port, HUB_PORT_STATE_DISCONNECTED); 374 } 375 rc = EOK; 376 break; 377 } 378 379 fibril_mutex_unlock(&port->guard); 380 return rc; 260 381 } 261 382 … … 267 388 usb_device_request_setup_packet_t *request, uint8_t *data) 268 389 { 269 dprintf(2, "hub class request (%d) \n", (int) request->request);390 dprintf(2, "hub class request (%d)", (int) request->request); 270 391 271 392 uint8_t recipient = request->request_type & 31; … … 298 419 299 420 case USB_HUB_REQUEST_GET_DESCRIPTOR: 300 return get_hub_descriptor( request->value_low,421 return get_hub_descriptor(dev, request->value_low, 301 422 request->value_high, request->length); 302 423 … … 316 437 317 438 default: 439 dprintf(0, "WARN: unknown request (%d)!\n", 440 request->request); 318 441 break; 319 442 } … … 325 448 } 326 449 450 void clear_port_status_change_nl(hub_port_t *port, uint16_t change) 451 { 452 port->status_change &= (~change); 453 dprintf(2, "cleared port %d status change %d (%u)", port->index, 454 (int)change, (unsigned int) port->status_change); 455 } 456 457 void set_port_status_change_nl(hub_port_t *port, uint16_t change) 458 { 459 port->status_change |= change; 460 dprintf(2, "set port %d status change %d (%u)", port->index, 461 (int)change, (unsigned int) port->status_change); 462 463 } 464 327 465 void clear_port_status_change(hub_port_t *port, uint16_t change) 328 466 { 329 port->status_change &= (~change); 467 fibril_mutex_lock(&port->guard); 468 clear_port_status_change_nl(port, change); 469 fibril_mutex_unlock(&port->guard); 330 470 } 331 471 332 472 void set_port_status_change(hub_port_t *port, uint16_t change) 333 473 { 334 port->status_change |= change; 474 fibril_mutex_lock(&port->guard); 475 set_port_status_change_nl(port, change); 476 fibril_mutex_unlock(&port->guard); 335 477 } 336 478 … … 350 492 hub_port_t *port = &hub_dev.ports[i]; 351 493 494 fibril_mutex_lock(&port->guard); 352 495 if (port->status_change != 0) { 353 496 change_map |= (1 << (i + 1)); 354 497 } 498 fibril_mutex_unlock(&port->guard); 355 499 } 356 500
Note:
See TracChangeset
for help on using the changeset viewer.