Changeset 19a1800 in mainline for uspace/drv
- Timestamp:
- 2011-03-01T22:20:56Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e24e7b1
- Parents:
- 976f546 (diff), ac8285d (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. - Location:
- uspace/drv
- Files:
-
- 46 added
- 2 deleted
- 37 edited
- 8 moved
-
isa/isa.c (modified) (22 diffs)
-
ns8250/ns8250.c (modified) (37 diffs)
-
pciintel/pci.c (modified) (18 diffs)
-
pciintel/pci.h (modified) (3 diffs)
-
root/root.c (modified) (9 diffs)
-
rootpc/rootpc.c (modified) (8 diffs)
-
rootvirt/devices.def (modified) (2 diffs)
-
rootvirt/rootvirt.c (modified) (5 diffs)
-
test1/char.c (modified) (2 diffs)
-
test1/test1.c (modified) (4 diffs)
-
test1/test1.h (modified) (1 diff)
-
test2/test2.c (modified) (3 diffs)
-
uhci-hcd/Makefile (moved) (moved from uspace/app/tasks/Makefile ) (2 diffs)
-
uhci-hcd/batch.c (added)
-
uhci-hcd/batch.h (added)
-
uhci-hcd/iface.c (added)
-
uhci-hcd/iface.h (moved) (moved from uspace/drv/uhci/uhci.h ) (1 diff)
-
uhci-hcd/main.c (added)
-
uhci-hcd/pci.c (added)
-
uhci-hcd/pci.h (moved) (moved from uspace/drv/vhc/debug.c ) (1 diff)
-
uhci-hcd/root_hub.c (added)
-
uhci-hcd/root_hub.h (added)
-
uhci-hcd/transfer_list.c (added)
-
uhci-hcd/transfer_list.h (added)
-
uhci-hcd/transfers.c (moved) (moved from uspace/drv/uhci/transfers.c )
-
uhci-hcd/uhci-hcd.ma (added)
-
uhci-hcd/uhci.c (added)
-
uhci-hcd/uhci.h (added)
-
uhci-hcd/uhci_struct/link_pointer.h (added)
-
uhci-hcd/uhci_struct/queue_head.h (added)
-
uhci-hcd/uhci_struct/transfer_descriptor.c (added)
-
uhci-hcd/uhci_struct/transfer_descriptor.h (added)
-
uhci-hcd/utils/device_keeper.c (added)
-
uhci-hcd/utils/device_keeper.h (added)
-
uhci-hcd/utils/malloc32.h (added)
-
uhci-rhd/Makefile (moved) (moved from uspace/drv/usbkbd/Makefile ) (2 diffs)
-
uhci-rhd/main.c (added)
-
uhci-rhd/port.c (added)
-
uhci-rhd/port.h (added)
-
uhci-rhd/port_status.c (added)
-
uhci-rhd/port_status.h (added)
-
uhci-rhd/root_hub.c (added)
-
uhci-rhd/root_hub.h (added)
-
uhci-rhd/uhci-rhd.ma (added)
-
uhci/uhci.ma (deleted)
-
usbhid/Makefile (added)
-
usbhid/conv.c (added)
-
usbhid/conv.h (added)
-
usbhid/descdump.c (added)
-
usbhid/descdump.h (added)
-
usbhid/hiddev.c (added)
-
usbhid/hiddev.h (added)
-
usbhid/hidreq.c (added)
-
usbhid/hidreq.h (added)
-
usbhid/kbd.h (added)
-
usbhid/kbddev.c (added)
-
usbhid/kbddev.h (added)
-
usbhid/layout.h (added)
-
usbhid/main.c (moved) (moved from uspace/drv/uhci/main.c ) (2 diffs)
-
usbhid/usbhid.ma (moved) (moved from uspace/drv/usbkbd/usbkbd.ma )
-
usbhub/main.c (modified) (3 diffs)
-
usbhub/port_status.h (modified) (4 diffs)
-
usbhub/usbhub.c (modified) (10 diffs)
-
usbhub/usbhub.h (modified) (4 diffs)
-
usbhub/usbhub_private.h (modified) (6 diffs)
-
usbhub/usblist.c (modified) (1 diff)
-
usbhub/usblist.h (modified) (3 diffs)
-
usbhub/utils.c (modified) (6 diffs)
-
usbkbd/main.c (deleted)
-
usbmid/Makefile (moved) (moved from uspace/drv/uhci/Makefile ) (2 diffs)
-
usbmid/dump.c (added)
-
usbmid/explore.c (added)
-
usbmid/main.c (added)
-
usbmid/usbmid.c (added)
-
usbmid/usbmid.h (added)
-
usbmid/usbmid.ma (added)
-
vhc/Makefile (modified) (1 diff)
-
vhc/conn.h (modified) (3 diffs)
-
vhc/conndev.c (modified) (3 diffs)
-
vhc/connhost.c (modified) (15 diffs)
-
vhc/devices.c (modified) (10 diffs)
-
vhc/devices.h (modified) (2 diffs)
-
vhc/hc.c (modified) (9 diffs)
-
vhc/hc.h (modified) (3 diffs)
-
vhc/hcd.c (modified) (7 diffs)
-
vhc/hub.c (modified) (4 diffs)
-
vhc/hub.h (modified) (3 diffs)
-
vhc/hub/hub.c (modified) (4 diffs)
-
vhc/hub/hub.h (modified) (3 diffs)
-
vhc/hub/virthub.c (modified) (4 diffs)
-
vhc/hub/virthub.h (modified) (2 diffs)
-
vhc/hub/virthubops.c (modified) (1 diff)
-
vhc/vhcd.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/isa/isa.c
r976f546 r19a1800 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 43 44 #include <stdlib.h> 44 45 #include <str.h> 46 #include <str_error.h> 45 47 #include <ctype.h> 46 48 #include <macros.h> … … 50 52 #include <sys/stat.h> 51 53 52 #include <d river.h>54 #include <ddf/driver.h> 53 55 #include <ops/hw_res.h> 54 56 … … 58 60 59 61 #define NAME "isa" 60 #define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev" 62 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev" 63 64 /** Obtain soft-state pointer from function node pointer */ 65 #define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data)) 61 66 62 67 #define ISA_MAX_HW_RES 4 63 68 64 typedef struct isa_child_data { 69 typedef struct isa_fun { 70 ddf_fun_t *fnode; 65 71 hw_resource_list_t hw_resources; 66 } isa_child_data_t; 67 68 static hw_resource_list_t *isa_get_child_resources(device_t *dev) 69 { 70 isa_child_data_t *dev_data; 71 72 dev_data = (isa_child_data_t *)dev->driver_data; 73 if (dev_data == NULL) 74 return NULL; 75 76 return &dev_data->hw_resources; 77 } 78 79 static bool isa_enable_child_interrupt(device_t *dev) 72 } isa_fun_t; 73 74 static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode) 75 { 76 isa_fun_t *fun = ISA_FUN(fnode); 77 assert(fun != NULL); 78 79 return &fun->hw_resources; 80 } 81 82 static bool isa_enable_fun_interrupt(ddf_fun_t *fnode) 80 83 { 81 84 // TODO … … 84 87 } 85 88 86 static hw_res_ops_t isa_ child_hw_res_ops = {87 &isa_get_ child_resources,88 &isa_enable_ child_interrupt89 static hw_res_ops_t isa_fun_hw_res_ops = { 90 &isa_get_fun_resources, 91 &isa_enable_fun_interrupt 89 92 }; 90 93 91 static d evice_ops_t isa_child_dev_ops;92 93 static int isa_add_device(d evice_t *dev);94 static ddf_dev_ops_t isa_fun_ops; 95 96 static int isa_add_device(ddf_dev_t *dev); 94 97 95 98 /** The isa device driver's standard operations */ … … 104 107 }; 105 108 106 107 static isa_child_data_t *create_isa_child_data() 108 { 109 isa_child_data_t *data; 110 111 data = (isa_child_data_t *) malloc(sizeof(isa_child_data_t)); 112 if (data != NULL) 113 memset(data, 0, sizeof(isa_child_data_t)); 114 115 return data; 116 } 117 118 static device_t *create_isa_child_dev() 119 { 120 device_t *dev = create_device(); 121 if (dev == NULL) 109 static isa_fun_t *isa_fun_create(ddf_dev_t *dev, const char *name) 110 { 111 isa_fun_t *fun = calloc(1, sizeof(isa_fun_t)); 112 if (fun == NULL) 122 113 return NULL; 123 114 124 isa_child_data_t *data = create_isa_child_data();125 if ( data== NULL) {126 delete_device(dev);115 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name); 116 if (fnode == NULL) { 117 free(fun); 127 118 return NULL; 128 119 } 129 120 130 dev->driver_data = data; 131 return dev; 132 } 133 134 static char *read_dev_conf(const char *conf_path) 121 fun->fnode = fnode; 122 fnode->driver_data = fun; 123 return fun; 124 } 125 126 static char *fun_conf_read(const char *conf_path) 135 127 { 136 128 bool suc = false; … … 151 143 lseek(fd, 0, SEEK_SET); 152 144 if (len == 0) { 153 printf(NAME ": read_dev_conferror: configuration file '%s' "145 printf(NAME ": fun_conf_read error: configuration file '%s' " 154 146 "is empty.\n", conf_path); 155 147 goto cleanup; … … 158 150 buf = malloc(len + 1); 159 151 if (buf == NULL) { 160 printf(NAME ": read_dev_conferror: memory allocation failed.\n");152 printf(NAME ": fun_conf_read error: memory allocation failed.\n"); 161 153 goto cleanup; 162 154 } 163 155 164 156 if (0 >= read(fd, buf, len)) { 165 printf(NAME ": read_dev_conferror: unable to read file '%s'.\n",157 printf(NAME ": fun_conf_read error: unable to read file '%s'.\n", 166 158 conf_path); 167 159 goto cleanup; … … 249 241 } 250 242 251 static void isa_child_set_irq(device_t *dev, int irq) 252 { 253 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 254 255 size_t count = data->hw_resources.count; 256 hw_resource_t *resources = data->hw_resources.resources; 243 static void isa_fun_set_irq(isa_fun_t *fun, int irq) 244 { 245 size_t count = fun->hw_resources.count; 246 hw_resource_t *resources = fun->hw_resources.resources; 257 247 258 248 if (count < ISA_MAX_HW_RES) { … … 260 250 resources[count].res.interrupt.irq = irq; 261 251 262 data->hw_resources.count++; 263 264 printf(NAME ": added irq 0x%x to device %s\n", irq, dev->name); 265 } 266 } 267 268 static void isa_child_set_io_range(device_t *dev, size_t addr, size_t len) 269 { 270 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 271 272 size_t count = data->hw_resources.count; 273 hw_resource_t *resources = data->hw_resources.resources; 252 fun->hw_resources.count++; 253 254 printf(NAME ": added irq 0x%x to function %s\n", irq, 255 fun->fnode->name); 256 } 257 } 258 259 static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len) 260 { 261 size_t count = fun->hw_resources.count; 262 hw_resource_t *resources = fun->hw_resources.resources; 274 263 275 264 if (count < ISA_MAX_HW_RES) { … … 279 268 resources[count].res.io_range.endianness = LITTLE_ENDIAN; 280 269 281 data->hw_resources.count++;270 fun->hw_resources.count++; 282 271 283 272 printf(NAME ": added io range (addr=0x%x, size=0x%x) to " 284 " device%s\n", (unsigned int) addr, (unsigned int) len,285 dev->name);286 } 287 } 288 289 static void get_dev_irq(device_t *dev, char *val)273 "function %s\n", (unsigned int) addr, (unsigned int) len, 274 fun->fnode->name); 275 } 276 } 277 278 static void fun_parse_irq(isa_fun_t *fun, char *val) 290 279 { 291 280 int irq = 0; 292 281 char *end = NULL; 293 282 294 val = skip_spaces(val); 283 val = skip_spaces(val); 295 284 irq = (int)strtol(val, &end, 0x10); 296 285 297 286 if (val != end) 298 isa_ child_set_irq(dev, irq);299 } 300 301 static void get_dev_io_range(device_t *dev, char *val)287 isa_fun_set_irq(fun, irq); 288 } 289 290 static void fun_parse_io_range(isa_fun_t *fun, char *val) 302 291 { 303 292 size_t addr, len; 304 293 char *end = NULL; 305 294 306 val = skip_spaces(val); 295 val = skip_spaces(val); 307 296 addr = strtol(val, &end, 0x10); 308 297 … … 310 299 return; 311 300 312 val = skip_spaces(end); 301 val = skip_spaces(end); 313 302 len = strtol(val, &end, 0x10); 314 303 … … 316 305 return; 317 306 318 isa_ child_set_io_range(dev, addr, len);307 isa_fun_set_io_range(fun, addr, len); 319 308 } 320 309 … … 331 320 } 332 321 333 static void get_dev_match_id(device_t *dev, char *val)322 static void fun_parse_match_id(isa_fun_t *fun, char *val) 334 323 { 335 324 char *id = NULL; 336 325 int score = 0; 337 326 char *end = NULL; 338 339 val = skip_spaces(val); 327 int rc; 328 329 val = skip_spaces(val); 340 330 341 331 score = (int)strtol(val, &end, 10); 342 332 if (val == end) { 343 333 printf(NAME " : error - could not read match score for " 344 " device %s.\n", dev->name);334 "function %s.\n", fun->fnode->name); 345 335 return; 346 336 } 347 337 348 match_id_t *match_id = create_match_id(); 349 if (match_id == NULL) { 350 printf(NAME " : failed to allocate match id for device %s.\n", 351 dev->name); 352 return; 353 } 354 355 val = skip_spaces(end); 338 val = skip_spaces(end); 356 339 get_match_id(&id, val); 357 340 if (id == NULL) { 358 341 printf(NAME " : error - could not read match id for " 359 "device %s.\n", dev->name); 360 delete_match_id(match_id); 342 "function %s.\n", fun->fnode->name); 361 343 return; 362 344 } 363 345 364 match_id->id = id;365 match_id->score = score;366 367 printf(NAME ": adding match id '%s' with score %d to device %s\n", id,368 score, dev->name);369 add_match_id(&dev->match_ids, match_id);370 } 371 372 static bool read_dev_prop(device_t *dev, char *line, const char *prop,373 void (*read_fn)( device_t *, char *))346 printf(NAME ": adding match id '%s' with score %d to function %s\n", id, 347 score, fun->fnode->name); 348 349 rc = ddf_fun_add_match_id(fun->fnode, id, score); 350 if (rc != EOK) 351 printf(NAME ": error adding match ID: %s\n", str_error(rc)); 352 } 353 354 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop, 355 void (*read_fn)(isa_fun_t *, char *)) 374 356 { 375 357 size_t proplen = str_size(prop); … … 378 360 line += proplen; 379 361 line = skip_spaces(line); 380 (*read_fn)( dev, line);362 (*read_fn)(fun, line); 381 363 382 364 return true; … … 386 368 } 387 369 388 static void get_dev_prop(device_t *dev, char *line)370 static void fun_prop_parse(isa_fun_t *fun, char *line) 389 371 { 390 372 /* Skip leading spaces. */ 391 373 line = skip_spaces(line); 392 374 393 if (! read_dev_prop(dev, line, "io_range", &get_dev_io_range) &&394 ! read_dev_prop(dev, line, "irq", &get_dev_irq) &&395 ! read_dev_prop(dev, line, "match", &get_dev_match_id))375 if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) && 376 !prop_parse(fun, line, "irq", &fun_parse_irq) && 377 !prop_parse(fun, line, "match", &fun_parse_match_id)) 396 378 { 397 379 printf(NAME " error undefined device property at line '%s'\n", … … 400 382 } 401 383 402 static void child_alloc_hw_res(device_t *dev) 403 { 404 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 405 data->hw_resources.resources = 384 static void fun_hw_res_alloc(isa_fun_t *fun) 385 { 386 fun->hw_resources.resources = 406 387 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 407 388 } 408 389 409 static char * read_isa_dev_info(char *dev_conf, device_t *parent)390 static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev) 410 391 { 411 392 char *line; 412 char * dev_name = NULL;393 char *fun_name = NULL; 413 394 414 395 /* Skip empty lines. */ 415 396 while (true) { 416 line = str_get_line( dev_conf, &dev_conf);397 line = str_get_line(fun_conf, &fun_conf); 417 398 418 399 if (line == NULL) { … … 426 407 427 408 /* Get device name. */ 428 dev_name = get_device_name(line);429 if ( dev_name == NULL)409 fun_name = get_device_name(line); 410 if (fun_name == NULL) 430 411 return NULL; 431 412 432 device_t *dev = create_isa_child_dev();433 if ( dev== NULL) {434 free( dev_name);413 isa_fun_t *fun = isa_fun_create(dev, fun_name); 414 if (fun == NULL) { 415 free(fun_name); 435 416 return NULL; 436 417 } 437 418 438 dev->name = dev_name;439 440 419 /* Allocate buffer for the list of hardware resources of the device. */ 441 child_alloc_hw_res(dev);420 fun_hw_res_alloc(fun); 442 421 443 422 /* Get properties of the device (match ids, irq and io range). */ 444 423 while (true) { 445 line = str_get_line( dev_conf, &dev_conf);424 line = str_get_line(fun_conf, &fun_conf); 446 425 447 426 if (line_empty(line)) { … … 454 433 * and store it in the device structure. 455 434 */ 456 get_dev_prop(dev, line); 457 458 //printf(NAME ": next line ='%s'\n", dev_conf); 459 //printf(NAME ": current line ='%s'\n", line); 435 fun_prop_parse(fun, line); 460 436 } 461 437 462 438 /* Set device operations to the device. */ 463 dev->ops = &isa_child_dev_ops; 464 465 printf(NAME ": child_device_register(dev, parent); device is %s.\n", 466 dev->name); 467 child_device_register(dev, parent); 468 469 return dev_conf; 470 } 471 472 static void parse_dev_conf(char *conf, device_t *parent) 439 fun->fnode->ops = &isa_fun_ops; 440 441 printf(NAME ": Binding function %s.\n", fun->fnode->name); 442 443 /* XXX Handle error */ 444 (void) ddf_fun_bind(fun->fnode); 445 446 return fun_conf; 447 } 448 449 static void fun_conf_parse(char *conf, ddf_dev_t *dev) 473 450 { 474 451 while (conf != NULL && *conf != '\0') { 475 conf = read_isa_dev_info(conf, parent);476 } 477 } 478 479 static void add_legacy_children(device_t *parent)480 { 481 char * dev_conf;482 483 dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH);484 if ( dev_conf != NULL) {485 parse_dev_conf(dev_conf, parent);486 free( dev_conf);487 } 488 } 489 490 static int isa_add_device(d evice_t *dev)452 conf = isa_fun_read_info(conf, dev); 453 } 454 } 455 456 static void isa_functions_add(ddf_dev_t *dev) 457 { 458 char *fun_conf; 459 460 fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH); 461 if (fun_conf != NULL) { 462 fun_conf_parse(fun_conf, dev); 463 free(fun_conf); 464 } 465 } 466 467 static int isa_add_device(ddf_dev_t *dev) 491 468 { 492 469 printf(NAME ": isa_add_device, device handle = %d\n", 493 470 (int) dev->handle); 494 471 495 /* Add child devices. */ 496 add_legacy_children(dev); 497 printf(NAME ": finished the enumeration of legacy devices\n"); 472 /* Make the bus device more visible. Does not do anything. */ 473 printf(NAME ": adding a 'ctl' function\n"); 474 475 ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl"); 476 if (ctl == NULL) { 477 printf(NAME ": Error creating control function.\n"); 478 return EXDEV; 479 } 480 481 if (ddf_fun_bind(ctl) != EOK) { 482 printf(NAME ": Error binding control function.\n"); 483 return EXDEV; 484 } 485 486 /* Add functions as specified in the configuration file. */ 487 isa_functions_add(dev); 488 printf(NAME ": finished the enumeration of legacy functions\n"); 498 489 499 490 return EOK; … … 502 493 static void isa_init() 503 494 { 504 isa_ child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_hw_res_ops;495 isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops; 505 496 } 506 497 … … 509 500 printf(NAME ": HelenOS ISA bus driver\n"); 510 501 isa_init(); 511 return d river_main(&isa_driver);502 return ddf_driver_main(&isa_driver); 512 503 } 513 504 … … 515 506 * @} 516 507 */ 517 -
uspace/drv/ns8250/ns8250.c
r976f546 r19a1800 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 52 53 #include <libarch/ddi.h> 53 54 54 #include <driver.h> 55 #include <ddf/driver.h> 56 #include <ddf/interrupt.h> 55 57 #include <ops/char_dev.h> 56 58 … … 67 69 #define MAX_BAUD_RATE 115200 68 70 #define DLAB_MASK (1 << 7) 71 72 /** Obtain soft-state structure from function node */ 73 #define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data)) 74 75 /** Obtain soft-state structure from device node */ 76 #define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data)) 69 77 70 78 /** The number of bits of one data unit send by the serial port. */ … … 85 93 86 94 /** The driver data for the serial port devices. */ 87 typedef struct ns8250_dev_data { 95 typedef struct ns8250 { 96 /** DDF device node */ 97 ddf_dev_t *dev; 98 /** DDF function node */ 99 ddf_fun_t *fun; 88 100 /** Is there any client conntected to the device? */ 89 101 bool client_connected; … … 98 110 /** The fibril mutex for synchronizing the access to the device. */ 99 111 fibril_mutex_t mutex; 100 } ns8250_ dev_data_t;101 102 /** Create driver data for a device.103 * 104 * @return The driver data.105 */ 106 static ns8250_ dev_data_t *create_ns8250_dev_data(void)107 { 108 ns8250_ dev_data_t *data;109 110 data = (ns8250_dev_data_t *) malloc(sizeof(ns8250_dev_data_t));111 if ( NULL != data) {112 memset(data, 0, sizeof(ns8250_dev_data_t));113 fibril_mutex_initialize(&data->mutex);114 }115 return data;116 } 117 118 /** Delete driver data.119 * 120 * @param dataThe driver data structure.121 */ 122 static void delete_ns8250_dev_data(ns8250_dev_data_t *data)123 { 124 if (data != NULL)125 free(data);112 } ns8250_t; 113 114 /** Create per-device soft-state structure. 115 * 116 * @return Pointer to soft-state structure. 117 */ 118 static ns8250_t *ns8250_new(void) 119 { 120 ns8250_t *ns; 121 122 ns = (ns8250_t *) calloc(1, sizeof(ns8250_t)); 123 if (ns == NULL) 124 return NULL; 125 126 fibril_mutex_initialize(&ns->mutex); 127 return ns; 128 } 129 130 /** Delete soft-state structure. 131 * 132 * @param ns The driver data structure. 133 */ 134 static void ns8250_delete(ns8250_t *ns) 135 { 136 assert(ns != NULL); 137 free(ns); 126 138 } 127 139 … … 171 183 /** Read data from the serial port device. 172 184 * 173 * @param dev The serial port device.185 * @param fun The serial port function 174 186 * @param buf The ouput buffer for read data. 175 187 * @param count The number of bytes to be read. … … 178 190 * error number otherwise. 179 191 */ 180 static int ns8250_read(device_t *dev, char *buf, size_t count) 181 { 192 static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count) 193 { 194 ns8250_t *ns = NS8250(fun); 182 195 int ret = EOK; 183 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 184 185 fibril_mutex_lock(&data->mutex); 186 while (!buf_is_empty(&data->input_buffer) && (size_t)ret < count) { 187 buf[ret] = (char)buf_pop_front(&data->input_buffer); 196 197 fibril_mutex_lock(&ns->mutex); 198 while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) { 199 buf[ret] = (char)buf_pop_front(&ns->input_buffer); 188 200 ret++; 189 201 } 190 fibril_mutex_unlock(& data->mutex);202 fibril_mutex_unlock(&ns->mutex); 191 203 192 204 return ret; … … 195 207 /** Write a character to the serial port. 196 208 * 197 * @param data The serial port device's driver data.198 * @param c The character to be written .199 */ 200 static inline void ns8250_putchar(ns8250_ dev_data_t *data, uint8_t c)201 { 202 fibril_mutex_lock(& data->mutex);203 ns8250_write_8( data->port, c);204 fibril_mutex_unlock(& data->mutex);209 * @param ns Serial port device 210 * @param c The character to be written 211 */ 212 static inline void ns8250_putchar(ns8250_t *ns, uint8_t c) 213 { 214 fibril_mutex_lock(&ns->mutex); 215 ns8250_write_8(ns->port, c); 216 fibril_mutex_unlock(&ns->mutex); 205 217 } 206 218 207 219 /** Write data to the serial port. 208 220 * 209 * @param dev The serial port device.210 * @param buf The data to be written .211 * @param count The number of bytes to be written .212 * @return Zero on success .213 */ 214 static int ns8250_write(d evice_t *dev, char *buf, size_t count)215 { 216 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;221 * @param fun The serial port function 222 * @param buf The data to be written 223 * @param count The number of bytes to be written 224 * @return Zero on success 225 */ 226 static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count) 227 { 228 ns8250_t *ns = NS8250(fun); 217 229 size_t idx; 218 230 219 231 for (idx = 0; idx < count; idx++) 220 ns8250_putchar( data, (uint8_t) buf[idx]);232 ns8250_putchar(ns, (uint8_t) buf[idx]); 221 233 222 234 return 0; 223 235 } 224 236 225 static d evice_ops_t ns8250_dev_ops;237 static ddf_dev_ops_t ns8250_dev_ops; 226 238 227 239 /** The character interface's callbacks. */ … … 231 243 }; 232 244 233 static int ns8250_add_device(d evice_t *dev);245 static int ns8250_add_device(ddf_dev_t *dev); 234 246 235 247 /** The serial port device driver's standard operations. */ … … 244 256 }; 245 257 246 /** Clean up the serial port device structure. 247 * 248 * @param dev The device structure. 249 */ 250 static void ns8250_dev_cleanup(device_t *dev) 251 { 252 if (dev->driver_data != NULL) { 253 delete_ns8250_dev_data((ns8250_dev_data_t*) dev->driver_data); 254 dev->driver_data = NULL; 255 } 256 257 if (dev->parent_phone > 0) { 258 ipc_hangup(dev->parent_phone); 259 dev->parent_phone = 0; 258 /** Clean up the serial port soft-state 259 * 260 * @param ns Serial port device 261 */ 262 static void ns8250_dev_cleanup(ns8250_t *ns) 263 { 264 if (ns->dev->parent_phone > 0) { 265 async_hangup(ns->dev->parent_phone); 266 ns->dev->parent_phone = 0; 260 267 } 261 268 } … … 263 270 /** Enable the i/o ports of the device. 264 271 * 265 * @param dev The serial port device. 266 * @return True on success, false otherwise. 267 */ 268 static bool ns8250_pio_enable(device_t *dev) 269 { 270 printf(NAME ": ns8250_pio_enable %s\n", dev->name); 271 272 ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data; 272 * @param ns Serial port device 273 * @return True on success, false otherwise 274 */ 275 static bool ns8250_pio_enable(ns8250_t *ns) 276 { 277 printf(NAME ": ns8250_pio_enable %s\n", ns->dev->name); 273 278 274 279 /* Gain control over port's registers. */ 275 if (pio_enable((void *)(uintptr_t) data->io_addr, REG_COUNT,276 (void **) & data->port)) {280 if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT, 281 (void **) &ns->port)) { 277 282 printf(NAME ": error - cannot gain the port %#" PRIx32 " for device " 278 "%s.\n", data->io_addr,dev->name);283 "%s.\n", ns->io_addr, ns->dev->name); 279 284 return false; 280 285 } … … 285 290 /** Probe the serial port device for its presence. 286 291 * 287 * @param dev The serial port device. 288 * @return True if the device is present, false otherwise. 289 */ 290 static bool ns8250_dev_probe(device_t *dev) 291 { 292 printf(NAME ": ns8250_dev_probe %s\n", dev->name); 293 294 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 295 ioport8_t *port_addr = data->port; 292 * @param ns Serial port device 293 * @return True if the device is present, false otherwise 294 */ 295 static bool ns8250_dev_probe(ns8250_t *ns) 296 { 297 printf(NAME ": ns8250_dev_probe %s\n", ns->dev->name); 298 299 ioport8_t *port_addr = ns->port; 296 300 bool res = true; 297 301 uint8_t olddata; … … 310 314 311 315 if (!res) 312 printf(NAME ": device %s is not present.\n", dev->name);316 printf(NAME ": device %s is not present.\n", ns->dev->name); 313 317 314 318 return res; … … 317 321 /** Initialize serial port device. 318 322 * 319 * @param dev The serial port device.320 * @return Zero on success, negative error number otherwise .321 */ 322 static int ns8250_dev_initialize( device_t *dev)323 { 324 printf(NAME ": ns8250_dev_initialize %s\n", dev->name);323 * @param ns Serial port device 324 * @return Zero on success, negative error number otherwise 325 */ 326 static int ns8250_dev_initialize(ns8250_t *ns) 327 { 328 printf(NAME ": ns8250_dev_initialize %s\n", ns->dev->name); 325 329 326 330 int ret = EOK; … … 329 333 memset(&hw_resources, 0, sizeof(hw_resource_list_t)); 330 334 331 /* Allocate driver data for the device. */332 ns8250_dev_data_t *data = create_ns8250_dev_data();333 if (data == NULL)334 return ENOMEM;335 dev->driver_data = data;336 337 335 /* Connect to the parent's driver. */ 338 dev->parent_phone = devman_parent_device_connect(dev->handle,336 ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle, 339 337 IPC_FLAG_BLOCKING); 340 if ( dev->parent_phone < 0) {338 if (ns->dev->parent_phone < 0) { 341 339 printf(NAME ": failed to connect to the parent driver of the " 342 "device %s.\n", dev->name);343 ret = dev->parent_phone;340 "device %s.\n", ns->dev->name); 341 ret = ns->dev->parent_phone; 344 342 goto failed; 345 343 } 346 344 347 345 /* Get hw resources. */ 348 ret = hw_res_get_resource_list( dev->parent_phone, &hw_resources);346 ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources); 349 347 if (ret != EOK) { 350 348 printf(NAME ": failed to get hw resources for the device " 351 "%s.\n", dev->name);349 "%s.\n", ns->dev->name); 352 350 goto failed; 353 351 } … … 362 360 switch (res->type) { 363 361 case INTERRUPT: 364 data->irq = res->res.interrupt.irq;362 ns->irq = res->res.interrupt.irq; 365 363 irq = true; 366 364 printf(NAME ": the %s device was asigned irq = 0x%x.\n", 367 dev->name, data->irq);365 ns->dev->name, ns->irq); 368 366 break; 369 367 370 368 case IO_RANGE: 371 data->io_addr = res->res.io_range.address;369 ns->io_addr = res->res.io_range.address; 372 370 if (res->res.io_range.size < REG_COUNT) { 373 371 printf(NAME ": i/o range assigned to the device " 374 "%s is too small.\n", dev->name);372 "%s is too small.\n", ns->dev->name); 375 373 ret = ELIMIT; 376 374 goto failed; … … 378 376 ioport = true; 379 377 printf(NAME ": the %s device was asigned i/o address = " 380 "0x%x.\n", dev->name, data->io_addr);378 "0x%x.\n", ns->dev->name, ns->io_addr); 381 379 break; 382 380 … … 388 386 if (!irq || !ioport) { 389 387 printf(NAME ": missing hw resource(s) for the device %s.\n", 390 dev->name);388 ns->dev->name); 391 389 ret = ENOENT; 392 390 goto failed; … … 397 395 398 396 failed: 399 ns8250_dev_cleanup( dev);397 ns8250_dev_cleanup(ns); 400 398 hw_res_clean_resource_list(&hw_resources); 401 399 return ret; … … 404 402 /** Enable interrupts on the serial port device. 405 403 * 406 * Interrupt when data is received .404 * Interrupt when data is received 407 405 * 408 406 * @param port The base address of the serial port device's ports. 409 407 */ 410 408 static inline void ns8250_port_interrupts_enable(ioport8_t *port) 411 { 409 { 412 410 pio_write_8(port + 1, 0x1); /* Interrupt when data received. */ 413 411 pio_write_8(port + 4, 0xB); … … 416 414 /** Disable interrupts on the serial port device. 417 415 * 418 * @param port The base address of the serial port device's ports .416 * @param port The base address of the serial port device's ports 419 417 */ 420 418 static inline void ns8250_port_interrupts_disable(ioport8_t *port) … … 425 423 /** Enable interrupts for the serial port device. 426 424 * 427 * @param dev The device. 428 * @return Zero on success, negative error number otherwise. 429 */ 430 static int ns8250_interrupt_enable(device_t *dev) 431 { 432 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 433 425 * @param ns Serial port device 426 * @return Zero on success, negative error number otherwise 427 */ 428 static int ns8250_interrupt_enable(ns8250_t *ns) 429 { 434 430 /* Enable interrupt on the serial port. */ 435 ns8250_port_interrupts_enable( data->port);431 ns8250_port_interrupts_enable(ns->port); 436 432 437 433 return EOK; … … 618 614 * Set the default parameters of the serial communication. 619 615 * 620 * @param dev The serial port device. 621 */ 622 static void ns8250_initialize_port(device_t *dev) 623 { 624 ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data; 625 ioport8_t *port = data->port; 616 * @param ns Serial port device 617 */ 618 static void ns8250_initialize_port(ns8250_t *ns) 619 { 620 ioport8_t *port = ns->port; 626 621 627 622 /* Disable interrupts. */ … … 643 638 * buffer. 644 639 * 645 * @param dev The serial port device. 646 */ 647 static void ns8250_read_from_device(device_t *dev) 648 { 649 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 650 ioport8_t *port = data->port; 640 * @param ns Serial port device 641 */ 642 static void ns8250_read_from_device(ns8250_t *ns) 643 { 644 ioport8_t *port = ns->port; 651 645 bool cont = true; 652 646 653 647 while (cont) { 654 fibril_mutex_lock(& data->mutex);648 fibril_mutex_lock(&ns->mutex); 655 649 656 650 cont = ns8250_received(port); … … 658 652 uint8_t val = ns8250_read_8(port); 659 653 660 if ( data->client_connected) {661 if (!buf_push_back(& data->input_buffer, val)) {654 if (ns->client_connected) { 655 if (!buf_push_back(&ns->input_buffer, val)) { 662 656 printf(NAME ": buffer overflow on " 663 "%s.\n", dev->name);657 "%s.\n", ns->dev->name); 664 658 } else { 665 659 printf(NAME ": the character %c saved " 666 660 "to the buffer of %s.\n", 667 val, dev->name);661 val, ns->dev->name); 668 662 } 669 663 } 670 664 } 671 665 672 fibril_mutex_unlock(& data->mutex);666 fibril_mutex_unlock(&ns->mutex); 673 667 fibril_yield(); 674 668 } … … 682 676 * @param dev The serial port device. 683 677 */ 684 static inline void ns8250_interrupt_handler(d evice_t *dev, ipc_callid_t iid,678 static inline void ns8250_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid, 685 679 ipc_call_t *icall) 686 680 { 687 ns8250_read_from_device( dev);681 ns8250_read_from_device(NS8250_FROM_DEV(dev)); 688 682 } 689 683 690 684 /** Register the interrupt handler for the device. 691 685 * 686 * @param ns Serial port device 687 */ 688 static inline int ns8250_register_interrupt_handler(ns8250_t *ns) 689 { 690 return register_interrupt_handler(ns->dev, ns->irq, 691 ns8250_interrupt_handler, NULL); 692 } 693 694 /** Unregister the interrupt handler for the device. 695 * 696 * @param ns Serial port device 697 */ 698 static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns) 699 { 700 return unregister_interrupt_handler(ns->dev, ns->irq); 701 } 702 703 /** The add_device callback method of the serial port driver. 704 * 705 * Probe and initialize the newly added device. 706 * 692 707 * @param dev The serial port device. 693 708 */ 694 static inline int ns8250_register_interrupt_handler(device_t *dev) 695 { 696 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 697 698 return register_interrupt_handler(dev, data->irq, 699 ns8250_interrupt_handler, NULL); 700 } 701 702 /** Unregister the interrupt handler for the device. 703 * 704 * @param dev The serial port device. 705 */ 706 static inline int ns8250_unregister_interrupt_handler(device_t *dev) 707 { 708 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 709 710 return unregister_interrupt_handler(dev, data->irq); 711 } 712 713 /** The add_device callback method of the serial port driver. 714 * 715 * Probe and initialize the newly added device. 716 * 717 * @param dev The serial port device. 718 */ 719 static int ns8250_add_device(device_t *dev) 720 { 709 static int ns8250_add_device(ddf_dev_t *dev) 710 { 711 ns8250_t *ns = NULL; 712 ddf_fun_t *fun = NULL; 713 bool need_cleanup = false; 714 int rc; 715 721 716 printf(NAME ": ns8250_add_device %s (handle = %d)\n", 722 717 dev->name, (int) dev->handle); 723 718 724 int res = ns8250_dev_initialize(dev); 725 if (res != EOK) 726 return res; 727 728 if (!ns8250_pio_enable(dev)) { 729 ns8250_dev_cleanup(dev); 730 return EADDRNOTAVAIL; 719 /* Allocate soft-state for the device */ 720 ns = ns8250_new(); 721 if (ns == NULL) { 722 rc = ENOMEM; 723 goto fail; 724 } 725 726 ns->dev = dev; 727 dev->driver_data = ns; 728 729 rc = ns8250_dev_initialize(ns); 730 if (rc != EOK) 731 goto fail; 732 733 need_cleanup = true; 734 735 if (!ns8250_pio_enable(ns)) { 736 rc = EADDRNOTAVAIL; 737 goto fail; 731 738 } 732 739 733 740 /* Find out whether the device is present. */ 734 if (!ns8250_dev_probe( dev)) {735 ns8250_dev_cleanup(dev);736 return ENOENT;741 if (!ns8250_dev_probe(ns)) { 742 rc = ENOENT; 743 goto fail; 737 744 } 738 745 739 746 /* Serial port initialization (baud rate etc.). */ 740 ns8250_initialize_port( dev);747 ns8250_initialize_port(ns); 741 748 742 749 /* Register interrupt handler. */ 743 if (ns8250_register_interrupt_handler( dev) != EOK) {750 if (ns8250_register_interrupt_handler(ns) != EOK) { 744 751 printf(NAME ": failed to register interrupt handler.\n"); 745 ns8250_dev_cleanup(dev);746 return res;752 rc = EADDRNOTAVAIL; 753 goto fail; 747 754 } 748 755 749 756 /* Enable interrupt. */ 750 r es = ns8250_interrupt_enable(dev);751 if (r es!= EOK) {757 rc = ns8250_interrupt_enable(ns); 758 if (rc != EOK) { 752 759 printf(NAME ": failed to enable the interrupt. Error code = " 753 "%d.\n", res); 754 ns8250_dev_cleanup(dev); 755 ns8250_unregister_interrupt_handler(dev); 756 return res; 760 "%d.\n", rc); 761 goto fail; 762 } 763 764 fun = ddf_fun_create(dev, fun_exposed, "a"); 765 if (fun == NULL) { 766 printf(NAME ": error creating function.\n"); 767 goto fail; 757 768 } 758 769 759 770 /* Set device operations. */ 760 dev->ops = &ns8250_dev_ops; 761 762 add_device_to_class(dev, "serial"); 771 fun->ops = &ns8250_dev_ops; 772 rc = ddf_fun_bind(fun); 773 if (rc != EOK) { 774 printf(NAME ": error binding function.\n"); 775 goto fail; 776 } 777 778 ns->fun = fun; 779 780 ddf_fun_add_to_class(fun, "serial"); 763 781 764 782 printf(NAME ": the %s device has been successfully initialized.\n", … … 766 784 767 785 return EOK; 786 fail: 787 if (fun != NULL) 788 ddf_fun_destroy(fun); 789 if (need_cleanup) 790 ns8250_dev_cleanup(ns); 791 if (ns != NULL) 792 ns8250_delete(ns); 793 return rc; 768 794 } 769 795 … … 775 801 * @param dev The device. 776 802 */ 777 static int ns8250_open(d evice_t *dev)778 { 779 ns8250_ dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;803 static int ns8250_open(ddf_fun_t *fun) 804 { 805 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 780 806 int res; 781 807 … … 788 814 } 789 815 fibril_mutex_unlock(&data->mutex); 790 816 791 817 return res; 792 818 } … … 799 825 * @param dev The device. 800 826 */ 801 static void ns8250_close(d evice_t *dev)802 { 803 ns8250_ dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;827 static void ns8250_close(ddf_fun_t *fun) 828 { 829 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 804 830 805 831 fibril_mutex_lock(&data->mutex); … … 823 849 */ 824 850 static void 825 ns8250_get_props(d evice_t *dev, unsigned int *baud_rate, unsigned int *parity,851 ns8250_get_props(ddf_dev_t *dev, unsigned int *baud_rate, unsigned int *parity, 826 852 unsigned int *word_length, unsigned int* stop_bits) 827 853 { 828 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;854 ns8250_t *data = (ns8250_t *) dev->driver_data; 829 855 ioport8_t *port = data->port; 830 856 … … 850 876 * @param stop_bits The number of stop bits to be used. 851 877 */ 852 static int ns8250_set_props(d evice_t *dev, unsigned int baud_rate,878 static int ns8250_set_props(ddf_dev_t *dev, unsigned int baud_rate, 853 879 unsigned int parity, unsigned int word_length, unsigned int stop_bits) 854 880 { … … 857 883 stop_bits); 858 884 859 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;885 ns8250_t *data = (ns8250_t *) dev->driver_data; 860 886 ioport8_t *port = data->port; 861 887 int ret; … … 877 903 * Configure the parameters of the serial communication. 878 904 */ 879 static void ns8250_default_handler(d evice_t *dev, ipc_callid_t callid,905 static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid, 880 906 ipc_call_t *call) 881 907 { … … 886 912 switch (method) { 887 913 case SERIAL_GET_COM_PROPS: 888 ns8250_get_props( dev, &baud_rate, &parity, &word_length,914 ns8250_get_props(fun->dev, &baud_rate, &parity, &word_length, 889 915 &stop_bits); 890 ipc_answer_4(callid, EOK, baud_rate, parity, word_length,916 async_answer_4(callid, EOK, baud_rate, parity, word_length, 891 917 stop_bits); 892 918 break; … … 897 923 word_length = IPC_GET_ARG3(*call); 898 924 stop_bits = IPC_GET_ARG4(*call); 899 ret = ns8250_set_props( dev, baud_rate, parity, word_length,925 ret = ns8250_set_props(fun->dev, baud_rate, parity, word_length, 900 926 stop_bits); 901 ipc_answer_0(callid, ret);927 async_answer_0(callid, ret); 902 928 break; 903 929 904 930 default: 905 ipc_answer_0(callid, ENOTSUP);931 async_answer_0(callid, ENOTSUP); 906 932 } 907 933 } … … 925 951 printf(NAME ": HelenOS serial port driver\n"); 926 952 ns8250_init(); 927 return d river_main(&ns8250_driver);953 return ddf_driver_main(&ns8250_driver); 928 954 } 929 955 -
uspace/drv/pciintel/pci.c
r976f546 r19a1800 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 44 45 #include <ctype.h> 45 46 #include <macros.h> 46 47 #include <driver.h> 47 #include <str_error.h> 48 49 #include <ddf/driver.h> 48 50 #include <devman.h> 49 51 #include <ipc/devman.h> 50 52 #include <ipc/dev_iface.h> 53 #include <ipc/irc.h> 54 #include <ipc/ns.h> 55 #include <ipc/services.h> 56 #include <sysinfo.h> 51 57 #include <ops/hw_res.h> 52 58 #include <device/hw_res.h> … … 61 67 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 62 68 63 static hw_resource_list_t *pciintel_get_child_resources(device_t *dev) 64 { 65 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 66 67 if (dev_data == NULL) 69 /** Obtain PCI function soft-state from DDF function node */ 70 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 71 72 /** Obtain PCI bus soft-state from DDF device node */ 73 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 74 75 /** Obtain PCI bus soft-state from function soft-state */ 76 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 77 78 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) 79 { 80 pci_fun_t *fun = PCI_FUN(fnode); 81 82 if (fun == NULL) 68 83 return NULL; 69 return &dev_data->hw_resources; 70 } 71 72 static bool pciintel_enable_child_interrupt(device_t *dev) 73 { 74 /* TODO */ 75 76 return false; 77 } 78 79 static hw_res_ops_t pciintel_child_hw_res_ops = { 80 &pciintel_get_child_resources, 81 &pciintel_enable_child_interrupt 84 return &fun->hw_resources; 85 } 86 87 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 88 { 89 /* This is an old ugly way, copied from ne2000 driver */ 90 assert(fnode); 91 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data; 92 93 sysarg_t apic; 94 sysarg_t i8259; 95 int irc_phone = -1; 96 int irc_service = 0; 97 98 if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) { 99 irc_service = SERVICE_APIC; 100 } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) { 101 irc_service = SERVICE_I8259; 102 } 103 104 if (irc_service) { 105 while (irc_phone < 0) 106 irc_phone = service_connect_blocking(irc_service, 0, 0); 107 } else { 108 return false; 109 } 110 111 size_t i; 112 for (i = 0; i < dev_data->hw_resources.count; i++) { 113 if (dev_data->hw_resources.resources[i].type == INTERRUPT) { 114 int irq = dev_data->hw_resources.resources[i].res.interrupt.irq; 115 async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq); 116 } 117 } 118 119 async_hangup(irc_phone); 120 return true; 121 } 122 123 static hw_res_ops_t pciintel_hw_res_ops = { 124 &pciintel_get_resources, 125 &pciintel_enable_interrupt 82 126 }; 83 127 84 static d evice_ops_t pci_child_ops;85 86 static int pci_add_device(d evice_t *);87 88 /** The pci bus driver's standard operations.*/128 static ddf_dev_ops_t pci_fun_ops; 129 130 static int pci_add_device(ddf_dev_t *); 131 132 /** PCI bus driver standard operations */ 89 133 static driver_ops_t pci_ops = { 90 134 .add_device = &pci_add_device 91 135 }; 92 136 93 /** The pci bus driver structure.*/137 /** PCI bus driver structure */ 94 138 static driver_t pci_driver = { 95 139 .name = NAME, … … 97 141 }; 98 142 99 typedef struct pciintel_bus_data { 100 uint32_t conf_io_addr; 101 void *conf_data_port; 102 void *conf_addr_port; 103 fibril_mutex_t conf_mutex; 104 } pci_bus_data_t; 105 106 static pci_bus_data_t *create_pci_bus_data(void) 107 { 108 pci_bus_data_t *bus_data; 109 110 bus_data = (pci_bus_data_t *) malloc(sizeof(pci_bus_data_t)); 111 if (bus_data != NULL) { 112 memset(bus_data, 0, sizeof(pci_bus_data_t)); 113 fibril_mutex_initialize(&bus_data->conf_mutex); 114 } 115 116 return bus_data; 117 } 118 119 static void delete_pci_bus_data(pci_bus_data_t *bus_data) 120 { 121 free(bus_data); 122 } 123 124 static void pci_conf_read(device_t *dev, int reg, uint8_t *buf, size_t len) 125 { 126 assert(dev->parent != NULL); 127 128 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 129 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 130 131 fibril_mutex_lock(&bus_data->conf_mutex); 143 static pci_bus_t *pci_bus_new(void) 144 { 145 pci_bus_t *bus; 146 147 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t)); 148 if (bus == NULL) 149 return NULL; 150 151 fibril_mutex_initialize(&bus->conf_mutex); 152 return bus; 153 } 154 155 static void pci_bus_delete(pci_bus_t *bus) 156 { 157 assert(bus != NULL); 158 free(bus); 159 } 160 161 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 162 { 163 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 164 165 fibril_mutex_lock(&bus->conf_mutex); 132 166 133 167 uint32_t conf_addr; 134 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);135 void *addr = bus _data->conf_data_port + (reg & 3);136 137 pio_write_32(bus _data->conf_addr_port, conf_addr);168 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 169 void *addr = bus->conf_data_port + (reg & 3); 170 171 pio_write_32(bus->conf_addr_port, conf_addr); 138 172 139 173 switch (len) { … … 149 183 } 150 184 151 fibril_mutex_unlock(&bus_data->conf_mutex); 152 } 153 154 static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len) 155 { 156 assert(dev->parent != NULL); 157 158 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 159 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 160 161 fibril_mutex_lock(&bus_data->conf_mutex); 185 fibril_mutex_unlock(&bus->conf_mutex); 186 } 187 188 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 189 { 190 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 191 192 fibril_mutex_lock(&bus->conf_mutex); 162 193 163 194 uint32_t conf_addr; 164 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);165 void *addr = bus _data->conf_data_port + (reg & 3);166 167 pio_write_32(bus _data->conf_addr_port, conf_addr);195 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 196 void *addr = bus->conf_data_port + (reg & 3); 197 198 pio_write_32(bus->conf_addr_port, conf_addr); 168 199 169 200 switch (len) { … … 179 210 } 180 211 181 fibril_mutex_unlock(&bus _data->conf_mutex);182 } 183 184 uint8_t pci_conf_read_8( device_t *dev, int reg)212 fibril_mutex_unlock(&bus->conf_mutex); 213 } 214 215 uint8_t pci_conf_read_8(pci_fun_t *fun, int reg) 185 216 { 186 217 uint8_t res; 187 pci_conf_read( dev, reg, &res, 1);218 pci_conf_read(fun, reg, &res, 1); 188 219 return res; 189 220 } 190 221 191 uint16_t pci_conf_read_16( device_t *dev, int reg)222 uint16_t pci_conf_read_16(pci_fun_t *fun, int reg) 192 223 { 193 224 uint16_t res; 194 pci_conf_read( dev, reg, (uint8_t *) &res, 2);225 pci_conf_read(fun, reg, (uint8_t *) &res, 2); 195 226 return res; 196 227 } 197 228 198 uint32_t pci_conf_read_32( device_t *dev, int reg)229 uint32_t pci_conf_read_32(pci_fun_t *fun, int reg) 199 230 { 200 231 uint32_t res; 201 pci_conf_read( dev, reg, (uint8_t *) &res, 4);232 pci_conf_read(fun, reg, (uint8_t *) &res, 4); 202 233 return res; 203 234 } 204 235 205 void pci_conf_write_8(device_t *dev, int reg, uint8_t val) 206 { 207 pci_conf_write(dev, reg, (uint8_t *) &val, 1); 208 } 209 210 void pci_conf_write_16(device_t *dev, int reg, uint16_t val) 211 { 212 pci_conf_write(dev, reg, (uint8_t *) &val, 2); 213 } 214 215 void pci_conf_write_32(device_t *dev, int reg, uint32_t val) 216 { 217 pci_conf_write(dev, reg, (uint8_t *) &val, 4); 218 } 219 220 void create_pci_match_ids(device_t *dev) 221 { 222 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 223 match_id_t *match_id = NULL; 236 void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val) 237 { 238 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 239 } 240 241 void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val) 242 { 243 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 244 } 245 246 void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val) 247 { 248 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 249 } 250 251 void pci_fun_create_match_ids(pci_fun_t *fun) 252 { 224 253 char *match_id_str; 225 226 match_id = create_match_id(); 227 if (match_id != NULL) { 228 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 229 dev_data->vendor_id, dev_data->device_id); 230 match_id->id = match_id_str; 231 match_id->score = 90; 232 add_match_id(&dev->match_ids, match_id); 233 } 234 254 int rc; 255 256 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 257 fun->vendor_id, fun->device_id); 258 259 if (match_id_str == NULL) { 260 printf(NAME ": out of memory creating match ID.\n"); 261 return; 262 } 263 264 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 265 if (rc != EOK) { 266 printf(NAME ": error adding match ID: %s\n", 267 str_error(rc)); 268 } 269 235 270 /* TODO add more ids (with subsys ids, using class id etc.) */ 236 271 } 237 272 238 void 239 pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io) 240 { 241 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 242 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 273 void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size, 274 bool io) 275 { 276 hw_resource_list_t *hw_res_list = &fun->hw_resources; 243 277 hw_resource_t *hw_resources = hw_res_list->resources; 244 278 size_t count = hw_res_list->count; … … 265 299 * address add it to the devices hw resource list. 266 300 * 267 * @param dev The pci device.301 * @param fun PCI function 268 302 * @param addr The address of the BAR in the PCI configuration address space of 269 * the device .270 * @return The addr the address of the BAR which should be read next .303 * the device 304 * @return The addr the address of the BAR which should be read next 271 305 */ 272 int pci_read_bar( device_t *dev, int addr)273 { 306 int pci_read_bar(pci_fun_t *fun, int addr) 307 { 274 308 /* Value of the BAR */ 275 309 uint32_t val, mask; … … 285 319 286 320 /* Get the value of the BAR. */ 287 val = pci_conf_read_32(dev, addr); 321 val = pci_conf_read_32(fun, addr); 322 323 #define IO_MASK (~0x3) 324 #define MEM_MASK (~0xf) 288 325 289 326 io = (bool) (val & 1); 290 327 if (io) { 291 328 addrw64 = false; 329 mask = IO_MASK; 292 330 } else { 331 mask = MEM_MASK; 293 332 switch ((val >> 1) & 3) { 294 333 case 0: … … 305 344 306 345 /* Get the address mask. */ 307 pci_conf_write_32( dev, addr, 0xffffffff);308 mask = pci_conf_read_32(dev, addr);346 pci_conf_write_32(fun, addr, 0xffffffff); 347 mask &= pci_conf_read_32(fun, addr); 309 348 310 349 /* Restore the original value. */ 311 pci_conf_write_32( dev, addr, val);312 val = pci_conf_read_32( dev, addr);350 pci_conf_write_32(fun, addr, val); 351 val = pci_conf_read_32(fun, addr); 313 352 314 353 range_size = pci_bar_mask_to_size(mask); 315 354 316 355 if (addrw64) { 317 range_addr = ((uint64_t)pci_conf_read_32( dev, addr + 4) << 32) |356 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | 318 357 (val & 0xfffffff0); 319 358 } else { … … 322 361 323 362 if (range_addr != 0) { 324 printf(NAME ": device %s : ", dev->name);363 printf(NAME ": function %s : ", fun->fnode->name); 325 364 printf("address = %" PRIx64, range_addr); 326 365 printf(", size = %x\n", (unsigned int) range_size); 327 366 } 328 367 329 pci_add_range( dev, range_addr, range_size, io);368 pci_add_range(fun, range_addr, range_size, io); 330 369 331 370 if (addrw64) … … 335 374 } 336 375 337 void pci_add_interrupt(device_t *dev, int irq) 338 { 339 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 340 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 376 void pci_add_interrupt(pci_fun_t *fun, int irq) 377 { 378 hw_resource_list_t *hw_res_list = &fun->hw_resources; 341 379 hw_resource_t *hw_resources = hw_res_list->resources; 342 380 size_t count = hw_res_list->count; … … 350 388 hw_res_list->count++; 351 389 352 printf(NAME ": device %s uses irq %x.\n", dev->name, irq);353 } 354 355 void pci_read_interrupt( device_t *dev)356 { 357 uint8_t irq = pci_conf_read_8( dev, PCI_BRIDGE_INT_LINE);390 printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq); 391 } 392 393 void pci_read_interrupt(pci_fun_t *fun) 394 { 395 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 358 396 if (irq != 0xff) 359 pci_add_interrupt( dev, irq);397 pci_add_interrupt(fun, irq); 360 398 } 361 399 362 400 /** Enumerate (recursively) and register the devices connected to a pci bus. 363 401 * 364 * @param parent The host-to-pci bridge device.365 * @param bus_num The bus number.402 * @param bus Host-to-PCI bridge 403 * @param bus_num Bus number 366 404 */ 367 void pci_bus_scan(device_t *parent, int bus_num) 368 { 369 device_t *dev = create_device(); 370 pci_dev_data_t *dev_data = create_pci_dev_data(); 371 dev->driver_data = dev_data; 372 dev->parent = parent; 405 void pci_bus_scan(pci_bus_t *bus, int bus_num) 406 { 407 ddf_fun_t *fnode; 408 pci_fun_t *fun; 373 409 374 410 int child_bus = 0; 375 411 int dnum, fnum; 376 412 bool multi; 377 uint8_t header_type; 413 uint8_t header_type; 414 415 fun = pci_fun_new(bus); 378 416 379 417 for (dnum = 0; dnum < 32; dnum++) { 380 418 multi = true; 381 419 for (fnum = 0; multi && fnum < 8; fnum++) { 382 init_pci_dev_data(dev_data, bus_num, dnum, fnum);383 dev_data->vendor_id = pci_conf_read_16(dev,420 pci_fun_init(fun, bus_num, dnum, fnum); 421 fun->vendor_id = pci_conf_read_16(fun, 384 422 PCI_VENDOR_ID); 385 dev_data->device_id = pci_conf_read_16(dev,423 fun->device_id = pci_conf_read_16(fun, 386 424 PCI_DEVICE_ID); 387 if ( dev_data->vendor_id == 0xffff) {425 if (fun->vendor_id == 0xffff) { 388 426 /* 389 427 * The device is not present, go on scanning the … … 396 434 } 397 435 398 header_type = pci_conf_read_8( dev, PCI_HEADER_TYPE);436 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 399 437 if (fnum == 0) { 400 438 /* Is the device multifunction? */ … … 404 442 header_type = header_type & 0x7F; 405 443 406 create_pci_dev_name(dev); 407 408 pci_alloc_resource_list(dev); 409 pci_read_bars(dev); 410 pci_read_interrupt(dev); 411 412 dev->ops = &pci_child_ops; 413 414 printf(NAME ": adding new child device %s.\n", 415 dev->name); 416 417 create_pci_match_ids(dev); 418 419 if (child_device_register(dev, parent) != EOK) { 420 pci_clean_resource_list(dev); 421 clean_match_ids(&dev->match_ids); 422 free((char *) dev->name); 423 dev->name = NULL; 444 char *fun_name = pci_fun_create_name(fun); 445 if (fun_name == NULL) { 446 printf(NAME ": out of memory.\n"); 447 return; 448 } 449 450 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 451 if (fnode == NULL) { 452 printf(NAME ": error creating function.\n"); 453 return; 454 } 455 456 free(fun_name); 457 fun->fnode = fnode; 458 459 pci_alloc_resource_list(fun); 460 pci_read_bars(fun); 461 pci_read_interrupt(fun); 462 463 fnode->ops = &pci_fun_ops; 464 fnode->driver_data = fun; 465 466 printf(NAME ": adding new function %s.\n", 467 fnode->name); 468 469 pci_fun_create_match_ids(fun); 470 471 if (ddf_fun_bind(fnode) != EOK) { 472 pci_clean_resource_list(fun); 473 clean_match_ids(&fnode->match_ids); 474 free((char *) fnode->name); 475 fnode->name = NULL; 424 476 continue; 425 477 } … … 427 479 if (header_type == PCI_HEADER_TYPE_BRIDGE || 428 480 header_type == PCI_HEADER_TYPE_CARDBUS) { 429 child_bus = pci_conf_read_8( dev,481 child_bus = pci_conf_read_8(fun, 430 482 PCI_BRIDGE_SEC_BUS_NUM); 431 483 printf(NAME ": device is pci-to-pci bridge, " 432 484 "secondary bus number = %d.\n", bus_num); 433 485 if (child_bus > bus_num) 434 pci_bus_scan( parent, child_bus);486 pci_bus_scan(bus, child_bus); 435 487 } 436 488 437 /* Alloc new aux. dev. structure. */ 438 dev = create_device(); 439 dev_data = create_pci_dev_data(); 440 dev->driver_data = dev_data; 441 dev->parent = parent; 489 fun = pci_fun_new(bus); 442 490 } 443 491 } 444 492 445 if (dev_data->vendor_id == 0xffff) { 446 delete_device(dev); 447 /* Free the auxiliary device structure. */ 448 delete_pci_dev_data(dev_data); 449 } 450 } 451 452 static int pci_add_device(device_t *dev) 453 { 493 if (fun->vendor_id == 0xffff) { 494 /* Free the auxiliary function structure. */ 495 pci_fun_delete(fun); 496 } 497 } 498 499 static int pci_add_device(ddf_dev_t *dnode) 500 { 501 pci_bus_t *bus = NULL; 502 ddf_fun_t *ctl = NULL; 503 bool got_res = false; 454 504 int rc; 455 505 456 506 printf(NAME ": pci_add_device\n"); 457 458 pci_bus_data_t *bus_data = create_pci_bus_data(); 459 if (bus_data == NULL) { 507 dnode->parent_phone = -1; 508 509 bus = pci_bus_new(); 510 if (bus == NULL) { 460 511 printf(NAME ": pci_add_device allocation failed.\n"); 461 return ENOMEM; 462 } 463 464 dev->parent_phone = devman_parent_device_connect(dev->handle, 512 rc = ENOMEM; 513 goto fail; 514 } 515 bus->dnode = dnode; 516 dnode->driver_data = bus; 517 518 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 465 519 IPC_FLAG_BLOCKING); 466 if (d ev->parent_phone < 0) {520 if (dnode->parent_phone < 0) { 467 521 printf(NAME ": pci_add_device failed to connect to the " 468 522 "parent's driver.\n"); 469 delete_pci_bus_data(bus_data);470 return dev->parent_phone;523 rc = dnode->parent_phone; 524 goto fail; 471 525 } 472 526 473 527 hw_resource_list_t hw_resources; 474 528 475 rc = hw_res_get_resource_list(d ev->parent_phone, &hw_resources);529 rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources); 476 530 if (rc != EOK) { 477 531 printf(NAME ": pci_add_device failed to get hw resources for " 478 532 "the device.\n"); 479 delete_pci_bus_data(bus_data); 480 ipc_hangup(dev->parent_phone); 481 return rc; 482 } 533 goto fail; 534 } 535 got_res = true; 483 536 484 537 printf(NAME ": conf_addr = %" PRIx64 ".\n", … … 489 542 assert(hw_resources.resources[0].res.io_range.size == 8); 490 543 491 bus _data->conf_io_addr =544 bus->conf_io_addr = 492 545 (uint32_t) hw_resources.resources[0].res.io_range.address; 493 546 494 if (pio_enable((void *)(uintptr_t)bus _data->conf_io_addr, 8,495 &bus _data->conf_addr_port)) {547 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 548 &bus->conf_addr_port)) { 496 549 printf(NAME ": failed to enable configuration ports.\n"); 497 delete_pci_bus_data(bus_data); 498 ipc_hangup(dev->parent_phone); 550 rc = EADDRNOTAVAIL; 551 goto fail; 552 } 553 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 554 555 /* Make the bus device more visible. It has no use yet. */ 556 printf(NAME ": adding a 'ctl' function\n"); 557 558 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 559 if (ctl == NULL) { 560 printf(NAME ": error creating control function.\n"); 561 rc = ENOMEM; 562 goto fail; 563 } 564 565 rc = ddf_fun_bind(ctl); 566 if (rc != EOK) { 567 printf(NAME ": error binding control function.\n"); 568 goto fail; 569 } 570 571 /* Enumerate functions. */ 572 printf(NAME ": scanning the bus\n"); 573 pci_bus_scan(bus, 0); 574 575 hw_res_clean_resource_list(&hw_resources); 576 577 return EOK; 578 579 fail: 580 if (bus != NULL) 581 pci_bus_delete(bus); 582 if (dnode->parent_phone >= 0) 583 async_hangup(dnode->parent_phone); 584 if (got_res) 499 585 hw_res_clean_resource_list(&hw_resources); 500 return EADDRNOTAVAIL; 501 } 502 bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4; 503 504 dev->driver_data = bus_data; 505 506 /* Enumerate child devices. */ 507 printf(NAME ": scanning the bus\n"); 508 pci_bus_scan(dev, 0); 509 510 hw_res_clean_resource_list(&hw_resources); 511 512 return EOK; 586 if (ctl != NULL) 587 ddf_fun_destroy(ctl); 588 589 return rc; 513 590 } 514 591 515 592 static void pciintel_init(void) 516 593 { 517 pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops; 518 } 519 520 pci_dev_data_t *create_pci_dev_data(void) 521 { 522 pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t)); 523 524 if (res != NULL) 525 memset(res, 0, sizeof(pci_dev_data_t)); 526 return res; 527 } 528 529 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn) 530 { 531 dev_data->bus = bus; 532 dev_data->dev = dev; 533 dev_data->fn = fn; 534 } 535 536 void delete_pci_dev_data(pci_dev_data_t *dev_data) 537 { 538 if (dev_data != NULL) { 539 hw_res_clean_resource_list(&dev_data->hw_resources); 540 free(dev_data); 541 } 542 } 543 544 void create_pci_dev_name(device_t *dev) 545 { 546 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 594 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 595 } 596 597 pci_fun_t *pci_fun_new(pci_bus_t *bus) 598 { 599 pci_fun_t *fun; 600 601 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 602 if (fun == NULL) 603 return NULL; 604 605 fun->busptr = bus; 606 return fun; 607 } 608 609 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 610 { 611 fun->bus = bus; 612 fun->dev = dev; 613 fun->fn = fn; 614 } 615 616 void pci_fun_delete(pci_fun_t *fun) 617 { 618 assert(fun != NULL); 619 hw_res_clean_resource_list(&fun->hw_resources); 620 free(fun); 621 } 622 623 char *pci_fun_create_name(pci_fun_t *fun) 624 { 547 625 char *name = NULL; 548 626 549 asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev, 550 dev_data->fn); 551 dev->name = name; 552 } 553 554 bool pci_alloc_resource_list(device_t *dev) 555 { 556 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 557 558 dev_data->hw_resources.resources = 627 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 628 fun->fn); 629 return name; 630 } 631 632 bool pci_alloc_resource_list(pci_fun_t *fun) 633 { 634 fun->hw_resources.resources = 559 635 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 560 return dev_data->hw_resources.resources != NULL; 561 } 562 563 void pci_clean_resource_list(device_t *dev) 564 { 565 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 566 567 if (dev_data->hw_resources.resources != NULL) { 568 free(dev_data->hw_resources.resources); 569 dev_data->hw_resources.resources = NULL; 570 } 571 } 572 573 /** Read the base address registers (BARs) of the device and adds the addresses 574 * to its hw resource list. 636 return fun->hw_resources.resources != NULL; 637 } 638 639 void pci_clean_resource_list(pci_fun_t *fun) 640 { 641 if (fun->hw_resources.resources != NULL) { 642 free(fun->hw_resources.resources); 643 fun->hw_resources.resources = NULL; 644 } 645 } 646 647 /** Read the base address registers (BARs) of the function and add the addresses 648 * to its HW resource list. 575 649 * 576 * @param dev the pci device.650 * @param fun PCI function 577 651 */ 578 void pci_read_bars( device_t *dev)652 void pci_read_bars(pci_fun_t *fun) 579 653 { 580 654 /* … … 585 659 586 660 while (addr <= PCI_BASE_ADDR_5) 587 addr = pci_read_bar( dev, addr);661 addr = pci_read_bar(fun, addr); 588 662 } 589 663 590 664 size_t pci_bar_mask_to_size(uint32_t mask) 591 665 { 592 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 666 size_t size = mask & ~(mask - 1); 667 return size; 593 668 } 594 669 … … 597 672 printf(NAME ": HelenOS pci bus driver (intel method 1).\n"); 598 673 pciintel_init(); 599 return d river_main(&pci_driver);674 return ddf_driver_main(&pci_driver); 600 675 } 601 676 -
uspace/drv/pciintel/pci.h
r976f546 r19a1800 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 36 37 #define PCI_H_ 37 38 38 #include <stdlib.h> 39 #include <driver.h> 40 #include <malloc.h> 41 39 #include <ddf/driver.h> 42 40 #include "pci_regs.h" 43 41 44 42 #define PCI_MAX_HW_RES 8 45 43 46 typedef struct pci_dev_data { 44 typedef struct pciintel_bus { 45 /** DDF device node */ 46 ddf_dev_t *dnode; 47 uint32_t conf_io_addr; 48 void *conf_data_port; 49 void *conf_addr_port; 50 fibril_mutex_t conf_mutex; 51 } pci_bus_t; 52 53 typedef struct pci_fun_data { 54 pci_bus_t *busptr; 55 ddf_fun_t *fnode; 56 47 57 int bus; 48 58 int dev; … … 51 61 int device_id; 52 62 hw_resource_list_t hw_resources; 53 } pci_ dev_data_t;63 } pci_fun_t; 54 64 55 extern void create_pci_match_ids(device_t *);65 extern void pci_fun_create_match_ids(pci_fun_t *); 56 66 57 extern uint8_t pci_conf_read_8( device_t *, int);58 extern uint16_t pci_conf_read_16( device_t *, int);59 extern uint32_t pci_conf_read_32( device_t *, int);60 extern void pci_conf_write_8( device_t *, int, uint8_t);61 extern void pci_conf_write_16( device_t *, int, uint16_t);62 extern void pci_conf_write_32( device_t *, int, uint32_t);67 extern uint8_t pci_conf_read_8(pci_fun_t *, int); 68 extern uint16_t pci_conf_read_16(pci_fun_t *, int); 69 extern uint32_t pci_conf_read_32(pci_fun_t *, int); 70 extern void pci_conf_write_8(pci_fun_t *, int, uint8_t); 71 extern void pci_conf_write_16(pci_fun_t *, int, uint16_t); 72 extern void pci_conf_write_32(pci_fun_t *, int, uint32_t); 63 73 64 extern void pci_add_range( device_t *, uint64_t, size_t, bool);65 extern int pci_read_bar( device_t *, int);66 extern void pci_read_interrupt( device_t *);67 extern void pci_add_interrupt( device_t *, int);74 extern void pci_add_range(pci_fun_t *, uint64_t, size_t, bool); 75 extern int pci_read_bar(pci_fun_t *, int); 76 extern void pci_read_interrupt(pci_fun_t *); 77 extern void pci_add_interrupt(pci_fun_t *, int); 68 78 69 extern void pci_bus_scan(device_t *, int); 79 extern pci_fun_t *pci_fun_new(pci_bus_t *); 80 extern void pci_fun_init(pci_fun_t *, int, int, int); 81 extern void pci_fun_delete(pci_fun_t *); 82 extern char *pci_fun_create_name(pci_fun_t *); 70 83 71 extern pci_dev_data_t *create_pci_dev_data(void); 72 extern void init_pci_dev_data(pci_dev_data_t *, int, int, int); 73 extern void delete_pci_dev_data(pci_dev_data_t *); 74 extern void create_pci_dev_name(device_t *); 84 extern void pci_bus_scan(pci_bus_t *, int); 75 85 76 extern bool pci_alloc_resource_list( device_t *);77 extern void pci_clean_resource_list( device_t *);86 extern bool pci_alloc_resource_list(pci_fun_t *); 87 extern void pci_clean_resource_list(pci_fun_t *); 78 88 79 extern void pci_read_bars( device_t *);89 extern void pci_read_bars(pci_fun_t *); 80 90 extern size_t pci_bar_mask_to_size(uint32_t); 81 91 -
uspace/drv/root/root.c
r976f546 r19a1800 2 2 * Copyright (c) 2010 Lenka Trochtova 3 3 * Copyright (c) 2010 Vojtech Horky 4 * Copyright (c) 2011 Jiri Svoboda 4 5 * All rights reserved. 5 6 * … … 44 45 #include <stdlib.h> 45 46 #include <str.h> 47 #include <str_error.h> 46 48 #include <ctype.h> 47 49 #include <macros.h> … … 49 51 #include <sysinfo.h> 50 52 51 #include <d river.h>53 #include <ddf/driver.h> 52 54 #include <devman.h> 53 55 #include <ipc/devman.h> … … 55 57 #define NAME "root" 56 58 57 #define PLATFORM_ DEVICE_NAME "hw"58 #define PLATFORM_ DEVICE_MATCH_ID_FMT "platform/%s"59 #define PLATFORM_ DEVICE_MATCH_SCORE 10060 61 #define VIRTUAL_ DEVICE_NAME "virt"62 #define VIRTUAL_ DEVICE_MATCH_ID "rootvirt"63 #define VIRTUAL_ DEVICE_MATCH_SCORE 10064 65 static int root_add_device(d evice_t *dev);59 #define PLATFORM_FUN_NAME "hw" 60 #define PLATFORM_FUN_MATCH_ID_FMT "platform/%s" 61 #define PLATFORM_FUN_MATCH_SCORE 100 62 63 #define VIRTUAL_FUN_NAME "virt" 64 #define VIRTUAL_FUN_MATCH_ID "rootvirt" 65 #define VIRTUAL_FUN_MATCH_SCORE 100 66 67 static int root_add_device(ddf_dev_t *dev); 66 68 67 69 /** The root device driver's standard operations. */ … … 76 78 }; 77 79 78 /** Create the device which represents the root of virtual device tree. 79 * 80 * @param parent Parent of the newly created device. 81 * @return Error code. 82 */ 83 static int add_virtual_root_child(device_t *parent) 84 { 85 printf(NAME ": adding new child for virtual devices.\n"); 86 printf(NAME ": device node is `%s' (%d %s)\n", VIRTUAL_DEVICE_NAME, 87 VIRTUAL_DEVICE_MATCH_SCORE, VIRTUAL_DEVICE_MATCH_ID); 88 89 int res = child_device_register_wrapper(parent, VIRTUAL_DEVICE_NAME, 90 VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE, 91 NULL); 92 93 return res; 94 } 95 96 /** Create the device which represents the root of HW device tree. 97 * 98 * @param parent Parent of the newly created device. 99 * @return 0 on success, negative error number otherwise. 100 */ 101 static int add_platform_child(device_t *parent) 80 /** Create the function which represents the root of virtual device tree. 81 * 82 * @param dev Device 83 * @return EOK on success or negative error code 84 */ 85 static int add_virtual_root_fun(ddf_dev_t *dev) 86 { 87 const char *name = VIRTUAL_FUN_NAME; 88 ddf_fun_t *fun; 89 int rc; 90 91 printf(NAME ": adding new function for virtual devices.\n"); 92 printf(NAME ": function node is `%s' (%d %s)\n", name, 93 VIRTUAL_FUN_MATCH_SCORE, VIRTUAL_FUN_MATCH_ID); 94 95 fun = ddf_fun_create(dev, fun_inner, name); 96 if (fun == NULL) { 97 printf(NAME ": error creating function %s\n", name); 98 return ENOMEM; 99 } 100 101 rc = ddf_fun_add_match_id(fun, VIRTUAL_FUN_MATCH_ID, 102 VIRTUAL_FUN_MATCH_SCORE); 103 if (rc != EOK) { 104 printf(NAME ": error adding match IDs to function %s\n", name); 105 ddf_fun_destroy(fun); 106 return rc; 107 } 108 109 rc = ddf_fun_bind(fun); 110 if (rc != EOK) { 111 printf(NAME ": error binding function %s: %s\n", name, 112 str_error(rc)); 113 ddf_fun_destroy(fun); 114 return rc; 115 } 116 117 return EOK; 118 } 119 120 /** Create the function which represents the root of HW device tree. 121 * 122 * @param dev Device 123 * @return EOK on success or negative error code 124 */ 125 static int add_platform_fun(ddf_dev_t *dev) 102 126 { 103 127 char *match_id; 104 128 char *platform; 105 129 size_t platform_size; 106 int res; 130 131 const char *name = PLATFORM_FUN_NAME; 132 ddf_fun_t *fun; 133 int rc; 107 134 108 135 /* Get platform name from sysinfo. */ 109 110 136 platform = sysinfo_get_data("platform", &platform_size); 111 137 if (platform == NULL) { … … 124 150 125 151 /* Construct match ID. */ 126 127 if (asprintf(&match_id, PLATFORM_DEVICE_MATCH_ID_FMT, platform) == -1) { 152 if (asprintf(&match_id, PLATFORM_FUN_MATCH_ID_FMT, platform) == -1) { 128 153 printf(NAME ": Memory allocation failed.\n"); 129 154 return ENOMEM; 130 155 } 131 156 132 /* Add child. */ 133 134 printf(NAME ": adding new child for platform device.\n"); 135 printf(NAME ": device node is `%s' (%d %s)\n", PLATFORM_DEVICE_NAME, 136 PLATFORM_DEVICE_MATCH_SCORE, match_id); 137 138 res = child_device_register_wrapper(parent, PLATFORM_DEVICE_NAME, 139 match_id, PLATFORM_DEVICE_MATCH_SCORE, NULL); 140 141 return res; 157 /* Add function. */ 158 printf(NAME ": adding platform function\n"); 159 printf(NAME ": function node is `%s' (%d %s)\n", PLATFORM_FUN_NAME, 160 PLATFORM_FUN_MATCH_SCORE, match_id); 161 162 fun = ddf_fun_create(dev, fun_inner, name); 163 if (fun == NULL) { 164 printf(NAME ": error creating function %s\n", name); 165 return ENOMEM; 166 } 167 168 rc = ddf_fun_add_match_id(fun, match_id, PLATFORM_FUN_MATCH_SCORE); 169 if (rc != EOK) { 170 printf(NAME ": error adding match IDs to function %s\n", name); 171 ddf_fun_destroy(fun); 172 return rc; 173 } 174 175 rc = ddf_fun_bind(fun); 176 if (rc != EOK) { 177 printf(NAME ": error binding function %s: %s\n", name, 178 str_error(rc)); 179 ddf_fun_destroy(fun); 180 return rc; 181 } 182 183 return EOK; 142 184 } 143 185 … … 147 189 * of HW and pseudo devices). 148 190 */ 149 static int root_add_device(d evice_t *dev)191 static int root_add_device(ddf_dev_t *dev) 150 192 { 151 193 printf(NAME ": root_add_device, device handle=%" PRIun "\n", 152 194 dev->handle); 153 195 154 196 /* 155 197 * Register virtual devices root. … … 157 199 * vital for the system. 158 200 */ 159 add_virtual_root_ child(dev);201 add_virtual_root_fun(dev); 160 202 161 203 /* Register root device's children. */ 162 int res = add_platform_ child(dev);204 int res = add_platform_fun(dev); 163 205 if (EOK != res) 164 206 printf(NAME ": failed to add child device for platform.\n"); 165 207 166 208 return res; 167 209 } … … 170 212 { 171 213 printf(NAME ": HelenOS root device driver\n"); 172 return d river_main(&root_driver);214 return ddf_driver_main(&root_driver); 173 215 } 174 216 -
uspace/drv/rootpc/rootpc.c
r976f546 r19a1800 46 46 #include <macros.h> 47 47 48 #include <d river.h>48 #include <ddf/driver.h> 49 49 #include <devman.h> 50 50 #include <ipc/devman.h> … … 55 55 #define NAME "rootpc" 56 56 57 typedef struct rootpc_child_dev_data { 57 /** Obtain function soft-state from DDF function node */ 58 #define ROOTPC_FUN(fnode) ((rootpc_fun_t *) (fnode)->driver_data) 59 60 typedef struct rootpc_fun { 58 61 hw_resource_list_t hw_resources; 59 } rootpc_ child_dev_data_t;60 61 static int rootpc_add_device(d evice_t *dev);62 } rootpc_fun_t; 63 64 static int rootpc_add_device(ddf_dev_t *dev); 62 65 static void root_pc_init(void); 63 66 … … 82 85 }; 83 86 84 static rootpc_ child_dev_data_t pci_data = {87 static rootpc_fun_t pci_data = { 85 88 .hw_resources = { 86 89 1, … … 89 92 }; 90 93 91 static hw_resource_list_t *rootpc_get_child_resources(device_t *dev) 92 { 93 rootpc_child_dev_data_t *data; 94 95 data = (rootpc_child_dev_data_t *) dev->driver_data; 96 if (NULL == data) 97 return NULL; 98 99 return &data->hw_resources; 100 } 101 102 static bool rootpc_enable_child_interrupt(device_t *dev) 94 static hw_resource_list_t *rootpc_get_resources(ddf_fun_t *fnode) 95 { 96 rootpc_fun_t *fun = ROOTPC_FUN(fnode); 97 98 assert(fun != NULL); 99 return &fun->hw_resources; 100 } 101 102 static bool rootpc_enable_interrupt(ddf_fun_t *fun) 103 103 { 104 104 /* TODO */ … … 107 107 } 108 108 109 static hw_res_ops_t child_hw_res_ops = {110 &rootpc_get_ child_resources,111 &rootpc_enable_ child_interrupt109 static hw_res_ops_t fun_hw_res_ops = { 110 &rootpc_get_resources, 111 &rootpc_enable_interrupt 112 112 }; 113 113 114 114 /* Initialized in root_pc_init() function. */ 115 static d evice_ops_t rootpc_child_ops;115 static ddf_dev_ops_t rootpc_fun_ops; 116 116 117 117 static bool 118 rootpc_add_ child(device_t *parent, const char *name, const char *str_match_id,119 rootpc_ child_dev_data_t *drv_data)120 { 121 printf(NAME ": adding new child device'%s'.\n", name);122 123 d evice_t *child= NULL;118 rootpc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id, 119 rootpc_fun_t *fun) 120 { 121 printf(NAME ": adding new function '%s'.\n", name); 122 123 ddf_fun_t *fnode = NULL; 124 124 match_id_t *match_id = NULL; 125 125 126 126 /* Create new device. */ 127 child = create_device();128 if ( NULL == child)127 fnode = ddf_fun_create(dev, fun_inner, name); 128 if (fnode == NULL) 129 129 goto failure; 130 130 131 child->name = name; 132 child->driver_data = drv_data; 131 fnode->driver_data = fun; 133 132 134 133 /* Initialize match id list */ 135 134 match_id = create_match_id(); 136 if ( NULL == match_id)135 if (match_id == NULL) 137 136 goto failure; 138 137 139 138 match_id->id = str_match_id; 140 139 match_id->score = 100; 141 add_match_id(& child->match_ids, match_id);140 add_match_id(&fnode->match_ids, match_id); 142 141 143 142 /* Set provided operations to the device. */ 144 child->ops = &rootpc_child_ops; 145 146 /* Register child device. */ 147 if (EOK != child_device_register(child, parent)) 143 fnode->ops = &rootpc_fun_ops; 144 145 /* Register function. */ 146 if (ddf_fun_bind(fnode) != EOK) { 147 printf(NAME ": error binding function %s.\n", name); 148 148 goto failure; 149 } 149 150 150 151 return true; 151 152 152 153 failure: 153 if ( NULL != match_id)154 if (match_id != NULL) 154 155 match_id->id = NULL; 155 156 156 if (NULL != child) { 157 child->name = NULL; 158 delete_device(child); 159 } 160 161 printf(NAME ": failed to add child device '%s'.\n", name); 157 if (fnode != NULL) 158 ddf_fun_destroy(fnode); 159 160 printf(NAME ": failed to add function '%s'.\n", name); 162 161 163 162 return false; 164 163 } 165 164 166 static bool rootpc_add_ children(device_t *dev)167 { 168 return rootpc_add_ child(dev, "pci0", "intel_pci", &pci_data);165 static bool rootpc_add_functions(ddf_dev_t *dev) 166 { 167 return rootpc_add_fun(dev, "pci0", "intel_pci", &pci_data); 169 168 } 170 169 … … 175 174 * @return Zero on success, negative error number otherwise. 176 175 */ 177 static int rootpc_add_device(d evice_t *dev)176 static int rootpc_add_device(ddf_dev_t *dev) 178 177 { 179 178 printf(NAME ": rootpc_add_device, device handle = %d\n", 180 179 (int)dev->handle); 181 180 182 /* Register child devices. */183 if (!rootpc_add_ children(dev)) {184 printf(NAME ": failed to add child devices for PC platform.\n");181 /* Register functions. */ 182 if (!rootpc_add_functions(dev)) { 183 printf(NAME ": failed to add functions for PC platform.\n"); 185 184 } 186 185 … … 190 189 static void root_pc_init(void) 191 190 { 192 rootpc_ child_ops.interfaces[HW_RES_DEV_IFACE] = &child_hw_res_ops;191 rootpc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops; 193 192 } 194 193 … … 197 196 printf(NAME ": HelenOS PC platform driver\n"); 198 197 root_pc_init(); 199 return d river_main(&rootpc_driver);198 return ddf_driver_main(&rootpc_driver); 200 199 } 201 200 -
uspace/drv/rootvirt/devices.def
r976f546 r19a1800 22 22 }, 23 23 #endif 24 #ifdef CONFIG_RUN_VIRTUAL_USB_HC 24 25 /* Virtual USB host controller. */ 25 26 { … … 27 28 .match_id = "usb&hc=vhc" 28 29 }, 30 #endif -
uspace/drv/rootvirt/rootvirt.c
r976f546 r19a1800 39 39 #include <errno.h> 40 40 #include <str_error.h> 41 #include <d river.h>41 #include <ddf/driver.h> 42 42 43 43 #define NAME "rootvirt" 44 44 45 /** Virtual device entry.*/45 /** Virtual function entry */ 46 46 typedef struct { 47 /** Device name.*/47 /** Function name */ 48 48 const char *name; 49 /** Device match id.*/49 /** Function match ID */ 50 50 const char *match_id; 51 } virtual_ device_t;51 } virtual_function_t; 52 52 53 /** List of existing virtual devices.*/54 virtual_ device_t virtual_devices[] = {53 /** List of existing virtual functions */ 54 virtual_function_t virtual_functions[] = { 55 55 #include "devices.def" 56 /* Terminating item .*/56 /* Terminating item */ 57 57 { 58 58 .name = NULL, … … 61 61 }; 62 62 63 static int add_device(device_t *dev);63 static int rootvirt_add_device(ddf_dev_t *dev); 64 64 65 65 static driver_ops_t rootvirt_ops = { 66 .add_device = & add_device66 .add_device = &rootvirt_add_device 67 67 }; 68 68 … … 72 72 }; 73 73 74 /** Add childdevice.74 /** Add function to the virtual device. 75 75 * 76 * @param parent Parent device.77 * @param v irt_dev Virtual device to add.78 * @return Error code.76 * @param vdev The virtual device 77 * @param vfun Virtual function description 78 * @return EOK on success or negative error code. 79 79 */ 80 static int add_child(device_t *parent, virtual_device_t *virt_dev)80 static int rootvirt_add_fun(ddf_dev_t *vdev, virtual_function_t *vfun) 81 81 { 82 printf(NAME ": registering child device `%s' (match \"%s\")\n",83 virt_dev->name, virt_dev->match_id);82 ddf_fun_t *fun; 83 int rc; 84 84 85 int rc = child_device_register_wrapper(parent, virt_dev->name,86 v irt_dev->match_id, 10, NULL);85 printf(NAME ": registering function `%s' (match \"%s\")\n", 86 vfun->name, vfun->match_id); 87 87 88 if (rc == EOK) { 89 printf(NAME ": registered child device `%s'\n", 90 virt_dev->name); 91 } else { 92 printf(NAME ": failed to register child device `%s': %s\n", 93 virt_dev->name, str_error(rc)); 88 fun = ddf_fun_create(vdev, fun_inner, vfun->name); 89 if (fun == NULL) { 90 printf(NAME ": error creating function %s\n", vfun->name); 91 return ENOMEM; 94 92 } 95 93 96 return rc; 94 rc = ddf_fun_add_match_id(fun, vfun->match_id, 10); 95 if (rc != EOK) { 96 printf(NAME ": error adding match IDs to function %s\n", 97 vfun->name); 98 ddf_fun_destroy(fun); 99 return rc; 100 } 101 102 rc = ddf_fun_bind(fun); 103 if (rc != EOK) { 104 printf(NAME ": error binding function %s: %s\n", vfun->name, 105 str_error(rc)); 106 ddf_fun_destroy(fun); 107 return rc; 108 } 109 110 printf(NAME ": registered child device `%s'\n", vfun->name); 111 return EOK; 97 112 } 98 113 99 static int add_device(device_t *dev)114 static int rootvirt_add_device(ddf_dev_t *dev) 100 115 { 101 116 static int instances = 0; … … 109 124 } 110 125 111 printf(NAME ": add_device(name=\"%s\", handle=%d)\n", 112 dev->name, (int)dev->handle); 113 126 printf(NAME ": add_device(handle=%d)\n", (int)dev->handle); 127 114 128 /* 115 * Go through all virtual devices and try to add them.129 * Go through all virtual functions and try to add them. 116 130 * We silently ignore failures. 117 131 */ 118 virtual_ device_t *virt_dev = virtual_devices;119 while (v irt_dev->name != NULL) {120 (void) add_child(dev, virt_dev);121 v irt_dev++;132 virtual_function_t *vfun = virtual_functions; 133 while (vfun->name != NULL) { 134 (void) rootvirt_add_fun(dev, vfun); 135 vfun++; 122 136 } 123 137 … … 128 142 { 129 143 printf(NAME ": HelenOS virtual devices root driver\n"); 130 return d river_main(&rootvirt_driver);144 return ddf_driver_main(&rootvirt_driver); 131 145 } 132 146 -
uspace/drv/test1/char.c
r976f546 r19a1800 37 37 #include "test1.h" 38 38 39 static int impl_char_read(d evice_t *dev, char *buf, size_t count) {39 static int impl_char_read(ddf_fun_t *fun, char *buf, size_t count) { 40 40 memset(buf, 0, count); 41 41 return count; 42 42 } 43 43 44 static int imp_char_write(d evice_t *dev, char *buf, size_t count) {44 static int imp_char_write(ddf_fun_t *fun, char *buf, size_t count) { 45 45 return count; 46 46 } … … 51 51 }; 52 52 53 d evice_ops_t char_device_ops = {53 ddf_dev_ops_t char_device_ops = { 54 54 .interfaces[CHAR_DEV_IFACE] = &char_dev_ops 55 55 }; -
uspace/drv/test1/test1.c
r976f546 r19a1800 34 34 #include <errno.h> 35 35 #include <str_error.h> 36 #include <ddf/driver.h> 37 36 38 #include "test1.h" 37 39 38 static int add_device(device_t *dev);40 static int test1_add_device(ddf_dev_t *dev); 39 41 40 42 static driver_ops_t driver_ops = { 41 .add_device = & add_device43 .add_device = &test1_add_device 42 44 }; 43 45 44 static driver_t t he_driver = {46 static driver_t test1_driver = { 45 47 .name = NAME, 46 48 .driver_ops = &driver_ops … … 55 57 * @param score Device match score. 56 58 */ 57 static void register_child_verbose(device_t *parent, const char *message,59 static int register_fun_verbose(ddf_dev_t *parent, const char *message, 58 60 const char *name, const char *match_id, int match_score) 59 61 { 60 printf(NAME ": registering child device `%s': %s.\n",61 name, message);62 ddf_fun_t *fun; 63 int rc; 62 64 63 int rc = child_device_register_wrapper(parent, name, 64 match_id, match_score, NULL); 65 printf(NAME ": registering function `%s': %s.\n", name, message); 65 66 66 if (rc == EOK) { 67 printf(NAME ": registered child device `%s'.\n", name); 68 } else { 69 printf(NAME ": failed to register child `%s' (%s).\n", 70 name, str_error(rc)); 67 fun = ddf_fun_create(parent, fun_inner, name); 68 if (fun == NULL) { 69 printf(NAME ": error creating function %s\n", name); 70 return ENOMEM; 71 71 } 72 73 rc = ddf_fun_add_match_id(fun, match_id, match_score); 74 if (rc != EOK) { 75 printf(NAME ": error adding match IDs to function %s\n", name); 76 ddf_fun_destroy(fun); 77 return rc; 78 } 79 80 rc = ddf_fun_bind(fun); 81 if (rc != EOK) { 82 printf(NAME ": error binding function %s: %s\n", name, 83 str_error(rc)); 84 ddf_fun_destroy(fun); 85 return rc; 86 } 87 88 printf(NAME ": registered child device `%s'\n", name); 89 return EOK; 72 90 } 73 91 … … 89 107 * @return Error code reporting success of the operation. 90 108 */ 91 static int add_device(device_t *dev)109 static int test1_add_device(ddf_dev_t *dev) 92 110 { 111 ddf_fun_t *fun_a; 112 int rc; 113 93 114 printf(NAME ": add_device(name=\"%s\", handle=%d)\n", 94 115 dev->name, (int) dev->handle); 95 116 96 add_device_to_class(dev, "virtual"); 117 fun_a = ddf_fun_create(dev, fun_exposed, "a"); 118 if (fun_a == NULL) { 119 printf(NAME ": error creating function 'a'.\n"); 120 return ENOMEM; 121 } 122 123 rc = ddf_fun_bind(fun_a); 124 if (rc != EOK) { 125 printf(NAME ": error binding function 'a'.\n"); 126 return rc; 127 } 128 129 ddf_fun_add_to_class(fun_a, "virtual"); 97 130 98 131 if (str_cmp(dev->name, "null") == 0) { 99 dev->ops = &char_device_ops;100 add_device_to_class(dev, "virt-null");101 } else if ( dev->parent == NULL) {102 register_child_verbose(dev, "cloning myself ;-)", "clone",132 fun_a->ops = &char_device_ops; 133 ddf_fun_add_to_class(fun_a, "virt-null"); 134 } else if (str_cmp(dev->name, "test1") == 0) { 135 (void) register_fun_verbose(dev, "cloning myself ;-)", "clone", 103 136 "virtual&test1", 10); 104 137 } else if (str_cmp(dev->name, "clone") == 0) { 105 register_child_verbose(dev, "run by the same task", "child",138 (void) register_fun_verbose(dev, "run by the same task", "child", 106 139 "virtual&test1&child", 10); 107 140 } … … 115 148 { 116 149 printf(NAME ": HelenOS test1 virtual device driver\n"); 117 return d river_main(&the_driver);150 return ddf_driver_main(&test1_driver); 118 151 } 119 152 -
uspace/drv/test1/test1.h
r976f546 r19a1800 32 32 #define DRV_TEST1_TEST1_H_ 33 33 34 #include <d river.h>34 #include <ddf/driver.h> 35 35 36 36 #define NAME "test1" 37 37 38 extern d evice_ops_t char_device_ops;38 extern ddf_dev_ops_t char_device_ops; 39 39 40 40 #endif -
uspace/drv/test2/test2.c
r976f546 r19a1800 31 31 32 32 #include <assert.h> 33 #include <async.h> 33 34 #include <stdio.h> 34 35 #include <errno.h> 35 36 #include <str_error.h> 36 #include <d river.h>37 #include <ddf/driver.h> 37 38 38 39 #define NAME "test2" 39 40 40 static int add_device(device_t *dev);41 static int test2_add_device(ddf_dev_t *dev); 41 42 42 43 static driver_ops_t driver_ops = { 43 .add_device = & add_device44 .add_device = &test2_add_device 44 45 }; 45 46 46 static driver_t t he_driver = {47 static driver_t test2_driver = { 47 48 .name = NAME, 48 49 .driver_ops = &driver_ops … … 57 58 * @param score Device match score. 58 59 */ 59 static void register_child_verbose(device_t *parent, const char *message,60 static int register_fun_verbose(ddf_dev_t *parent, const char *message, 60 61 const char *name, const char *match_id, int match_score) 61 62 { 62 printf(NAME ": registering child device `%s': %s.\n",63 name, message);63 ddf_fun_t *fun; 64 int rc; 64 65 65 int rc = child_device_register_wrapper(parent, name, 66 match_id, match_score, NULL); 66 printf(NAME ": registering function `%s': %s.\n", name, message); 67 67 68 if (rc == EOK) { 69 printf(NAME ": registered child device `%s'.\n", name); 70 } else { 71 printf(NAME ": failed to register child `%s' (%s).\n", 72 name, str_error(rc)); 68 fun = ddf_fun_create(parent, fun_inner, name); 69 if (fun == NULL) { 70 printf(NAME ": error creating function %s\n", name); 71 return ENOMEM; 73 72 } 73 74 rc = ddf_fun_add_match_id(fun, match_id, match_score); 75 if (rc != EOK) { 76 printf(NAME ": error adding match IDs to function %s\n", name); 77 ddf_fun_destroy(fun); 78 return rc; 79 } 80 81 rc = ddf_fun_bind(fun); 82 if (rc != EOK) { 83 printf(NAME ": error binding function %s: %s\n", name, 84 str_error(rc)); 85 ddf_fun_destroy(fun); 86 return rc; 87 } 88 89 printf(NAME ": registered child device `%s'\n", name); 90 return EOK; 74 91 } 75 92 76 93 /** Add child devices after some sleep. 77 94 * 78 * @param arg Parent device structure (d evice_t *).95 * @param arg Parent device structure (ddf_dev_t *). 79 96 * @return Always EOK. 80 97 */ 81 98 static int postponed_birth(void *arg) 82 99 { 83 device_t *dev = (device_t *) arg; 100 ddf_dev_t *dev = (ddf_dev_t *) arg; 101 ddf_fun_t *fun_a; 102 int rc; 84 103 85 104 async_usleep(1000); 86 105 87 register_child_verbose(dev, "child driven by the same task",106 (void) register_fun_verbose(dev, "child driven by the same task", 88 107 "child", "virtual&test2", 10); 89 register_child_verbose(dev, "child driven by test1",108 (void) register_fun_verbose(dev, "child driven by test1", 90 109 "test1", "virtual&test1", 10); 91 110 92 add_device_to_class(dev, "virtual"); 111 fun_a = ddf_fun_create(dev, fun_exposed, "a"); 112 if (fun_a == NULL) { 113 printf(NAME ": error creating function 'a'.\n"); 114 return ENOMEM; 115 } 116 117 rc = ddf_fun_bind(fun_a); 118 if (rc != EOK) { 119 printf(NAME ": error binding function 'a'.\n"); 120 return rc; 121 } 122 123 ddf_fun_add_to_class(fun_a, "virtual"); 93 124 94 125 return EOK; 95 126 } 96 127 97 98 static int add_device(device_t *dev) 128 static int test2_add_device(ddf_dev_t *dev) 99 129 { 100 printf(NAME ": add_device(name=\"%s\", handle=%d)\n",130 printf(NAME ": test2_add_device(name=\"%s\", handle=%d)\n", 101 131 dev->name, (int) dev->handle); 102 132 103 if ( dev->parent == NULL) {133 if (str_cmp(dev->name, "child") != 0) { 104 134 fid_t postpone = fibril_create(postponed_birth, dev); 135 if (postpone == 0) { 136 printf(NAME ": fibril_create() error\n"); 137 return ENOMEM; 138 } 105 139 fibril_add_ready(postpone); 106 140 } else { 107 register_child_verbose(dev, "child without available driver",141 (void) register_fun_verbose(dev, "child without available driver", 108 142 "ERROR", "non-existent.match.id", 10); 109 143 } … … 115 149 { 116 150 printf(NAME ": HelenOS test2 virtual device driver\n"); 117 return d river_main(&the_driver);151 return ddf_driver_main(&test2_driver); 118 152 } 119 153 -
uspace/drv/uhci-hcd/Makefile
r976f546 r19a1800 1 1 # 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 2 # Copyright (c) 2010 Vojtech Horky 4 3 # All rights reserved. 5 4 # … … 29 28 30 29 USPACE_PREFIX = ../.. 31 BINARY = tasks 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 32 BINARY = uhci-hcd 32 33 33 34 SOURCES = \ 34 tasks.c 35 iface.c \ 36 main.c \ 37 root_hub.c \ 38 transfer_list.c \ 39 uhci.c \ 40 uhci_struct/transfer_descriptor.c \ 41 utils/device_keeper.c \ 42 pci.c \ 43 batch.c 35 44 36 45 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/uhci-hcd/iface.h
r976f546 r19a1800 33 33 * @brief UHCI driver 34 34 */ 35 #ifndef DRV_UHCI_ UHCI_H36 #define DRV_UHCI_ UHCI_H35 #ifndef DRV_UHCI_IFACE_H 36 #define DRV_UHCI_IFACE_H 37 37 38 38 #include <usbhc_iface.h> 39 39 40 #define NAME "uhci" 41 42 usbhc_iface_t uhci_iface; 40 extern usbhc_iface_t uhci_iface; 43 41 44 42 #endif -
uspace/drv/uhci-hcd/pci.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbuhci 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief Debugging support.33 * @brief UHCI driver 34 34 */ 35 #include <stdio.h> 36 #include <ipc/ipc.h> 37 #include <usb/debug.h> 35 #ifndef DRV_UHCI_PCI_H 36 #define DRV_UHCI_PCI_H 38 37 39 #include "vhcd.h"38 #include <ddf/driver.h> 40 39 40 int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 int pci_enable_interrupts(ddf_dev_t *); 41 42 42 /** Debug print informing of invalid call. 43 */ 44 void dprintf_inval_call(int level, ipc_call_t call, sysarg_t phone_hash) 45 { 46 dprintf(level, "phone%#x: invalid call [%u (%u, %u, %u, %u, %u)]", 47 phone_hash, 48 IPC_GET_IMETHOD(call), 49 IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call), 50 IPC_GET_ARG4(call), IPC_GET_ARG5(call)); 51 } 52 43 #endif 53 44 /** 54 45 * @} 55 46 */ 47 -
uspace/drv/uhci-rhd/Makefile
r976f546 r19a1800 1 1 # 2 # Copyright (c) 2010 Vojtech Horky2 # Copyright (c) 2010 Jan Vesely 3 3 # All rights reserved. 4 4 # … … 29 29 USPACE_PREFIX = ../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 32 BINARY = u sbkbd31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 32 BINARY = uhci-rhd 33 33 34 34 SOURCES = \ 35 main.c 35 main.c \ 36 port.c \ 37 port_status.c \ 38 root_hub.c 36 39 37 40 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/usbhid/main.c
r976f546 r19a1800 1 1 /* 2 2 * Copyright (c) 2010 Vojtech Horky 3 * Copyright (c) 2011 Lubos Slovak 3 4 * All rights reserved. 4 5 * … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 28 #include <usb/hcdhubd.h> 29 #include <usb_iface.h> 29 30 /** @addtogroup drvusbhid 31 * @{ 32 */ 33 /** 34 * @file 35 * Main routines of USB HID driver. 36 */ 37 38 #include <ddf/driver.h> 30 39 #include <usb/debug.h> 31 40 #include <errno.h> 32 #include <driver.h>33 #include "uhci.h"34 41 35 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 42 #include "kbddev.h" 43 44 /*----------------------------------------------------------------------------*/ 45 46 #define NAME "usbhid" 47 48 /*----------------------------------------------------------------------------*/ 49 50 static int usbhid_add_device(ddf_dev_t *dev) 36 51 { 37 /* This shall be called only for the UHCI itself. */ 38 assert(dev->parent == NULL); 39 40 *handle = dev->handle; 52 usb_log_debug("usbhid_add_device()\n"); 53 54 int rc = usbhid_kbd_try_add_device(dev); 55 56 if (rc != EOK) { 57 usb_log_info("Device is not a supported keyboard.\n"); 58 usb_log_error("Failed to add HID device.\n"); 59 return EREFUSED; 60 } 61 41 62 return EOK; 42 63 } 43 64 44 static usb_iface_t hc_usb_iface = { 45 .get_hc_handle = usb_iface_get_hc_handle 65 /*----------------------------------------------------------------------------*/ 66 67 static driver_ops_t kbd_driver_ops = { 68 .add_device = usbhid_add_device, 46 69 }; 47 70 48 static device_ops_t uhci_ops = { 49 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 50 .interfaces[USBHC_DEV_IFACE] = &uhci_iface 71 /*----------------------------------------------------------------------------*/ 72 73 static driver_t kbd_driver = { 74 .name = NAME, 75 .driver_ops = &kbd_driver_ops 51 76 }; 52 77 53 static int uhci_add_device(device_t *device) 54 { 55 usb_dprintf(NAME, 1, "uhci_add_device() called\n"); 56 device->ops = &uhci_ops; 57 58 /* 59 * We need to announce the presence of our root hub. 60 */ 61 usb_dprintf(NAME, 2, "adding root hub\n"); 62 usb_hcd_add_root_hub(device); 63 64 return EOK; 65 } 66 67 static driver_ops_t uhci_driver_ops = { 68 .add_device = uhci_add_device, 69 }; 70 71 static driver_t uhci_driver = { 72 .name = NAME, 73 .driver_ops = &uhci_driver_ops 74 }; 78 /*----------------------------------------------------------------------------*/ 75 79 76 80 int main(int argc, char *argv[]) 77 81 { 78 /* 79 * Do some global initializations. 80 */ 81 sleep(5); 82 usb_dprintf_enable(NAME, 5); 82 usb_log_enable(USB_LOG_LEVEL_INFO, NAME); 83 return ddf_driver_main(&kbd_driver); 84 } 83 85 84 return driver_main(&uhci_driver); 85 } 86 /** 87 * @} 88 */ -
uspace/drv/usbhub/main.c
r976f546 r19a1800 27 27 */ 28 28 29 #include <driver.h> 29 /** @addtogroup drvusbhub 30 * @{ 31 */ 32 33 #include <ddf/driver.h> 30 34 #include <errno.h> 31 35 #include <async.h> 32 33 #include <usb/usbdrv.h> 36 #include <stdio.h> 34 37 35 38 #include "usbhub.h" … … 38 41 39 42 usb_general_list_t usb_hub_list; 40 f utex_t usb_hub_list_lock;43 fibril_mutex_t usb_hub_list_lock; 41 44 42 45 static driver_ops_t hub_driver_ops = { … … 49 52 }; 50 53 51 int usb_hub_control_loop(void * noparam){ 52 while(true){ 53 usb_hub_check_hub_changes(); 54 async_usleep(1000 * 1000); 55 } 56 return 0; 54 int main(int argc, char *argv[]) 55 { 56 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 57 dprintf(USB_LOG_LEVEL_INFO, "starting hub driver"); 58 59 //this is probably not needed anymore 60 fibril_mutex_initialize(&usb_hub_list_lock); 61 fibril_mutex_lock(&usb_hub_list_lock); 62 usb_lst_init(&usb_hub_list); 63 fibril_mutex_unlock(&usb_hub_list_lock); 64 65 return ddf_driver_main(&hub_driver); 57 66 } 58 67 68 /** 69 * @} 70 */ 59 71 60 int main(int argc, char *argv[])61 {62 usb_dprintf_enable(NAME,1);63 futex_initialize(&usb_hub_list_lock, 0);64 usb_lst_init(&usb_hub_list);65 futex_up(&usb_hub_list_lock);66 fid_t fid = fibril_create(usb_hub_control_loop, NULL);67 if (fid == 0) {68 dprintf(1, "failed to start fibril for HUB devices");69 //printf("%s: failed to start fibril for HUB devices\n", NAME);70 return ENOMEM;71 }72 fibril_add_ready(fid);73 74 return driver_main(&hub_driver);75 } -
uspace/drv/usbhub/port_status.h
r976f546 r19a1800 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbhub 29 * @{ 30 */ 28 31 29 32 #ifndef PORT_STATUS_H … … 32 35 #include <bool.h> 33 36 #include <sys/types.h> 34 #include <usb/ devreq.h>37 #include <usb/request.h> 35 38 #include "usbhub_private.h" 36 39 … … 170 173 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; 171 174 request->request = USB_HUB_REQUEST_SET_FEATURE; 175 request->value = USB_HUB_FEATURE_PORT_POWER; 176 request->length = 0; 177 } 178 179 /** 180 * set the device request to be a port disable request 181 * @param request 182 * @param port 183 */ 184 static inline void usb_hub_unset_power_port_request( 185 usb_device_request_setup_packet_t * request, uint16_t port 186 ){ 187 request->index = port; 188 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; 189 request->request = USB_HUB_REQUEST_CLEAR_FEATURE; 172 190 request->value = USB_HUB_FEATURE_PORT_POWER; 173 191 request->length = 0; … … 302 320 #endif /* PORT_STATUS_H */ 303 321 322 /** 323 * @} 324 */ -
uspace/drv/usbhub/usbhub.c
r976f546 r19a1800 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb hub driver28 /** @addtogroup drvusbhub 29 29 * @{ 30 30 */ … … 33 33 */ 34 34 35 #include <d river.h>35 #include <ddf/driver.h> 36 36 #include <bool.h> 37 37 #include <errno.h> 38 #include <str_error.h> 38 39 39 40 #include <usb_iface.h> 40 #include <usb/ usbdrv.h>41 #include <usb/ddfiface.h> 41 42 #include <usb/descriptor.h> 42 #include <usb/devreq.h> 43 #include <usb/recognise.h> 44 #include <usb/request.h> 43 45 #include <usb/classes/hub.h> 46 #include <stdio.h> 44 47 45 48 #include "usbhub.h" 46 49 #include "usbhub_private.h" 47 50 #include "port_status.h" 48 49 static usb_iface_t hub_usb_iface = { 50 .get_hc_handle = usb_drv_find_hc 51 #include "usb/usb.h" 52 #include "usb/pipes.h" 53 #include "usb/classes/classes.h" 54 55 static ddf_dev_ops_t hub_device_ops = { 56 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl 51 57 }; 52 58 53 static device_ops_t hub_device_ops = { 54 .interfaces[USB_DEV_IFACE] = &hub_usb_iface 59 /** Hub status-change endpoint description 60 * 61 * For more see usb hub specification in 11.15.1 of 62 */ 63 static usb_endpoint_description_t status_change_endpoint_description = { 64 .transfer_type = USB_TRANSFER_INTERRUPT, 65 .direction = USB_DIRECTION_IN, 66 .interface_class = USB_CLASS_HUB, 67 .interface_subclass = 0, 68 .interface_protocol = 0, 69 .flags = 0 55 70 }; 71 72 int usb_hub_control_loop(void * hub_info_param){ 73 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param; 74 while(true){ 75 usb_hub_check_hub_changes(hub_info); 76 async_usleep(1000 * 1000 );/// \TODO proper number once 77 } 78 return 0; 79 } 80 56 81 57 82 //********************************************* … … 61 86 //********************************************* 62 87 63 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) { 88 /** 89 * Initialize connnections to host controller, device, and device 90 * control endpoint 91 * @param hub 92 * @param device 93 * @return 94 */ 95 static int usb_hub_init_communication(usb_hub_info_t * hub){ 96 usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle); 97 int opResult; 98 opResult = usb_device_connection_initialize_from_device( 99 &hub->device_connection, 100 hub->device); 101 if(opResult != EOK){ 102 dprintf(USB_LOG_LEVEL_ERROR, 103 "could not initialize connection to hc, errno %d",opResult); 104 return opResult; 105 } 106 usb_log_debug("Initializing USB wire abstraction.\n"); 107 opResult = usb_hc_connection_initialize_from_device(&hub->connection, 108 hub->device); 109 if(opResult != EOK){ 110 dprintf(USB_LOG_LEVEL_ERROR, 111 "could not initialize connection to device, errno %d",opResult); 112 return opResult; 113 } 114 usb_log_debug("Initializing default control pipe.\n"); 115 opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control, 116 &hub->device_connection); 117 if(opResult != EOK){ 118 dprintf(USB_LOG_LEVEL_ERROR, 119 "could not initialize connection to device endpoint, errno %d",opResult); 120 } 121 return opResult; 122 } 123 124 /** 125 * When entering this function, hub->endpoints.control should be active. 126 * @param hub 127 * @return 128 */ 129 static int usb_hub_process_configuration_descriptors( 130 usb_hub_info_t * hub){ 131 if(hub==NULL) { 132 return EINVAL; 133 } 134 int opResult; 135 136 //device descriptor 137 usb_standard_device_descriptor_t std_descriptor; 138 opResult = usb_request_get_device_descriptor(&hub->endpoints.control, 139 &std_descriptor); 140 if(opResult!=EOK){ 141 dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult); 142 return opResult; 143 } 144 dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations", 145 std_descriptor.configuration_count); 146 if(std_descriptor.configuration_count<1){ 147 dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE"); 148 //shouldn`t I return? 149 } 150 151 //configuration descriptor 152 /// \TODO check other configurations? 153 usb_standard_configuration_descriptor_t config_descriptor; 154 opResult = usb_request_get_bare_configuration_descriptor( 155 &hub->endpoints.control, 0, 156 &config_descriptor); 157 if(opResult!=EOK){ 158 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult); 159 return opResult; 160 } 161 //set configuration 162 opResult = usb_request_set_configuration(&hub->endpoints.control, 163 config_descriptor.configuration_number); 164 165 if (opResult != EOK) { 166 dprintf(USB_LOG_LEVEL_ERROR, 167 "something went wrong when setting hub`s configuration, %d", 168 opResult); 169 return opResult; 170 } 171 dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d", 172 config_descriptor.configuration_number); 173 174 //full configuration descriptor 175 size_t transferred = 0; 176 uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length); 177 if (descriptors == NULL) { 178 dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory"); 179 return ENOMEM; 180 } 181 opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control, 182 0, descriptors, 183 config_descriptor.total_length, &transferred); 184 if(opResult!=EOK){ 185 free(descriptors); 186 dprintf(USB_LOG_LEVEL_ERROR, 187 "could not get full configuration descriptor, %d",opResult); 188 return opResult; 189 } 190 if (transferred != config_descriptor.total_length) { 191 dprintf(USB_LOG_LEVEL_ERROR, 192 "received incorrect full configuration descriptor"); 193 return ELIMIT; 194 } 195 196 usb_endpoint_mapping_t endpoint_mapping[1] = { 197 { 198 .pipe = &hub->endpoints.status_change, 199 .description = &status_change_endpoint_description, 200 .interface_no = 201 usb_device_get_assigned_interface(hub->device) 202 } 203 }; 204 opResult = usb_endpoint_pipe_initialize_from_configuration( 205 endpoint_mapping, 1, 206 descriptors, config_descriptor.total_length, 207 &hub->device_connection); 208 if (opResult != EOK) { 209 dprintf(USB_LOG_LEVEL_ERROR, 210 "Failed to initialize status change pipe: %s", 211 str_error(opResult)); 212 return opResult; 213 } 214 if (!endpoint_mapping[0].present) { 215 dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \ 216 "cannot understand what is happenning"); 217 return EREFUSED; 218 } 219 220 free(descriptors); 221 return EOK; 222 223 } 224 225 226 /** 227 * Create hub representation from device information. 228 * @param device 229 * @return pointer to created structure or NULL in case of error 230 */ 231 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) { 64 232 usb_hub_info_t* result = usb_new(usb_hub_info_t); 233 result->device = device; 234 int opResult; 235 opResult = usb_hub_init_communication(result); 236 if(opResult != EOK){ 237 free(result); 238 return NULL; 239 } 240 65 241 //result->device = device; 66 242 result->port_count = -1; 67 /// \TODO is this correct? is the device stored?68 243 result->device = device; 69 244 70 71 //printf("[usb_hub] phone to hc = %d\n", hc); 72 if (hc < 0) { 73 return result; 74 } 75 //get some hub info 76 usb_address_t addr = usb_drv_get_my_address(hc, device); 77 dprintf(1,"[usb_hub] address of newly created hub = %d", addr); 78 /*if(addr<0){ 79 //return result; 80 81 }*/ 82 83 result->usb_device = usb_new(usb_hcd_attached_device_info_t); 84 result->usb_device->address = addr; 245 //result->usb_device = usb_new(usb_hcd_attached_device_info_t); 246 size_t received_size; 85 247 86 248 // get hub descriptor 87 usb_target_t target; 88 target.address = addr; 89 target.endpoint = 0; 90 usb_device_request_setup_packet_t request; 91 //printf("[usb_hub] creating descriptor request\n"); 92 usb_hub_set_descriptor_request(&request); 93 94 //printf("[usb_hub] creating serialized descriptor\n"); 249 dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton"); 95 250 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 96 251 usb_hub_descriptor_t * descriptor; 97 size_t received_size; 98 int opResult; 99 //printf("[usb_hub] starting control transaction\n"); 100 opResult = usb_drv_sync_control_read( 101 hc, target, &request, serialized_descriptor, 252 dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction"); 253 usb_endpoint_pipe_start_session(&result->endpoints.control); 254 opResult = usb_request_get_descriptor(&result->endpoints.control, 255 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 256 USB_DESCTYPE_HUB, 257 0, 0, serialized_descriptor, 102 258 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 103 if (opResult != EOK) { 104 dprintf(1,"[usb_hub] failed when receiving hub descriptor, badcode = %d",opResult); 259 usb_endpoint_pipe_end_session(&result->endpoints.control); 260 261 if (opResult != EOK) { 262 dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult); 105 263 free(serialized_descriptor); 106 264 return result; 107 265 } 108 //printf("[usb_hub] deserializing descriptor\n");266 dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor"); 109 267 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor); 110 268 if(descriptor==NULL){ 111 dprintf( 1,"[usb_hub]could not deserialize descriptor ");269 dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor "); 112 270 result->port_count = 1;///\TODO this code is only for debug!!! 113 271 return result; 114 272 } 115 //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count); 273 274 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 116 275 result->port_count = descriptor->ports_count; 117 result->attached_devs = (usb_h ub_attached_device_t*)118 malloc((result->port_count+1) * sizeof(usb_h ub_attached_device_t));276 result->attached_devs = (usb_hc_attached_device_t*) 277 malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t)); 119 278 int i; 120 279 for(i=0;i<result->port_count+1;++i){ 121 result->attached_devs[i]. devman_handle=0;280 result->attached_devs[i].handle=0; 122 281 result->attached_devs[i].address=0; 123 282 } 124 //printf("[usb_hub] freeing data\n");283 dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data"); 125 284 free(serialized_descriptor); 126 285 free(descriptor->devices_removable); … … 129 288 //finish 130 289 131 dprintf( 1,"[usb_hub]hub info created");290 dprintf(USB_LOG_LEVEL_INFO, "hub info created"); 132 291 133 292 return result; 134 293 } 135 294 136 int usb_add_hub_device(device_t *dev) { 137 dprintf(1, "add_hub_device(handle=%d)", (int) dev->handle); 138 dprintf(1,"[usb_hub] hub device"); 139 140 /* 141 * We are some (probably deeply nested) hub. 142 * Thus, assign our own operations and explore already 143 * connected devices. 144 */ 145 dev->ops = &hub_device_ops; 146 147 //create the hub structure 148 //get hc connection 149 int hc = usb_drv_hc_connect_auto(dev, 0); 150 if (hc < 0) { 151 return hc; 152 } 153 154 usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc); 295 /** 296 * Create hub representation and add it into hub list 297 * @param dev 298 * @return 299 */ 300 int usb_add_hub_device(ddf_dev_t *dev) { 301 dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle); 302 303 //dev->ops = &hub_device_ops; 304 (void) hub_device_ops; 305 306 usb_hub_info_t * hub_info = usb_create_hub_info(dev); 307 308 int opResult; 309 310 //perform final configurations 311 usb_endpoint_pipe_start_session(&hub_info->endpoints.control); 312 // process descriptors 313 opResult = usb_hub_process_configuration_descriptors(hub_info); 314 if(opResult != EOK){ 315 dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d", 316 opResult); 317 return opResult; 318 } 319 //power ports 320 usb_device_request_setup_packet_t request; 155 321 int port; 156 int opResult;157 usb_device_request_setup_packet_t request;158 usb_target_t target;159 target.address = hub_info->usb_device->address;160 target.endpoint = 0;161 162 //get configuration descriptor163 // this is not fully correct - there are more configurations164 // and all should be checked165 usb_standard_device_descriptor_t std_descriptor;166 opResult = usb_drv_req_get_device_descriptor(hc, target.address,167 &std_descriptor);168 if(opResult!=EOK){169 dprintf(1,"[usb_hub] could not get device descriptor, %d",opResult);170 return opResult;171 }172 dprintf(1,"[usb_hub] hub has %d configurations",std_descriptor.configuration_count);173 if(std_descriptor.configuration_count<1){174 dprintf(1,"[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE");175 }176 /// \TODO check other configurations177 usb_standard_configuration_descriptor_t config_descriptor;178 opResult = usb_drv_req_get_bare_configuration_descriptor(hc,179 target.address, 0,180 &config_descriptor);181 if(opResult!=EOK){182 dprintf(1,"[usb_hub] could not get configuration descriptor, %d",opResult);183 return opResult;184 }185 //set configuration186 request.request_type = 0;187 request.request = USB_DEVREQ_SET_CONFIGURATION;188 request.index=0;189 request.length=0;190 request.value_high=0;191 request.value_low = config_descriptor.configuration_number;192 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);193 if (opResult != EOK) {194 dprintf(1,"[usb_hub]something went wrong when setting hub`s configuration, %d", opResult);195 }196 197 322 for (port = 1; port < hub_info->port_count+1; ++port) { 198 323 usb_hub_set_power_port_request(&request, port); 199 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 200 dprintf(1,"[usb_hub] powering port %d",port); 324 opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control, 325 &request,sizeof(usb_device_request_setup_packet_t), NULL, 0); 326 dprintf(USB_LOG_LEVEL_INFO, "powering port %d",port); 201 327 if (opResult != EOK) { 202 dprintf( 1,"[usb_hub]something went wrong when setting hub`s %dth port", port);328 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port); 203 329 } 204 330 } 205 331 //ports powered, hub seems to be enabled 206 207 ipc_hangup(hc); 332 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 208 333 209 334 //add the hub to list 210 futex_down(&usb_hub_list_lock); 335 //is this needed now? 336 fibril_mutex_lock(&usb_hub_list_lock); 211 337 usb_lst_append(&usb_hub_list, hub_info); 212 futex_up(&usb_hub_list_lock); 213 214 dprintf(1,"[usb_hub] hub info added to list"); 338 fibril_mutex_unlock(&usb_hub_list_lock); 339 dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list"); 340 341 dprintf(USB_LOG_LEVEL_DEBUG, "adding to ddf"); 342 ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub"); 343 assert(hub_fun != NULL); 344 hub_fun->ops = NULL; 345 346 int rc = ddf_fun_bind(hub_fun); 347 assert(rc == EOK); 348 rc = ddf_fun_add_to_class(hub_fun, "hub"); 349 assert(rc == EOK); 350 351 fid_t fid = fibril_create(usb_hub_control_loop, hub_info); 352 if (fid == 0) { 353 dprintf(USB_LOG_LEVEL_ERROR, 354 ": failed to start monitoring fibril for new hub"); 355 return ENOMEM; 356 } 357 fibril_add_ready(fid); 358 359 dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created"); 215 360 //(void)hub_info; 216 usb_hub_check_hub_changes(); 217 361 //usb_hub_check_hub_changes(); 218 362 219 220 dprintf(1,"[usb_hub] hub dev added");221 dprintf( 1,"\taddress %d, has %d ports ",222 hub_info->usb_device->address,363 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); 364 //address is lost... 365 dprintf(USB_LOG_LEVEL_DEBUG, "\taddress %d, has %d ports ", 366 //hub_info->endpoints.control., 223 367 hub_info->port_count); 224 dprintf(1,"\tused configuration %d",config_descriptor.configuration_number);225 368 226 369 return EOK; 227 370 //return ENOTSUP; 228 371 } 229 230 372 231 373 … … 237 379 238 380 /** 239 * convenience function for releasing default address and writing debug info 240 * (these few lines are used too often to be written again and again) 241 * @param hc 242 * @return 243 */ 244 inline static int usb_hub_release_default_address(int hc){ 245 int opResult; 246 dprintf(1,"[usb_hub] releasing default address"); 247 opResult = usb_drv_release_default_address(hc); 248 if (opResult != EOK) { 249 dprintf(1,"[usb_hub] failed to release default address"); 250 } 251 return opResult; 252 } 253 254 /** 255 * reset the port with new device and reserve the default address 381 * Reset the port with new device and reserve the default address. 256 382 * @param hc 257 383 * @param port 258 384 * @param target 259 385 */ 260 static void usb_hub_init_add_device( int hc, uint16_t port, usb_target_t target) {386 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) { 261 387 usb_device_request_setup_packet_t request; 262 388 int opResult; 263 dprintf(1,"[usb_hub] some connection changed"); 389 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 390 assert(hub->endpoints.control.hc_phone); 264 391 //get default address 265 opResult = usb_drv_reserve_default_address(hc); 266 if (opResult != EOK) { 267 dprintf(1,"[usb_hub] cannot assign default address, it is probably used"); 392 //opResult = usb_drv_reserve_default_address(hc); 393 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW); 394 395 if (opResult != EOK) { 396 dprintf(USB_LOG_LEVEL_WARNING, 397 "cannot assign default address, it is probably used %d",opResult); 268 398 return; 269 399 } 270 400 //reset port 271 401 usb_hub_set_reset_port_request(&request, port); 272 opResult = usb_ drv_sync_control_write(273 hc, target,274 &request, 402 opResult = usb_endpoint_pipe_control_write( 403 &hub->endpoints.control, 404 &request,sizeof(usb_device_request_setup_packet_t), 275 405 NULL, 0 276 406 ); 277 407 if (opResult != EOK) { 278 dprintf(1,"[usb_hub] something went wrong when reseting a port"); 279 usb_hub_release_default_address(hc); 280 } 281 } 282 283 /** 284 * finalize adding new device after port reset 408 dprintf(USB_LOG_LEVEL_ERROR, 409 "something went wrong when reseting a port %d",opResult); 410 //usb_hub_release_default_address(hc); 411 usb_hc_release_default_address(&hub->connection); 412 } 413 } 414 415 /** 416 * Finalize adding new device after port reset 285 417 * @param hc 286 418 * @param port … … 288 420 */ 289 421 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 290 int hc, uint16_t port, usb_target_t target) {291 292 int opResult; 293 dprintf( 1,"[usb_hub]finalizing add device");294 opResult = usb_hub_clear_port_feature( hc, target.address,422 uint16_t port, bool isLowSpeed) { 423 424 int opResult; 425 dprintf(USB_LOG_LEVEL_INFO, "finalizing add device"); 426 opResult = usb_hub_clear_port_feature(&hub->endpoints.control, 295 427 port, USB_HUB_FEATURE_C_PORT_RESET); 296 if (opResult != EOK) { 297 dprintf(1,"[usb_hub] failed to clear port reset feature"); 298 usb_hub_release_default_address(hc); 299 return; 300 } 301 302 /* Request address at from host controller. */ 303 usb_address_t new_device_address = usb_drv_request_address(hc); 428 429 if (opResult != EOK) { 430 dprintf(USB_LOG_LEVEL_ERROR, "failed to clear port reset feature"); 431 usb_hc_release_default_address(&hub->connection); 432 return; 433 } 434 //create connection to device 435 usb_endpoint_pipe_t new_device_pipe; 436 usb_device_connection_t new_device_connection; 437 usb_device_connection_initialize_on_default_address( 438 &new_device_connection, 439 &hub->connection 440 ); 441 usb_endpoint_pipe_initialize_default_control( 442 &new_device_pipe, 443 &new_device_connection); 444 /// \TODO get highspeed info 445 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 446 447 448 /* Request address from host controller. */ 449 usb_address_t new_device_address = usb_hc_request_address( 450 &hub->connection, 451 speed/// \TODO fullspeed?? 452 ); 304 453 if (new_device_address < 0) { 305 dprintf( 1,"[usb_hub]failed to get free USB address");454 dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address"); 306 455 opResult = new_device_address; 307 usb_hub_release_default_address(hc); 308 return; 309 } 310 dprintf(1,"[usb_hub] setting new address"); 311 opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 312 new_device_address); 313 314 if (opResult != EOK) { 315 dprintf(1,"[usb_hub] could not set address for new device"); 316 usb_hub_release_default_address(hc); 317 return; 318 } 319 320 321 opResult = usb_hub_release_default_address(hc); 456 usb_hc_release_default_address(&hub->connection); 457 return; 458 } 459 dprintf(USB_LOG_LEVEL_INFO, "setting new address %d",new_device_address); 460 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 461 // new_device_address); 462 usb_endpoint_pipe_start_session(&new_device_pipe); 463 opResult = usb_request_set_address(&new_device_pipe,new_device_address); 464 usb_endpoint_pipe_end_session(&new_device_pipe); 465 if (opResult != EOK) { 466 dprintf(USB_LOG_LEVEL_ERROR, 467 "could not set address for new device %d",opResult); 468 usb_hc_release_default_address(&hub->connection); 469 return; 470 } 471 472 473 //opResult = usb_hub_release_default_address(hc); 474 opResult = usb_hc_release_default_address(&hub->connection); 322 475 if(opResult!=EOK){ 323 476 return; … … 325 478 326 479 devman_handle_t child_handle; 327 opResult = usb_drv_register_child_in_devman(hc, hub->device, 328 new_device_address, &child_handle); 329 if (opResult != EOK) { 330 dprintf(1,"[usb_hub] could not start driver for new device"); 331 return; 332 } 333 hub->attached_devs[port].devman_handle = child_handle; 480 //?? 481 opResult = usb_device_register_child_in_devman(new_device_address, 482 hub->connection.hc_handle, hub->device, &child_handle, 483 NULL, NULL, NULL); 484 485 if (opResult != EOK) { 486 dprintf(USB_LOG_LEVEL_ERROR, 487 "could not start driver for new device %d",opResult); 488 return; 489 } 490 hub->attached_devs[port].handle = child_handle; 334 491 hub->attached_devs[port].address = new_device_address; 335 492 336 opResult = usb_drv_bind_address(hc, new_device_address, child_handle); 337 if (opResult != EOK) { 338 dprintf(1,"[usb_hub] could not assign address of device in hcd"); 339 return; 340 } 341 dprintf(1,"[usb_hub] new device address %d, handle %zu", 493 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle); 494 opResult = usb_hc_register_device( 495 &hub->connection, 496 &hub->attached_devs[port]); 497 if (opResult != EOK) { 498 dprintf(USB_LOG_LEVEL_ERROR, 499 "could not assign address of device in hcd %d",opResult); 500 return; 501 } 502 dprintf(USB_LOG_LEVEL_INFO, "new device address %d, handle %zu", 342 503 new_device_address, child_handle); 343 504 … … 345 506 346 507 /** 347 * unregister device address in hc508 * Unregister device address in hc 348 509 * @param hc 349 510 * @param port … … 351 512 */ 352 513 static void usb_hub_removed_device( 353 usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {514 usb_hub_info_t * hub,uint16_t port) { 354 515 //usb_device_request_setup_packet_t request; 355 516 int opResult; 356 517 357 /// \TODO remove device 358 359 hub->attached_devs[port].devman_handle=0; 518 /** \TODO remove device from device manager - not yet implemented in 519 * devide manager 520 */ 521 360 522 //close address 361 523 if(hub->attached_devs[port].address!=0){ 362 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 524 //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 525 opResult = usb_hc_unregister_device( 526 &hub->connection, hub->attached_devs[port].address); 363 527 if(opResult != EOK) { 364 dprintf(1, 365 "[usb_hub] could not release address of removed device: %d" 366 ,opResult); 528 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \ 529 "removed device: %d", opResult); 367 530 } 368 531 hub->attached_devs[port].address = 0; 532 hub->attached_devs[port].handle = 0; 369 533 }else{ 370 dprintf(1, 371 "[usb_hub] this is strange, disconnected device had no address"); 534 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address"); 372 535 //device was disconnected before it`s port was reset - return default address 373 usb_drv_release_default_address(hc); 374 } 375 } 376 377 /** 378 * process interrupts on given hub port 536 //usb_drv_release_default_address(hc); 537 usb_hc_release_default_address(&hub->connection); 538 } 539 } 540 541 542 /** 543 *Process over current condition on port. 544 * 545 * Turn off the power on the port. 546 * 547 * @param hub 548 * @param port 549 */ 550 static void usb_hub_over_current( usb_hub_info_t * hub, 551 uint16_t port){ 552 int opResult; 553 opResult = usb_hub_clear_port_feature(&hub->endpoints.control, 554 port, USB_HUB_FEATURE_PORT_POWER); 555 if(opResult!=EOK){ 556 dprintf(USB_LOG_LEVEL_ERROR, "cannot power off port %d; %d", 557 port, opResult); 558 } 559 } 560 561 /** 562 * Process interrupts on given hub port 379 563 * @param hc 380 564 * @param port 381 565 * @param target 382 566 */ 383 static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,384 uint16_t port , usb_address_t address) {385 dprintf( 1,"[usb_hub]interrupt at port %d", port);567 static void usb_hub_process_interrupt(usb_hub_info_t * hub, 568 uint16_t port) { 569 dprintf(USB_LOG_LEVEL_DEBUG, "interrupt at port %d", port); 386 570 //determine type of change 387 usb_target_t target; 388 target.address=address; 389 target.endpoint=0; 571 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 572 573 int opResult; 574 390 575 usb_port_status_t status; 391 576 size_t rcvd_size; 392 577 usb_device_request_setup_packet_t request; 393 int opResult;578 //int opResult; 394 579 usb_hub_set_port_status_request(&request, port); 395 580 //endpoint 0 396 581 397 opResult = usb_ drv_sync_control_read(398 hc, target,399 &request, 582 opResult = usb_endpoint_pipe_control_read( 583 pipe, 584 &request, sizeof(usb_device_request_setup_packet_t), 400 585 &status, 4, &rcvd_size 401 586 ); 402 587 if (opResult != EOK) { 403 dprintf( 1,"[usb_hub] ERROR:could not get port status");588 dprintf(USB_LOG_LEVEL_ERROR, "could not get port status"); 404 589 return; 405 590 } 406 591 if (rcvd_size != sizeof (usb_port_status_t)) { 407 dprintf( 1,"[usb_hub] ERROR:received status has incorrect size");592 dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size"); 408 593 return; 409 594 } 410 595 //something connected/disconnected 411 596 if (usb_port_connect_change(&status)) { 412 opResult = usb_hub_clear_port_feature( hc, target.address,597 opResult = usb_hub_clear_port_feature(pipe, 413 598 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 414 599 // TODO: check opResult 415 600 if (usb_port_dev_connected(&status)) { 416 dprintf( 1,"[usb_hub]some connection changed");417 usb_hub_init_add_device(h c, port, target);601 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 602 usb_hub_init_add_device(hub, port); 418 603 } else { 419 usb_hub_removed_device(hub, hc, port, target); 604 usb_hub_removed_device(hub, port); 605 } 606 } 607 //over current 608 if (usb_port_overcurrent_change(&status)) { 609 //check if it was not auto-resolved 610 if(usb_port_over_current(&status)){ 611 usb_hub_over_current(hub,port); 612 }else{ 613 dprintf(USB_LOG_LEVEL_INFO, 614 "over current condition was auto-resolved on port %d",port); 420 615 } 421 616 } 422 617 //port reset 423 618 if (usb_port_reset_completed(&status)) { 424 dprintf( 1,"[usb_hub]port reset complete");619 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 425 620 if (usb_port_enabled(&status)) { 426 usb_hub_finalize_add_device(hub, hc, port, target);621 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status)); 427 622 } else { 428 dprintf( 1,"[usb_hub] ERROR:port reset, but port still not enabled");623 dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled"); 429 624 } 430 625 } … … 434 629 usb_port_set_reset_completed(&status, false); 435 630 usb_port_set_dev_connected(&status, false); 436 if (status) { 437 dprintf(1,"[usb_hub]there was some unsupported change on port %d",port); 631 if (status>>16) { 632 dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status); 633 438 634 } 439 635 /// \TODO handle other changes 440 /// \TODO debug log for various situations 441 442 } 443 444 /* Check changes on all known hubs. 445 */ 446 void usb_hub_check_hub_changes(void) { 636 } 637 638 /** 639 * Check changes on particular hub 640 * @param hub_info_param 641 */ 642 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 643 int opResult; 644 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); 645 if(opResult != EOK){ 646 dprintf(USB_LOG_LEVEL_ERROR, 647 "could not initialize communication for hub; %d", opResult); 648 return; 649 } 650 651 size_t port_count = hub_info->port_count; 652 653 /// FIXME: count properly 654 size_t byte_length = ((port_count+1) / 8) + 1; 655 void *change_bitmap = malloc(byte_length); 656 size_t actual_size; 657 447 658 /* 448 * Iterate through all hubs.659 * Send the request. 449 660 */ 450 usb_general_list_t * lst_item; 451 futex_down(&usb_hub_list_lock); 452 for (lst_item = usb_hub_list.next; 453 lst_item != &usb_hub_list; 454 lst_item = lst_item->next) { 455 futex_up(&usb_hub_list_lock); 456 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data); 457 /* 458 * Check status change pipe of this hub. 459 */ 460 461 usb_target_t target; 462 target.address = hub_info->usb_device->address; 463 target.endpoint = 1;/// \TODO get from endpoint descriptor 464 dprintf(1,"[usb_hub] checking changes for hub at addr %d", 465 target.address); 466 467 size_t port_count = hub_info->port_count; 468 469 /* 470 * Connect to respective HC. 471 */ 472 int hc = usb_drv_hc_connect_auto(hub_info->device, 0); 473 if (hc < 0) { 474 continue; 661 opResult = usb_endpoint_pipe_read( 662 &hub_info->endpoints.status_change, 663 change_bitmap, byte_length, &actual_size 664 ); 665 666 if (opResult != EOK) { 667 free(change_bitmap); 668 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 669 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 670 return; 671 } 672 unsigned int port; 673 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control); 674 if(opResult!=EOK){ 675 dprintf(USB_LOG_LEVEL_ERROR, "could not start control pipe session %d", 676 opResult); 677 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 678 return; 679 } 680 opResult = usb_hc_connection_open(&hub_info->connection); 681 if(opResult!=EOK){ 682 dprintf(USB_LOG_LEVEL_ERROR, "could not start host controller session %d", 683 opResult); 684 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 685 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 686 return; 687 } 688 689 ///todo, opresult check, pre obe konekce 690 for (port = 1; port < port_count+1; ++port) { 691 bool interrupt = 692 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 693 if (interrupt) { 694 usb_hub_process_interrupt( 695 hub_info, port); 475 696 } 476 477 /// FIXME: count properly 478 size_t byte_length = ((port_count+1) / 8) + 1; 479 480 void *change_bitmap = malloc(byte_length); 481 size_t actual_size; 482 usb_handle_t handle; 483 484 /* 485 * Send the request. 486 */ 487 int opResult = usb_drv_async_interrupt_in(hc, target, 488 change_bitmap, byte_length, &actual_size, 489 &handle); 490 491 usb_drv_async_wait_for(handle); 492 493 if (opResult != EOK) { 494 dprintf(1,"[usb_hub] something went wrong while getting status of hub"); 495 continue; 496 } 497 unsigned int port; 498 for (port = 1; port < port_count+1; ++port) { 499 bool interrupt = 500 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 501 if (interrupt) { 502 usb_hub_process_interrupt( 503 hub_info, hc, port, hub_info->usb_device->address); 504 } 505 } 506 free(change_bitmap); 507 508 ipc_hangup(hc); 509 futex_down(&usb_hub_list_lock); 510 } 511 futex_up(&usb_hub_list_lock); 512 } 513 514 697 } 698 usb_hc_connection_close(&hub_info->connection); 699 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 700 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 701 free(change_bitmap); 702 } 515 703 516 704 -
uspace/drv/usbhub/usbhub.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbhub 30 30 * @{ 31 31 */ … … 36 36 #define DRV_USBHUB_USBHUB_H 37 37 38 #include <ipc/devman.h> 39 #include <usb/usb.h> 40 #include <ddf/driver.h> 41 38 42 #define NAME "usbhub" 39 43 40 #include "usb/hcdhubd.h"44 #include <usb/hub.h> 41 45 42 /** basic information about device attached to hub */ 43 typedef struct{ 44 usb_address_t address; 45 devman_handle_t devman_handle; 46 }usb_hub_attached_device_t; 46 #include <usb/pipes.h> 47 48 /* Hub endpoints. */ 49 typedef struct { 50 usb_endpoint_pipe_t control; 51 usb_endpoint_pipe_t status_change; 52 } usb_hub_endpoints_t; 53 54 47 55 48 56 /** Information about attached hub. */ … … 50 58 /** Number of ports. */ 51 59 int port_count; 52 /** attached device handles */53 usb_h ub_attached_device_t * attached_devs;60 /** attached device handles, for each port one */ 61 usb_hc_attached_device_t * attached_devs; 54 62 /** General usb device info. */ 55 usb_hcd_attached_device_info_t * usb_device;63 //usb_hcd_attached_device_info_t * usb_device; 56 64 /** General device info*/ 57 device_t * device; 58 65 ddf_dev_t * device; 66 /** connection to hcd */ 67 //usb_device_connection_t connection; 68 usb_hc_connection_t connection; 69 /** */ 70 usb_device_connection_t device_connection; 71 /** hub endpoints */ 72 usb_hub_endpoints_t endpoints; 59 73 } usb_hub_info_t; 60 74 61 75 /** 62 76 * function running the hub-controlling loop. 63 * @param noparam fundtion does not need any parameters77 * @param hub_info_param hub info pointer 64 78 */ 65 int usb_hub_control_loop(void * noparam);79 int usb_hub_control_loop(void * hub_info_param); 66 80 67 81 /** Callback when new hub device is detected. … … 70 84 * @return Error code. 71 85 */ 72 int usb_add_hub_device(d evice_t *dev);86 int usb_add_hub_device(ddf_dev_t *dev); 73 87 74 88 /** 75 * check changes on all registered hubs 89 * check changes on specified hub 90 * @param hub_info_param pointer to usb_hub_info_t structure 76 91 */ 77 void usb_hub_check_hub_changes( void);92 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param); 78 93 79 94 80 //int usb_add_hub_device(device_t *);81 95 82 96 -
uspace/drv/usbhub/usbhub_private.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbhub 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief Hub driver .33 * @brief Hub driver private definitions 34 34 */ 35 35 … … 42 42 #include <adt/list.h> 43 43 #include <bool.h> 44 #include <d river.h>45 #include <f utex.h>44 #include <ddf/driver.h> 45 #include <fibril_synch.h> 46 46 47 #include <usb/classes/hub.h> 47 48 #include <usb/usb.h> 48 #include <usb/usbdrv.h>49 #include <usb/classes/hub.h>50 #include <usb/devreq.h>51 49 #include <usb/debug.h> 50 #include <usb/request.h> 52 51 53 52 //************ … … 61 60 //************ 62 61 // 63 // convenience debug printf 62 // convenience debug printf for usb hub 64 63 // 65 64 //************ 66 65 #define dprintf(level, format, ...) \ 67 usb_dprintf(NAME, (level), format "\n", ##__VA_ARGS__) 66 usb_log_printf((level), format "\n", ##__VA_ARGS__) 67 68 68 69 69 /** 70 * create hub structure instance70 * Create hub structure instance 71 71 * 72 72 * Set the address and port count information most importantly. … … 76 76 * @return 77 77 */ 78 usb_hub_info_t * usb_create_hub_info(d evice_t * device, int hc);78 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device); 79 79 80 /** list of hubs maanged by this driver */80 /** List of hubs maanged by this driver */ 81 81 extern usb_general_list_t usb_hub_list; 82 82 83 /** lock for hub list*/84 extern f utex_t usb_hub_list_lock;83 /** Lock for hub list*/ 84 extern fibril_mutex_t usb_hub_list_lock; 85 85 86 86 87 87 /** 88 * perform complete control read transaction88 * Perform complete control read transaction 89 89 * 90 * manages all three steps of transaction: setup, read and finalize90 * Manages all three steps of transaction: setup, read and finalize 91 91 * @param phone 92 92 * @param target 93 * @param request request for data94 * @param rcvd_buffer received data93 * @param request Request packet 94 * @param rcvd_buffer Received data 95 95 * @param rcvd_size 96 * @param actual_size actual size of received data96 * @param actual_size Actual size of received data 97 97 * @return error code 98 98 */ 99 /* 99 100 int usb_drv_sync_control_read( 100 int phone, usb_target_t target,101 usb_endpoint_pipe_t *pipe, 101 102 usb_device_request_setup_packet_t * request, 102 103 void * rcvd_buffer, size_t rcvd_size, size_t * actual_size 103 ); 104 );*/ 104 105 105 106 /** 106 * perform complete control write transaction107 * Perform complete control write transaction 107 108 * 108 * manages all three steps of transaction: setup, write and finalize109 * Manages all three steps of transaction: setup, write and finalize 109 110 * @param phone 110 111 * @param target 111 * @param request request to send data112 * @param request Request packet to send data 112 113 * @param sent_buffer 113 114 * @param sent_size 114 115 * @return error code 115 116 */ 116 int usb_drv_sync_control_write(117 int phone, usb_target_t target,117 /*int usb_drv_sync_control_write( 118 usb_endpoint_pipe_t *pipe, 118 119 usb_device_request_setup_packet_t * request, 119 120 void * sent_buffer, size_t sent_size 120 ); 121 );*/ 121 122 122 123 /** 123 * set the device request to be a get hub descriptor request.124 * Set the device request to be a get hub descriptor request. 124 125 * @warning the size is allways set to USB_HUB_MAX_DESCRIPTOR_SIZE 125 126 * @param request … … 137 138 } 138 139 139 static inline int usb_hub_clear_port_feature(int hc, usb_address_t address, 140 /** 141 * Clear feature on hub port. 142 * 143 * @param hc Host controller telephone 144 * @param address Hub address 145 * @param port_index Port 146 * @param feature Feature selector 147 * @return Operation result 148 */ 149 static inline int usb_hub_clear_port_feature(usb_endpoint_pipe_t *pipe, 140 150 int port_index, 141 151 usb_hub_class_feature_t feature) { 142 usb_target_t target = { 143 .address = address, 144 .endpoint = 0 145 }; 152 146 153 usb_device_request_setup_packet_t clear_request = { 147 154 .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE, … … 151 158 }; 152 159 clear_request.value = feature; 153 return usb_ drv_psync_control_write(hc, target, &clear_request,160 return usb_endpoint_pipe_control_write(pipe, &clear_request, 154 161 sizeof(clear_request), NULL, 0); 155 162 } 156 163 164 /** 165 * @brief create uint8_t array with serialized descriptor 166 * 167 * @param descriptor 168 * @return newly created serializd descriptor pointer 169 */ 170 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor); 171 172 /** 173 * @brief create deserialized desriptor structure out of serialized descriptor 174 * 175 * The serialized descriptor must be proper usb hub descriptor, 176 * otherwise an eerror might occur. 177 * 178 * @param sdescriptor serialized descriptor 179 * @return newly created deserialized descriptor pointer 180 */ 181 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * sdescriptor); 157 182 158 183 -
uspace/drv/usbhub/usblist.c
r976f546 r19a1800 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb hub driver28 /** @addtogroup drvusbhub 29 29 * @{ 30 30 */ -
uspace/drv/usbhub/usblist.h
r976f546 r19a1800 27 27 */ 28 28 29 30 #ifndef USBLIST_H 31 #define USBLIST_H 32 /** @addtogroup usb hub driver 29 /** @addtogroup drvusbhub 33 30 * @{ 34 31 */ … … 40 37 * much simpler and more straight-forward semantics. 41 38 */ 39 #ifndef USBLIST_H 40 #define USBLIST_H 42 41 43 42 /** … … 78 77 } 79 78 80 79 #endif /* USBLIST_H */ 81 80 /** 82 81 * @} 83 82 */ 84 85 86 87 #endif /* USBLIST_H */88 -
uspace/drv/usbhub/utils.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup libusb usb29 /** @addtogroup drvusbhub 30 30 * @{ 31 31 */ … … 33 33 * @brief various utilities 34 34 */ 35 #include <d river.h>35 #include <ddf/driver.h> 36 36 #include <bool.h> 37 37 #include <errno.h> 38 38 39 39 #include <usbhc_iface.h> 40 #include <usb/usbdrv.h>41 40 #include <usb/descriptor.h> 42 #include <usb/devreq.h>43 41 #include <usb/classes/hub.h> 44 42 … … 114 112 115 113 //control transactions 116 114 /* 117 115 int usb_drv_sync_control_read( 118 int phone, usb_target_t target,119 usb_device_request_setup_packet_t * request,120 void * rcvd_buffer, size_t rcvd_size, size_t * actual_size121 ) {116 int phone, usb_target_t target, 117 usb_device_request_setup_packet_t * request, 118 void * rcvd_buffer, size_t rcvd_size, size_t * actual_size 119 ) { 122 120 usb_handle_t handle; 123 121 int opResult; 124 122 //setup 125 123 opResult = usb_drv_async_control_read_setup(phone, target, 126 request, sizeof (usb_device_request_setup_packet_t),127 &handle);124 request, sizeof (usb_device_request_setup_packet_t), 125 &handle); 128 126 if (opResult != EOK) { 129 127 return opResult; … … 158 156 159 157 int usb_drv_sync_control_write( 160 int phone, usb_target_t target,161 usb_device_request_setup_packet_t * request,162 void * sent_buffer, size_t sent_size163 ) {158 int phone, usb_target_t target, 159 usb_device_request_setup_packet_t * request, 160 void * sent_buffer, size_t sent_size 161 ) { 164 162 usb_handle_t handle; 165 163 int opResult; 166 164 //setup 167 165 opResult = usb_drv_async_control_write_setup(phone, target, 168 request, sizeof (usb_device_request_setup_packet_t),169 &handle);166 request, sizeof (usb_device_request_setup_packet_t), 167 &handle); 170 168 if (opResult != EOK) { 171 169 return opResult; … … 188 186 //finalize 189 187 opResult = usb_drv_async_control_write_status(phone, target, 190 &handle);188 &handle); 191 189 if (opResult != EOK) { 192 190 return opResult; … … 199 197 } 200 198 201 199 */ 202 200 203 201 -
uspace/drv/usbmid/Makefile
r976f546 r19a1800 1 1 # 2 # Copyright (c) 201 0Vojtech Horky2 # Copyright (c) 2011 Vojtech Horky 3 3 # All rights reserved. 4 4 # … … 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include 32 BINARY = u hci32 BINARY = usbmid 33 33 34 34 SOURCES = \ 35 dump.c \ 36 explore.c \ 35 37 main.c \ 36 transfers.c38 usbmid.c 37 39 38 40 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/vhc/Makefile
r976f546 r19a1800 44 44 conndev.c \ 45 45 connhost.c \ 46 debug.c \47 46 devices.c \ 48 47 hc.c \ -
uspace/drv/vhc/conn.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 37 37 38 38 #include <usb/usb.h> 39 #include <usb/hcdhubd.h>40 39 #include <usbhc_iface.h> 40 #include <usb_iface.h> 41 41 #include "vhcd.h" 42 42 #include "devices.h" … … 44 44 void connection_handler_host(sysarg_t); 45 45 46 usb_hcd_transfer_ops_t vhc_transfer_ops; 47 usbhc_iface_t vhc_iface; 46 extern usbhc_iface_t vhc_iface; 47 extern usb_iface_t vhc_usb_iface; 48 extern usb_iface_t rh_usb_iface; 48 49 49 50 void address_init(void); 50 51 51 52 52 void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *); 53 void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 54 void on_client_close(ddf_fun_t *); 53 55 54 56 -
uspace/drv/vhc/conndev.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 76 76 /** Default handler for IPC methods not handled by DDF. 77 77 * 78 * @param devDevice handling the call.78 * @param fun Device handling the call. 79 79 * @param icallid Call id. 80 80 * @param icall Call data. 81 81 */ 82 void default_connection_handler(d evice_t *dev,82 void default_connection_handler(ddf_fun_t *fun, 83 83 ipc_callid_t icallid, ipc_call_t *icall) 84 84 { … … 88 88 int callback = IPC_GET_ARG5(*icall); 89 89 virtdev_connection_t *dev 90 = virtdev_add_device(callback );90 = virtdev_add_device(callback, (sysarg_t)fibril_get_id()); 91 91 if (!dev) { 92 ipc_answer_0(icallid, EEXISTS);93 ipc_hangup(callback);92 async_answer_0(icallid, EEXISTS); 93 async_hangup(callback); 94 94 return; 95 95 } 96 ipc_answer_0(icallid, EOK);96 async_answer_0(icallid, EOK); 97 97 98 98 char devname[DEVICE_NAME_MAXLENGTH + 1]; 99 99 int rc = get_device_name(callback, devname, DEVICE_NAME_MAXLENGTH); 100 100 101 dprintf(0, "virtual device connected (name: %s)", 102 rc == EOK ? devname : "<unknown>"); 103 104 /* FIXME: destroy the device when the client disconnects. */ 101 usb_log_info("New virtual device `%s' (id = %x).\n", 102 rc == EOK ? devname : "<unknown>", dev->id); 105 103 106 104 return; 107 105 } 108 106 109 ipc_answer_0(icallid, EINVAL); 107 async_answer_0(icallid, EINVAL); 108 } 109 110 /** Callback for DDF when client disconnects. 111 * 112 * @param d Device the client was connected to. 113 */ 114 void on_client_close(ddf_fun_t *fun) 115 { 116 /* 117 * Maybe a virtual device is being unplugged. 118 */ 119 virtdev_connection_t *dev = virtdev_find((sysarg_t)fibril_get_id()); 120 if (dev == NULL) { 121 return; 122 } 123 124 usb_log_info("Virtual device disconnected (id = %x).\n", dev->id); 125 virtdev_destroy_device(dev); 110 126 } 111 127 -
uspace/drv/vhc/connhost.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 36 36 #include <errno.h> 37 37 #include <usb/usb.h> 38 #include <usb/hcd.h> 38 #include <usb/addrkeep.h> 39 #include <usb/ddfiface.h> 39 40 40 41 #include "vhcd.h" 41 42 #include "conn.h" 42 43 #include "hc.h" 44 43 45 44 46 typedef struct { … … 46 48 usbhc_iface_transfer_out_callback_t out_callback; 47 49 usbhc_iface_transfer_in_callback_t in_callback; 48 device_t *dev; 50 ddf_fun_t *fun; 51 size_t reported_size; 49 52 void *arg; 50 53 } transfer_info_t; 51 54 55 typedef struct { 56 usb_direction_t direction; 57 usb_target_t target; 58 usbhc_iface_transfer_out_callback_t out_callback; 59 usbhc_iface_transfer_in_callback_t in_callback; 60 ddf_fun_t *fun; 61 void *arg; 62 void *data_buffer; 63 size_t data_buffer_size; 64 } control_transfer_info_t; 65 52 66 static void universal_callback(void *buffer, size_t size, 53 usb_transaction_outcome_t outcome, void *arg)67 int outcome, void *arg) 54 68 { 55 69 transfer_info_t *transfer = (transfer_info_t *) arg; 70 71 if (transfer->reported_size != (size_t) -1) { 72 size = transfer->reported_size; 73 } 56 74 57 75 switch (transfer->direction) { 58 76 case USB_DIRECTION_IN: 59 transfer->in_callback(transfer-> dev,77 transfer->in_callback(transfer->fun, 60 78 outcome, size, 61 79 transfer->arg); 62 80 break; 63 81 case USB_DIRECTION_OUT: 64 transfer->out_callback(transfer-> dev,82 transfer->out_callback(transfer->fun, 65 83 outcome, 66 84 transfer->arg); … … 74 92 } 75 93 76 static transfer_info_t *create_transfer_info(d evice_t *dev,94 static transfer_info_t *create_transfer_info(ddf_fun_t *fun, 77 95 usb_direction_t direction, void *arg) 78 96 { … … 83 101 transfer->out_callback = NULL; 84 102 transfer->arg = arg; 85 transfer->dev = dev; 103 transfer->fun = fun; 104 transfer->reported_size = (size_t) -1; 86 105 87 106 return transfer; 88 107 } 89 108 90 static int enqueue_transfer_out(device_t *dev, 109 static void control_abort_prematurely(control_transfer_info_t *transfer, 110 size_t size, int outcome) 111 { 112 switch (transfer->direction) { 113 case USB_DIRECTION_IN: 114 transfer->in_callback(transfer->fun, 115 outcome, size, 116 transfer->arg); 117 break; 118 case USB_DIRECTION_OUT: 119 transfer->out_callback(transfer->fun, 120 outcome, 121 transfer->arg); 122 break; 123 default: 124 assert(false && "unreachable"); 125 break; 126 } 127 } 128 129 static void control_callback_two(void *buffer, size_t size, 130 int outcome, void *arg) 131 { 132 control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg; 133 134 if (outcome != EOK) { 135 control_abort_prematurely(ctrl_transfer, outcome, size); 136 free(ctrl_transfer); 137 return; 138 } 139 140 transfer_info_t *transfer = create_transfer_info(ctrl_transfer->fun, 141 ctrl_transfer->direction, ctrl_transfer->arg); 142 transfer->out_callback = ctrl_transfer->out_callback; 143 transfer->in_callback = ctrl_transfer->in_callback; 144 transfer->reported_size = size; 145 146 switch (ctrl_transfer->direction) { 147 case USB_DIRECTION_IN: 148 hc_add_transaction_to_device(false, ctrl_transfer->target, 149 USB_TRANSFER_CONTROL, 150 NULL, 0, 151 universal_callback, transfer); 152 break; 153 case USB_DIRECTION_OUT: 154 hc_add_transaction_from_device(ctrl_transfer->target, 155 USB_TRANSFER_CONTROL, 156 NULL, 0, 157 universal_callback, transfer); 158 break; 159 default: 160 assert(false && "unreachable"); 161 break; 162 } 163 164 free(ctrl_transfer); 165 } 166 167 static void control_callback_one(void *buffer, size_t size, 168 int outcome, void *arg) 169 { 170 control_transfer_info_t *transfer = (control_transfer_info_t *) arg; 171 172 if (outcome != EOK) { 173 control_abort_prematurely(transfer, outcome, size); 174 free(transfer); 175 return; 176 } 177 178 switch (transfer->direction) { 179 case USB_DIRECTION_IN: 180 hc_add_transaction_from_device(transfer->target, 181 USB_TRANSFER_CONTROL, 182 transfer->data_buffer, transfer->data_buffer_size, 183 control_callback_two, transfer); 184 break; 185 case USB_DIRECTION_OUT: 186 hc_add_transaction_to_device(false, transfer->target, 187 USB_TRANSFER_CONTROL, 188 transfer->data_buffer, transfer->data_buffer_size, 189 control_callback_two, transfer); 190 break; 191 default: 192 assert(false && "unreachable"); 193 break; 194 } 195 } 196 197 static control_transfer_info_t *create_control_transfer_info(ddf_fun_t *fun, 198 usb_direction_t direction, usb_target_t target, 199 void *data_buffer, size_t data_buffer_size, 200 void *arg) 201 { 202 control_transfer_info_t *transfer 203 = malloc(sizeof(control_transfer_info_t)); 204 205 transfer->direction = direction; 206 transfer->target = target; 207 transfer->in_callback = NULL; 208 transfer->out_callback = NULL; 209 transfer->arg = arg; 210 transfer->fun = fun; 211 transfer->data_buffer = data_buffer; 212 transfer->data_buffer_size = data_buffer_size; 213 214 return transfer; 215 } 216 217 static int enqueue_transfer_out(ddf_fun_t *fun, 91 218 usb_target_t target, usb_transfer_type_t transfer_type, 92 219 void *buffer, size_t size, 93 220 usbhc_iface_transfer_out_callback_t callback, void *arg) 94 221 { 95 dprintf(3, "transfer OUT [%d.%d (%s); %zu]",222 usb_log_debug2("Transfer OUT [%d.%d (%s); %zu].\n", 96 223 target.address, target.endpoint, 97 224 usb_str_transfer_type(transfer_type), … … 99 226 100 227 transfer_info_t *transfer 101 = create_transfer_info( dev, USB_DIRECTION_OUT, arg);228 = create_transfer_info(fun, USB_DIRECTION_OUT, arg); 102 229 transfer->out_callback = callback; 103 230 … … 108 235 } 109 236 110 static int enqueue_transfer_ setup(device_t *dev,237 static int enqueue_transfer_in(ddf_fun_t *fun, 111 238 usb_target_t target, usb_transfer_type_t transfer_type, 112 239 void *buffer, size_t size, 113 usbhc_iface_transfer_ out_callback_t callback, void *arg)114 { 115 dprintf(3, "transfer SETUP [%d.%d (%s); %zu]",240 usbhc_iface_transfer_in_callback_t callback, void *arg) 241 { 242 usb_log_debug2("Transfer IN [%d.%d (%s); %zu].\n", 116 243 target.address, target.endpoint, 117 244 usb_str_transfer_type(transfer_type), … … 119 246 120 247 transfer_info_t *transfer 121 = create_transfer_info(dev, USB_DIRECTION_OUT, arg); 122 transfer->out_callback = callback; 123 124 hc_add_transaction_to_device(true, target, transfer_type, buffer, size, 125 universal_callback, transfer); 126 127 return EOK; 128 } 129 130 static int enqueue_transfer_in(device_t *dev, 131 usb_target_t target, usb_transfer_type_t transfer_type, 132 void *buffer, size_t size, 133 usbhc_iface_transfer_in_callback_t callback, void *arg) 134 { 135 dprintf(3, "transfer IN [%d.%d (%s); %zu]", 136 target.address, target.endpoint, 137 usb_str_transfer_type(transfer_type), 138 size); 139 140 transfer_info_t *transfer 141 = create_transfer_info(dev, USB_DIRECTION_IN, arg); 248 = create_transfer_info(fun, USB_DIRECTION_IN, arg); 142 249 transfer->in_callback = callback; 143 250 … … 149 256 150 257 151 static int interrupt_out(device_t *dev, usb_target_t target, 258 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 259 size_t max_packet_size, 152 260 void *data, size_t size, 153 261 usbhc_iface_transfer_out_callback_t callback, void *arg) 154 262 { 155 return enqueue_transfer_out( dev, target, USB_TRANSFER_INTERRUPT,263 return enqueue_transfer_out(fun, target, USB_TRANSFER_INTERRUPT, 156 264 data, size, 157 265 callback, arg); 158 266 } 159 267 160 static int interrupt_in(device_t *dev, usb_target_t target, 268 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 269 size_t max_packet_size, 161 270 void *data, size_t size, 162 271 usbhc_iface_transfer_in_callback_t callback, void *arg) 163 272 { 164 return enqueue_transfer_in( dev, target, USB_TRANSFER_INTERRUPT,273 return enqueue_transfer_in(fun, target, USB_TRANSFER_INTERRUPT, 165 274 data, size, 166 275 callback, arg); 167 276 } 168 277 169 static int control_write_setup(device_t *dev, usb_target_t target, 170 void *data, size_t size, 278 static int control_write(ddf_fun_t *fun, usb_target_t target, 279 size_t max_packet_size, 280 void *setup_packet, size_t setup_packet_size, 281 void *data, size_t data_size, 171 282 usbhc_iface_transfer_out_callback_t callback, void *arg) 172 283 { 173 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL, 174 data, size, 175 callback, arg); 176 } 177 178 static int control_write_data(device_t *dev, usb_target_t target, 179 void *data, size_t size, 180 usbhc_iface_transfer_out_callback_t callback, void *arg) 181 { 182 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL, 183 data, size, 184 callback, arg); 185 } 186 187 static int control_write_status(device_t *dev, usb_target_t target, 284 control_transfer_info_t *transfer 285 = create_control_transfer_info(fun, USB_DIRECTION_OUT, target, 286 data, data_size, arg); 287 transfer->out_callback = callback; 288 289 hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL, 290 setup_packet, setup_packet_size, 291 control_callback_one, transfer); 292 293 return EOK; 294 } 295 296 static int control_read(ddf_fun_t *fun, usb_target_t target, 297 size_t max_packet_size, 298 void *setup_packet, size_t setup_packet_size, 299 void *data, size_t data_size, 188 300 usbhc_iface_transfer_in_callback_t callback, void *arg) 189 301 { 190 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL, 191 NULL, 0, 192 callback, arg); 193 } 194 195 static int control_read_setup(device_t *dev, usb_target_t target, 196 void *data, size_t size, 197 usbhc_iface_transfer_out_callback_t callback, void *arg) 198 { 199 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL, 200 data, size, 201 callback, arg); 202 } 203 204 static int control_read_data(device_t *dev, usb_target_t target, 205 void *data, size_t size, 206 usbhc_iface_transfer_in_callback_t callback, void *arg) 207 { 208 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL, 209 data, size, 210 callback, arg); 211 } 212 213 static int control_read_status(device_t *dev, usb_target_t target, 214 usbhc_iface_transfer_out_callback_t callback, void *arg) 215 { 216 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL, 217 NULL, 0, 218 callback, arg); 302 control_transfer_info_t *transfer 303 = create_control_transfer_info(fun, USB_DIRECTION_IN, target, 304 data, data_size, arg); 305 transfer->in_callback = callback; 306 307 hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL, 308 setup_packet, setup_packet_size, 309 control_callback_one, transfer); 310 311 return EOK; 219 312 } 220 313 221 314 static usb_address_keeping_t addresses; 222 315 223 224 static int reserve_default_address(device_t *dev) 316 static int tell_address(ddf_fun_t *fun, devman_handle_t handle, 317 usb_address_t *address) 318 { 319 usb_log_debug("tell_address(fun \"%s\", handle %zu)\n", 320 fun->name, (size_t) fun->handle); 321 usb_address_t addr = usb_address_keeping_find(&addresses, handle); 322 if (addr < 0) { 323 return addr; 324 } 325 326 *address = addr; 327 return EOK; 328 } 329 330 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t ignored) 225 331 { 226 332 usb_address_keeping_reserve_default(&addresses); … … 228 334 } 229 335 230 static int release_default_address(d evice_t *dev)336 static int release_default_address(ddf_fun_t *fun) 231 337 { 232 338 usb_address_keeping_release_default(&addresses); … … 234 340 } 235 341 236 static int request_address(device_t *dev, usb_address_t *address) 342 static int request_address(ddf_fun_t *fun, usb_speed_t ignored, 343 usb_address_t *address) 237 344 { 238 345 usb_address_t addr = usb_address_keeping_request(&addresses); … … 245 352 } 246 353 247 static int release_address(d evice_t *dev, usb_address_t address)354 static int release_address(ddf_fun_t *fun, usb_address_t address) 248 355 { 249 356 return usb_address_keeping_release(&addresses, address); 250 357 } 251 358 252 static int bind_address(d evice_t *dev, usb_address_t address,359 static int bind_address(ddf_fun_t *fun, usb_address_t address, 253 360 devman_handle_t handle) 254 361 { … … 257 364 } 258 365 259 static int tell_address(device_t *dev, devman_handle_t handle, 366 static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun, 367 devman_handle_t *handle) 368 { 369 ddf_fun_t *hc_fun = root_hub_fun->driver_data; 370 assert(hc_fun != NULL); 371 372 *handle = hc_fun->handle; 373 374 usb_log_debug("usb_iface_get_hc_handle_rh_impl returns %zu\n", *handle); 375 376 return EOK; 377 } 378 379 static int tell_address_rh(ddf_fun_t *root_hub_fun, devman_handle_t handle, 260 380 usb_address_t *address) 261 381 { 262 usb_address_t addr = usb_address_keeping_find(&addresses, handle); 263 if (addr < 0) { 264 return addr; 265 } 266 267 *address = addr; 268 return EOK; 382 ddf_fun_t *hc_fun = root_hub_fun->driver_data; 383 assert(hc_fun != NULL); 384 385 return tell_address(hc_fun, root_hub_fun->handle, address); 269 386 } 270 387 … … 275 392 276 393 usbhc_iface_t vhc_iface = { 277 .tell_address = tell_address,278 279 394 .reserve_default_address = reserve_default_address, 280 395 .release_default_address = release_default_address, … … 286 401 .interrupt_in = interrupt_in, 287 402 288 .control_write_setup = control_write_setup, 289 .control_write_data = control_write_data, 290 .control_write_status = control_write_status, 291 292 .control_read_setup = control_read_setup, 293 .control_read_data = control_read_data, 294 .control_read_status = control_read_status 403 .control_write = control_write, 404 .control_read = control_read 295 405 }; 406 407 usb_iface_t vhc_usb_iface = { 408 .get_hc_handle = usb_iface_get_hc_handle_hc_impl, 409 .get_address = tell_address 410 }; 411 412 usb_iface_t rh_usb_iface = { 413 .get_hc_handle = usb_iface_get_hc_handle_rh_impl, 414 .get_address = tell_address_rh 415 }; 416 296 417 297 418 /** -
uspace/drv/vhc/devices.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 34 34 */ 35 35 36 #include <ipc/ipc.h>37 36 #include <adt/list.h> 38 37 #include <bool.h> … … 58 57 /** Create virtual device. 59 58 * 60 * @param address USB address.61 59 * @param phone Callback phone. 60 * @param id Device id. 62 61 * @return New device. 63 * @retval NULL Out of memory or address already occupied.64 */ 65 virtdev_connection_t *virtdev_add_device(int phone )62 * @retval NULL Out of memory. 63 */ 64 virtdev_connection_t *virtdev_add_device(int phone, sysarg_t id) 66 65 { 67 66 virtdev_connection_t *dev = (virtdev_connection_t *) 68 67 malloc(sizeof(virtdev_connection_t)); 68 if (dev == NULL) { 69 return NULL; 70 } 71 69 72 dev->phone = phone; 73 dev->id = id; 70 74 list_append(&dev->link, &devices); 71 75 … … 73 77 74 78 return dev; 79 } 80 81 /** Find virtual device by id. 82 * 83 * @param id Device id. 84 * @return Device with given id. 85 * @retval NULL No such device. 86 */ 87 virtdev_connection_t *virtdev_find(sysarg_t id) 88 { 89 link_t *pos; 90 list_foreach(pos, &devices) { 91 virtdev_connection_t *dev 92 = list_get_instance(pos, virtdev_connection_t, link); 93 if (dev->id == id) { 94 return dev; 95 } 96 } 97 98 return NULL; 75 99 } 76 100 … … 88 112 * @param transaction Transaction to be sent over the bus. 89 113 */ 90 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *transaction) 91 { 114 int virtdev_send_to_all(transaction_t *transaction) 115 { 116 /* For easier debugging. */ 117 switch (transaction->type) { 118 case USBVIRT_TRANSACTION_SETUP: 119 case USBVIRT_TRANSACTION_OUT: 120 transaction->actual_len = transaction->len; 121 break; 122 case USBVIRT_TRANSACTION_IN: 123 transaction->actual_len = 0; 124 break; 125 default: 126 assert(false && "unreachable branch in switch()"); 127 } 128 int outcome = EBADCHECKSUM; 129 92 130 link_t *pos; 93 131 list_foreach(pos, &devices) { … … 138 176 } else { 139 177 async_wait_for(req, &answer_rc); 178 transaction->actual_len = IPC_GET_ARG1(answer_data); 140 179 rc = (int)answer_rc; 180 } 181 182 /* 183 * If at least one device was able to accept this 184 * transaction and process it, we can announce success. 185 */ 186 if (rc == EOK) { 187 outcome = EOK; 141 188 } 142 189 } … … 148 195 if (virtual_hub_device.address == transaction->target.address) { 149 196 size_t tmp; 150 dprintf(1, "sending `%s' transaction to hub",197 usb_log_debug2("Sending `%s' transaction to hub.\n", 151 198 usbvirt_str_transaction_type(transaction->type)); 152 199 switch (transaction->type) { … … 164 211 transaction->buffer, transaction->len, 165 212 &tmp); 166 if (tmp < transaction->len) { 167 transaction->len = tmp; 168 } 213 transaction->actual_len = tmp; 169 214 break; 170 215 … … 176 221 break; 177 222 } 178 dprintf(4, "transaction on hub processed...");223 outcome = EOK; 179 224 } 180 225 … … 183 228 * real-life image. 184 229 */ 185 return USB_OUTCOME_OK;230 return outcome; 186 231 } 187 232 -
uspace/drv/vhc/devices.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 45 45 /** Phone used when sending data to device. */ 46 46 int phone; 47 /** Unique identification. */ 48 sysarg_t id; 47 49 /** Linked-list handle. */ 48 50 link_t link; 49 51 } virtdev_connection_t; 50 52 51 virtdev_connection_t *virtdev_add_device(int );52 virtdev_connection_t *virtdev_ get_mine(void);53 virtdev_connection_t *virtdev_add_device(int, sysarg_t); 54 virtdev_connection_t *virtdev_find(sysarg_t); 53 55 void virtdev_destroy_device(virtdev_connection_t *); 54 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *);56 int virtdev_send_to_all(transaction_t *); 55 57 56 58 #endif -
uspace/drv/vhc/hc.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 34 34 */ 35 35 36 #include <ipc/ipc.h>37 36 #include <adt/list.h> 38 37 #include <bool.h> … … 90 89 */ 91 90 static void process_transaction_with_outcome(transaction_t * transaction, 92 usb_transaction_outcome_t outcome)93 { 94 dprintf(3, "transaction " TRANSACTION_FORMAT " done, outcome: %s",91 int outcome) 92 { 93 usb_log_debug2("Transaction " TRANSACTION_FORMAT " done: %s.\n", 95 94 TRANSACTION_PRINTF(*transaction), 96 usb_str_transaction_outcome(outcome));97 98 transaction->callback(transaction->buffer, transaction-> len, outcome,99 transaction->callback_arg);95 str_error(outcome)); 96 97 transaction->callback(transaction->buffer, transaction->actual_len, 98 outcome, transaction->callback_arg); 100 99 } 101 100 … … 108 107 static unsigned int seed = 4573; 109 108 110 printf("%s: transaction processor ready.\n", NAME);109 usb_log_info("Transaction processor ready.\n"); 111 110 112 111 while (true) { … … 125 124 list_remove(first_transaction_link); 126 125 127 128 dprintf(0, "about to process " TRANSACTION_FORMAT " [%s]", 126 usb_log_debug("Processing " TRANSACTION_FORMAT " [%s].\n", 129 127 TRANSACTION_PRINTF(*transaction), ports); 130 128 131 dprintf(3, "processing transaction " TRANSACTION_FORMAT "", 132 TRANSACTION_PRINTF(*transaction)); 133 134 usb_transaction_outcome_t outcome; 129 int outcome; 135 130 outcome = virtdev_send_to_all(transaction); 136 131 … … 148 143 fid_t fid = fibril_create(hc_manager_fibril, NULL); 149 144 if (fid == 0) { 150 printf(NAME ": failed to start HC manager fibril\n");145 usb_log_fatal("Failed to start HC manager fibril.\n"); 151 146 return; 152 147 } … … 169 164 transaction->buffer = buffer; 170 165 transaction->len = len; 166 transaction->actual_len = len; 171 167 transaction->callback = callback; 172 168 transaction->callback_arg = arg; 173 174 dprintf(3, "creating transaction " TRANSACTION_FORMAT, 169 170 return transaction; 171 } 172 173 static void hc_add_transaction(transaction_t *transaction) 174 { 175 usb_log_debug("Adding transaction " TRANSACTION_FORMAT ".\n", 175 176 TRANSACTION_PRINTF(*transaction)); 176 177 return transaction; 177 list_append(&transaction->link, &transaction_list); 178 178 } 179 179 … … 189 189 target, transfer_type, 190 190 buffer, len, callback, arg); 191 list_append(&transaction->link, &transaction_list);191 hc_add_transaction(transaction); 192 192 } 193 193 … … 202 202 target, transfer_type, 203 203 buffer, len, callback, arg); 204 list_append(&transaction->link, &transaction_list);204 hc_add_transaction(transaction); 205 205 } 206 206 -
uspace/drv/vhc/hc.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 47 47 */ 48 48 typedef void (*hc_transaction_done_callback_t)(void *buffer, size_t size, 49 usb_transaction_outcome_t outcome, void *arg);49 int outcome, void *arg); 50 50 51 51 /** Pending transaction details. */ … … 65 65 /** Transaction data length. */ 66 66 size_t len; 67 /** Data length actually transfered. */ 68 size_t actual_len; 67 69 /** Callback after transaction is done. */ 68 70 hc_transaction_done_callback_t callback; -
uspace/drv/vhc/hcd.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 35 35 36 36 #include <devmap.h> 37 #include <ipc/ipc.h>38 37 #include <async.h> 39 38 #include <unistd.h> … … 43 42 #include <errno.h> 44 43 #include <str_error.h> 45 #include <d river.h>44 #include <ddf/driver.h> 46 45 47 46 #include <usb/usb.h> 47 #include <usb/ddfiface.h> 48 48 #include <usb_iface.h> 49 49 #include "vhcd.h" … … 53 53 #include "conn.h" 54 54 55 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 56 { 57 /* This shall be called only for VHC device. */ 58 assert(dev->parent == NULL); 59 60 *handle = dev->handle; 61 return EOK; 62 } 63 64 static usb_iface_t hc_usb_iface = { 65 .get_hc_handle = usb_iface_get_hc_handle 66 }; 67 68 static device_ops_t vhc_ops = { 55 static ddf_dev_ops_t vhc_ops = { 69 56 .interfaces[USBHC_DEV_IFACE] = &vhc_iface, 70 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 57 .interfaces[USB_DEV_IFACE] = &vhc_usb_iface, 58 .close = on_client_close, 71 59 .default_handler = default_connection_handler 72 60 }; 73 61 74 static int vhc_count = 0; 75 static int vhc_add_device(device_t *dev) 62 static int vhc_add_device(ddf_dev_t *dev) 76 63 { 64 static int vhc_count = 0; 65 int rc; 66 77 67 /* 78 68 * Currently, we know how to simulate only single HC. … … 82 72 } 83 73 84 vhc_count++; 74 /* 75 * Create exposed function representing the host controller 76 * itself. 77 */ 78 ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc"); 79 if (hc == NULL) { 80 usb_log_fatal("Failed to create device function.\n"); 81 return ENOMEM; 82 } 85 83 86 dev->ops = &vhc_ops;84 hc->ops = &vhc_ops; 87 85 88 devman_add_device_to_class(dev->handle, "usbhc"); 86 rc = ddf_fun_bind(hc); 87 if (rc != EOK) { 88 usb_log_fatal("Failed to bind HC function: %s.\n", 89 str_error(rc)); 90 return rc; 91 } 92 93 ddf_fun_add_to_class(hc, "usbhc"); 89 94 90 95 /* 91 96 * Initialize our hub and announce its presence. 92 97 */ 93 virtual_hub_device_init( dev);98 virtual_hub_device_init(hc); 94 99 95 printf("%s: virtual USB host controller ready.\n", NAME); 100 usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n", 101 (size_t) dev->handle, (size_t) hc->handle); 96 102 97 103 return EOK; … … 114 120 * in devman output. 115 121 */ 116 sleep(5);122 //sleep(5); 117 123 118 usb_ dprintf_enable(NAME, 0);124 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 119 125 120 126 printf(NAME ": virtual USB host controller driver.\n"); … … 133 139 * We are also a driver within devman framework. 134 140 */ 135 return d river_main(&vhc_driver);141 return ddf_driver_main(&vhc_driver); 136 142 } 137 143 -
uspace/drv/vhc/hub.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 39 39 #include <str_error.h> 40 40 #include <stdlib.h> 41 #include <driver.h> 42 #include <usb/usbdrv.h> 41 #include <ddf/driver.h> 42 #include <devman.h> 43 #include <usb/hub.h> 44 #include <usb/recognise.h> 43 45 44 46 #include "hub.h" 45 47 #include "hub/virthub.h" 46 48 #include "vhcd.h" 49 #include "conn.h" 47 50 48 51 usbvirt_device_t virtual_hub_device; 52 static ddf_dev_ops_t rh_ops = { 53 .interfaces[USB_DEV_IFACE] = &rh_usb_iface, 54 }; 49 55 50 56 static int hub_register_in_devman_fibril(void *arg); 51 57 52 void virtual_hub_device_init(d evice_t *hc_dev)58 void virtual_hub_device_init(ddf_fun_t *hc_dev) 53 59 { 54 60 virthub_init(&virtual_hub_device); … … 63 69 = fibril_create(hub_register_in_devman_fibril, hc_dev); 64 70 if (root_hub_registration == 0) { 65 printf(NAME ": failed to register root hub\n");71 usb_log_fatal("Failed to create hub registration fibril.\n"); 66 72 return; 67 73 } 68 74 69 75 fibril_add_ready(root_hub_registration); 76 } 77 78 static int pretend_port_rest(int unused, void *unused2) 79 { 80 return EOK; 70 81 } 71 82 … … 77 88 int hub_register_in_devman_fibril(void *arg) 78 89 { 79 d evice_t *hc_dev = (device_t *) arg;90 ddf_fun_t *hc_dev = (ddf_fun_t *) arg; 80 91 81 int hc = usb_drv_hc_connect(hc_dev, hc_dev->handle, IPC_FLAG_BLOCKING); 82 if (hc < 0) { 83 printf(NAME ": failed to register root hub\n"); 84 return hc; 92 /* 93 * Wait until parent device is properly initialized. 94 */ 95 int phone; 96 do { 97 phone = devman_device_connect(hc_dev->handle, 0); 98 } while (phone < 0); 99 async_hangup(phone); 100 101 int rc; 102 103 usb_hc_connection_t hc_conn; 104 rc = usb_hc_connection_initialize(&hc_conn, hc_dev->handle); 105 assert(rc == EOK); 106 107 rc = usb_hc_connection_open(&hc_conn); 108 assert(rc == EOK); 109 110 ddf_fun_t *hub_dev; 111 rc = usb_hc_new_device_wrapper(hc_dev->dev, &hc_conn, 112 USB_SPEED_FULL, 113 pretend_port_rest, 0, NULL, 114 NULL, NULL, &rh_ops, hc_dev, &hub_dev); 115 if (rc != EOK) { 116 usb_log_fatal("Failed to create root hub: %s.\n", 117 str_error(rc)); 85 118 } 86 119 87 usb_ drv_reserve_default_address(hc);120 usb_hc_connection_close(&hc_conn); 88 121 89 usb_ address_t hub_address = usb_drv_request_address(hc);90 usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, hub_address);122 usb_log_info("Created root hub function (handle %zu).\n", 123 (size_t) hub_dev->handle); 91 124 92 usb_drv_release_default_address(hc); 93 94 devman_handle_t hub_handle; 95 usb_drv_register_child_in_devman(hc, hc_dev, hub_address, &hub_handle); 96 usb_drv_bind_address(hc, hub_address, hub_handle); 97 98 return EOK; 125 return 0; 99 126 } 100 127 -
uspace/drv/vhc/hub.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 37 37 38 38 #include <usbvirt/device.h> 39 #include <d river.h>39 #include <ddf/driver.h> 40 40 41 41 #include "devices.h" … … 45 45 extern usbvirt_device_t virtual_hub_device; 46 46 47 void virtual_hub_device_init(d evice_t *);47 void virtual_hub_device_init(ddf_fun_t *); 48 48 49 49 #endif -
uspace/drv/vhc/hub/hub.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 38 38 #include <errno.h> 39 39 #include <str_error.h> 40 #include <assert.h> 40 41 #include <stdlib.h> 41 #include <driver.h> 42 #include <usb/usbdrv.h> 42 #include <ddf/driver.h> 43 43 44 44 #include "hub.h" … … 155 155 } 156 156 157 /** Disconnects a device from a hub. 158 * 159 * @param hub Hub the device was connected to. 160 * @param device Device to be disconnected. 161 * @return Error code. 162 */ 163 int hub_disconnect_device(hub_t *hub, void *device) 164 { 165 size_t index = hub_find_device(hub, device); 166 if (index == (size_t) -1) { 167 return ENOENT; 168 } 169 170 hub_port_t *port = &hub->ports[index]; 171 172 port->connected_device = NULL; 173 port->state = HUB_PORT_STATE_DISCONNECTED; 174 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION); 175 176 return EOK; 177 } 178 157 179 /** Find port device is connected to. 158 180 * … … 173 195 } 174 196 175 return 0;197 return -1; 176 198 } 177 199 -
uspace/drv/vhc/hub/hub.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 38 38 #include <fibril_synch.h> 39 39 40 #ifndef HUB_PORT_COUNT 40 41 #define HUB_PORT_COUNT 2 42 #endif 41 43 #define BITS2BYTES(bits) (bits ? ((((bits)-1)>>3)+1) : 0) 42 44 … … 94 96 void hub_init(hub_t *); 95 97 size_t hub_connect_device(hub_t *, void *); 98 int hub_disconnect_device(hub_t *, void *); 96 99 size_t hub_find_device(hub_t *, void *); 97 100 void hub_acquire(hub_t *); -
uspace/drv/vhc/hub/virthub.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 39 39 #include <errno.h> 40 40 #include <str_error.h> 41 #include <assert.h> 41 42 #include <stdlib.h> 42 #include <driver.h> 43 #include <usb/usbdrv.h> 43 #include <ddf/driver.h> 44 44 45 45 #include "virthub.h" … … 164 164 dev->device_data = hub; 165 165 166 usbvirt_connect_local(dev); 167 168 return EOK; 166 int rc; 167 #ifdef STANDALONE_HUB 168 dev->name = "hub"; 169 rc = usbvirt_connect(dev); 170 #else 171 rc = usbvirt_connect_local(dev); 172 #endif 173 174 return rc; 169 175 } 170 176 … … 203 209 204 210 hub_acquire(hub); 205 /* TODO: implement. */211 hub_disconnect_device(hub, conn); 206 212 hub_release(hub); 207 213 -
uspace/drv/vhc/hub/virthub.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 37 37 38 38 #include <usbvirt/device.h> 39 #include "hub.h" 40 41 #ifdef STANDALONE_HUB 42 #define virtdev_connection_t int 43 #else 39 44 #include "../devices.h" 40 # include "hub.h"45 #endif 41 46 42 47 /** Endpoint number for status change pipe. */ -
uspace/drv/vhc/hub/virthubops.c
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ -
uspace/drv/vhc/vhcd.h
r976f546 r19a1800 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbvhc 30 30 * @{ 31 31 */ … … 45 45 #define DEVMAP_PATH_DEV NAMESPACE "/" NAME_DEV 46 46 47 #define dprintf(level, format, ...) \ 48 usb_dprintf(NAME, (level), format "\n", ##__VA_ARGS__)49 void dprintf_inval_call(int, ipc_call_t, sysarg_t);47 //#define dprintf(level, format, ...) 48 // usb_dprintf(NAME, (level), format "\n", ##__VA_ARGS__) 49 //void dprintf_inval_call(int, ipc_call_t, sysarg_t); 50 50 51 51 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
