Changes in uspace/drv/vhc/hubops.c [56b962d:1e32a63] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/vhc/hubops.c
r56b962d r1e32a63 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); 71 72 /** Standard USB requests. */ 73 static usbvirt_standard_device_request_ops_t standard_request_ops = { 74 .on_get_status = NULL, 75 .on_clear_feature = NULL, 76 .on_set_feature = NULL, 77 .on_set_address = NULL, 78 .on_get_descriptor = on_get_descriptor, 79 .on_set_descriptor = NULL, 80 .on_get_configuration = NULL, 81 .on_set_configuration = on_set_configuration, 82 .on_get_interface = NULL, 83 .on_set_interface = NULL, 84 .on_synch_frame = NULL 85 }; 66 86 67 87 /** Hub operations. */ 68 88 usbvirt_device_ops_t hub_ops = { 69 . on_standard_request[USB_DEVREQ_GET_DESCRIPTOR] = on_get_descriptor,89 .standard_request_ops = &standard_request_ops, 70 90 .on_class_device_request = on_class_request, 71 91 .on_data = NULL, … … 87 107 } 88 108 109 /** Callback for SET_CONFIGURATION request. */ 110 int on_set_configuration(struct usbvirt_device *dev, 111 usb_device_request_setup_packet_t *request, uint8_t *data) 112 { 113 /* We must suspend power source to all ports. */ 114 size_t i; 115 for (i = 0; i < HUB_PORT_COUNT; i++) { 116 hub_port_t *port = &hub_dev.ports[i]; 117 118 set_port_state(port, HUB_PORT_STATE_POWERED_OFF); 119 } 120 121 /* Let the framework handle the rest of the job. */ 122 return EFORWARD; 123 } 124 125 struct delay_port_state_change { 126 suseconds_t delay; 127 hub_port_state_t old_state; 128 hub_port_state_t new_state; 129 hub_port_t *port; 130 }; 131 132 static int set_port_state_delayed_fibril(void *arg) 133 { 134 struct delay_port_state_change *change 135 = (struct delay_port_state_change *) arg; 136 137 async_usleep(change->delay); 138 139 fibril_mutex_lock(&change->port->guard); 140 if (change->port->state == change->old_state) { 141 set_port_state_nl(change->port, change->new_state); 142 } 143 fibril_mutex_unlock(&change->port->guard); 144 145 free(change); 146 147 return EOK; 148 } 149 150 static void set_port_state_delayed(hub_port_t *port, 151 suseconds_t delay_time, 152 hub_port_state_t old_state, hub_port_state_t new_state) 153 { 154 struct delay_port_state_change *change 155 = malloc(sizeof(struct delay_port_state_change)); 156 change->port = port; 157 change->delay = delay_time; 158 change->old_state = old_state; 159 change->new_state = new_state; 160 fid_t fibril = fibril_create(set_port_state_delayed_fibril, change); 161 if (fibril == 0) { 162 printf("Failed to create fibril\n"); 163 return; 164 } 165 fibril_add_ready(fibril); 166 } 167 89 168 /** Change port status and updates status change status fields. 90 169 */ 91 static void set_port_state(hub_port_t *port, hub_port_state_t state) 92 { 170 void set_port_state(hub_port_t *port, hub_port_state_t state) 171 { 172 fibril_mutex_lock(&port->guard); 173 set_port_state_nl(port, state); 174 fibril_mutex_unlock(&port->guard); 175 } 176 177 void set_port_state_nl(hub_port_t *port, hub_port_state_t state) 178 { 179 180 dprintf(2, "setting port %d state to %d (%c) from %c (change=%u)", 181 port->index, 182 state, hub_port_state_as_char(state), 183 hub_port_state_as_char(port->state), 184 (unsigned int) port->status_change); 185 186 if (state == HUB_PORT_STATE_POWERED_OFF) { 187 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION); 188 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_ENABLE); 189 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET); 190 } 191 if (state == HUB_PORT_STATE_RESUMING) { 192 set_port_state_delayed(port, 10*1000, 193 HUB_PORT_STATE_RESUMING, HUB_PORT_STATE_ENABLED); 194 } 195 if (state == HUB_PORT_STATE_RESETTING) { 196 set_port_state_delayed(port, 10*1000, 197 HUB_PORT_STATE_RESETTING, HUB_PORT_STATE_ENABLED); 198 } 199 if ((port->state == HUB_PORT_STATE_RESETTING) 200 && (state == HUB_PORT_STATE_ENABLED)) { 201 set_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET); 202 } 203 93 204 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 205 } 113 206 … … 122 215 } \ 123 216 } while (false); \ 124 hub_port_t *portvar = &hub_dev.ports[index ]217 hub_port_t *portvar = &hub_dev.ports[index-1] 125 218 126 219 … … 134 227 _GET_PORT(port, portindex); 135 228 229 fibril_mutex_lock(&port->guard); 230 int rc = ENOTSUP; 231 136 232 switch (feature) { 137 233 case USB_HUB_FEATURE_PORT_ENABLE: 138 234 if ((port->state != HUB_PORT_STATE_NOT_CONFIGURED) 139 235 && (port->state != HUB_PORT_STATE_POWERED_OFF)) { 140 set_port_state(port, HUB_PORT_STATE_DISABLED); 141 } 142 return EOK; 236 set_port_state_nl(port, HUB_PORT_STATE_DISABLED); 237 } 238 rc = EOK; 239 break; 143 240 144 241 case USB_HUB_FEATURE_PORT_SUSPEND: 145 242 if (port->state != HUB_PORT_STATE_SUSPENDED) { 146 return EOK; 147 } 148 set_port_state(port, HUB_PORT_STATE_RESUMING); 149 return EOK; 243 rc = EOK; 244 break; 245 } 246 set_port_state_nl(port, HUB_PORT_STATE_RESUMING); 247 rc = EOK; 248 break; 150 249 151 250 case USB_HUB_FEATURE_PORT_POWER: 152 251 if (port->state != HUB_PORT_STATE_NOT_CONFIGURED) { 153 set_port_state(port, HUB_PORT_STATE_POWERED_OFF); 154 } 155 return EOK; 252 set_port_state_nl(port, HUB_PORT_STATE_POWERED_OFF); 253 } 254 rc = EOK; 255 break; 156 256 157 257 case USB_HUB_FEATURE_C_PORT_CONNECTION: 158 clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION); 159 return EOK; 258 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION); 259 rc = EOK; 260 break; 160 261 161 262 case USB_HUB_FEATURE_C_PORT_ENABLE: 162 clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE); 163 return EOK; 263 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_ENABLE); 264 rc = EOK; 265 break; 164 266 165 267 case USB_HUB_FEATURE_C_PORT_SUSPEND: 166 clear_port_status_change(port, HUB_STATUS_C_PORT_SUSPEND); 167 return EOK; 268 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_SUSPEND); 269 rc = EOK; 270 break; 168 271 169 272 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 273 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_OVER_CURRENT); 274 rc = EOK; 275 break; 276 277 case USB_HUB_FEATURE_C_PORT_RESET: 278 clear_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET); 279 rc = EOK; 280 break; 281 } 282 283 fibril_mutex_unlock(&port->guard); 284 285 return rc; 286 } 287 288 static int get_bus_state(uint16_t portindex) 289 { 174 290 return ENOTSUP; 175 291 } 176 292 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 { 293 static int get_hub_descriptor(struct usbvirt_device *dev, 294 uint8_t descriptor_index, 295 uint8_t descriptor_type, uint16_t length) 296 { 297 if (descriptor_type == USB_DESCTYPE_HUB) { 298 int rc = dev->control_transfer_reply(dev, 0, 299 &hub_descriptor, hub_descriptor.length); 300 301 return rc; 302 303 } 304 185 305 return ENOTSUP; 186 306 } … … 198 318 _GET_PORT(port, portindex); 199 319 320 fibril_mutex_lock(&port->guard); 321 200 322 uint32_t status; 201 323 status = MAKE_BYTE( … … 225 347 status |= (port->status_change << 16); 226 348 349 fibril_mutex_unlock(&port->guard); 350 351 dprintf(2, "GetPortStatus(port=%d, status=%u)\n", (int)portindex, 352 (unsigned int) status); 227 353 return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4); 228 354 } … … 238 364 _GET_PORT(port, portindex); 239 365 366 fibril_mutex_lock(&port->guard); 367 368 int rc = ENOTSUP; 369 240 370 switch (feature) { 241 371 case USB_HUB_FEATURE_PORT_RESET: 242 372 if (port->state != HUB_PORT_STATE_POWERED_OFF) { 243 set_port_state(port, HUB_PORT_STATE_RESETTING); 244 } 245 return EOK; 373 set_port_state_nl(port, HUB_PORT_STATE_RESETTING); 374 } 375 rc = EOK; 376 break; 246 377 247 378 case USB_HUB_FEATURE_PORT_SUSPEND: 248 379 if (port->state == HUB_PORT_STATE_ENABLED) { 249 set_port_state(port, HUB_PORT_STATE_SUSPENDED); 250 } 251 return EOK; 380 set_port_state_nl(port, HUB_PORT_STATE_SUSPENDED); 381 } 382 rc = EOK; 383 break; 252 384 253 385 case USB_HUB_FEATURE_PORT_POWER: 254 386 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; 387 set_port_state_nl(port, HUB_PORT_STATE_DISCONNECTED); 388 } 389 rc = EOK; 390 break; 391 } 392 393 fibril_mutex_unlock(&port->guard); 394 return rc; 260 395 } 261 396 … … 267 402 usb_device_request_setup_packet_t *request, uint8_t *data) 268 403 { 269 dprintf(2, "hub class request (%d) \n", (int) request->request);404 dprintf(2, "hub class request (%d)", (int) request->request); 270 405 271 406 uint8_t recipient = request->request_type & 31; … … 298 433 299 434 case USB_HUB_REQUEST_GET_DESCRIPTOR: 300 return get_hub_descriptor( request->value_low,435 return get_hub_descriptor(dev, request->value_low, 301 436 request->value_high, request->length); 302 437 … … 316 451 317 452 default: 453 dprintf(0, "WARN: unknown request (%d)!\n", 454 request->request); 318 455 break; 319 456 } … … 325 462 } 326 463 464 void clear_port_status_change_nl(hub_port_t *port, uint16_t change) 465 { 466 port->status_change &= (~change); 467 dprintf(2, "cleared port %d status change %d (%u)", port->index, 468 (int)change, (unsigned int) port->status_change); 469 } 470 471 void set_port_status_change_nl(hub_port_t *port, uint16_t change) 472 { 473 port->status_change |= change; 474 dprintf(2, "set port %d status change %d (%u)", port->index, 475 (int)change, (unsigned int) port->status_change); 476 477 } 478 327 479 void clear_port_status_change(hub_port_t *port, uint16_t change) 328 480 { 329 port->status_change &= (~change); 481 fibril_mutex_lock(&port->guard); 482 clear_port_status_change_nl(port, change); 483 fibril_mutex_unlock(&port->guard); 330 484 } 331 485 332 486 void set_port_status_change(hub_port_t *port, uint16_t change) 333 487 { 334 port->status_change |= change; 488 fibril_mutex_lock(&port->guard); 489 set_port_status_change_nl(port, change); 490 fibril_mutex_unlock(&port->guard); 335 491 } 336 492 … … 350 506 hub_port_t *port = &hub_dev.ports[i]; 351 507 508 fibril_mutex_lock(&port->guard); 352 509 if (port->status_change != 0) { 353 510 change_map |= (1 << (i + 1)); 354 511 } 512 fibril_mutex_unlock(&port->guard); 355 513 } 356 514
Note:
See TracChangeset
for help on using the changeset viewer.