Changeset 92574f4 in mainline for uspace/drv
- Timestamp:
- 2011-02-24T12:03:27Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e7b7ebd5
- Parents:
- 4837092 (diff), a80849c (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:
-
- 31 added
- 34 edited
- 6 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 (added)
-
uhci-hcd/batch.c (added)
-
uhci-hcd/batch.h (added)
-
uhci-hcd/iface.c (added)
-
uhci-hcd/iface.h (added)
-
uhci-hcd/main.c (added)
-
uhci-hcd/pci.c (moved) (moved from uspace/drv/uhci/pci.c ) (3 diffs)
-
uhci-hcd/pci.h (moved) (moved from uspace/drv/uhci/uhci.h ) (2 diffs)
-
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 (moved) (moved from uspace/drv/uhci/uhci.ma ) (1 diff)
-
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/malloc32.h (added)
-
uhci-rhd/Makefile (added)
-
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)
-
usbhid/descdump.c (modified) (1 diff)
-
usbhid/descparser.c (modified) (1 diff)
-
usbhid/hid.h (modified) (2 diffs)
-
usbhid/main.c (modified) (20 diffs)
-
usbhub/main.c (modified) (3 diffs)
-
usbhub/port_status.h (modified) (1 diff)
-
usbhub/usbhub.c (modified) (16 diffs)
-
usbhub/usbhub.h (modified) (3 diffs)
-
usbhub/usbhub_private.h (modified) (7 diffs)
-
usbhub/utils.c (modified) (5 diffs)
-
usbmid/Makefile (moved) (moved from uspace/drv/uhci/Makefile ) (2 diffs)
-
usbmid/dump.c (added)
-
usbmid/explore.c (added)
-
usbmid/main.c (moved) (moved from uspace/drv/uhci/main.c ) (2 diffs)
-
usbmid/usbmid.c (added)
-
usbmid/usbmid.h (added)
-
usbmid/usbmid.ma (added)
-
vhc/conn.h (modified) (2 diffs)
-
vhc/conndev.c (modified) (4 diffs)
-
vhc/connhost.c (modified) (28 diffs)
-
vhc/devices.c (modified) (5 diffs)
-
vhc/devices.h (modified) (1 diff)
-
vhc/hc.c (modified) (3 diffs)
-
vhc/hc.h (modified) (1 diff)
-
vhc/hcd.c (modified) (6 diffs)
-
vhc/hub.c (modified) (3 diffs)
-
vhc/hub.h (modified) (2 diffs)
-
vhc/hub/hub.c (modified) (1 diff)
-
vhc/hub/virthub.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/isa/isa.c
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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); 288 322 289 323 io = (bool) (val & 1); … … 305 339 306 340 /* Get the address mask. */ 307 pci_conf_write_32( dev, addr, 0xffffffff);308 mask = pci_conf_read_32( dev, addr);341 pci_conf_write_32(fun, addr, 0xffffffff); 342 mask = pci_conf_read_32(fun, addr); 309 343 310 344 /* Restore the original value. */ 311 pci_conf_write_32( dev, addr, val);312 val = pci_conf_read_32( dev, addr);345 pci_conf_write_32(fun, addr, val); 346 val = pci_conf_read_32(fun, addr); 313 347 314 348 range_size = pci_bar_mask_to_size(mask); 315 349 316 350 if (addrw64) { 317 range_addr = ((uint64_t)pci_conf_read_32( dev, addr + 4) << 32) |351 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | 318 352 (val & 0xfffffff0); 319 353 } else { … … 322 356 323 357 if (range_addr != 0) { 324 printf(NAME ": device %s : ", dev->name);358 printf(NAME ": function %s : ", fun->fnode->name); 325 359 printf("address = %" PRIx64, range_addr); 326 360 printf(", size = %x\n", (unsigned int) range_size); 327 361 } 328 362 329 pci_add_range( dev, range_addr, range_size, io);363 pci_add_range(fun, range_addr, range_size, io); 330 364 331 365 if (addrw64) … … 335 369 } 336 370 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; 371 void pci_add_interrupt(pci_fun_t *fun, int irq) 372 { 373 hw_resource_list_t *hw_res_list = &fun->hw_resources; 341 374 hw_resource_t *hw_resources = hw_res_list->resources; 342 375 size_t count = hw_res_list->count; … … 350 383 hw_res_list->count++; 351 384 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);385 printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq); 386 } 387 388 void pci_read_interrupt(pci_fun_t *fun) 389 { 390 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 358 391 if (irq != 0xff) 359 pci_add_interrupt( dev, irq);392 pci_add_interrupt(fun, irq); 360 393 } 361 394 362 395 /** Enumerate (recursively) and register the devices connected to a pci bus. 363 396 * 364 * @param parent The host-to-pci bridge device.365 * @param bus_num The bus number.397 * @param bus Host-to-PCI bridge 398 * @param bus_num Bus number 366 399 */ 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; 400 void pci_bus_scan(pci_bus_t *bus, int bus_num) 401 { 402 ddf_fun_t *fnode; 403 pci_fun_t *fun; 373 404 374 405 int child_bus = 0; 375 406 int dnum, fnum; 376 407 bool multi; 377 uint8_t header_type; 408 uint8_t header_type; 409 410 fun = pci_fun_new(bus); 378 411 379 412 for (dnum = 0; dnum < 32; dnum++) { 380 413 multi = true; 381 414 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,415 pci_fun_init(fun, bus_num, dnum, fnum); 416 fun->vendor_id = pci_conf_read_16(fun, 384 417 PCI_VENDOR_ID); 385 dev_data->device_id = pci_conf_read_16(dev,418 fun->device_id = pci_conf_read_16(fun, 386 419 PCI_DEVICE_ID); 387 if ( dev_data->vendor_id == 0xffff) {420 if (fun->vendor_id == 0xffff) { 388 421 /* 389 422 * The device is not present, go on scanning the … … 396 429 } 397 430 398 header_type = pci_conf_read_8( dev, PCI_HEADER_TYPE);431 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 399 432 if (fnum == 0) { 400 433 /* Is the device multifunction? */ … … 404 437 header_type = header_type & 0x7F; 405 438 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; 439 char *fun_name = pci_fun_create_name(fun); 440 if (fun_name == NULL) { 441 printf(NAME ": out of memory.\n"); 442 return; 443 } 444 445 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 446 if (fnode == NULL) { 447 printf(NAME ": error creating function.\n"); 448 return; 449 } 450 451 free(fun_name); 452 fun->fnode = fnode; 453 454 pci_alloc_resource_list(fun); 455 pci_read_bars(fun); 456 pci_read_interrupt(fun); 457 458 fnode->ops = &pci_fun_ops; 459 fnode->driver_data = fun; 460 461 printf(NAME ": adding new function %s.\n", 462 fnode->name); 463 464 pci_fun_create_match_ids(fun); 465 466 if (ddf_fun_bind(fnode) != EOK) { 467 pci_clean_resource_list(fun); 468 clean_match_ids(&fnode->match_ids); 469 free((char *) fnode->name); 470 fnode->name = NULL; 424 471 continue; 425 472 } … … 427 474 if (header_type == PCI_HEADER_TYPE_BRIDGE || 428 475 header_type == PCI_HEADER_TYPE_CARDBUS) { 429 child_bus = pci_conf_read_8( dev,476 child_bus = pci_conf_read_8(fun, 430 477 PCI_BRIDGE_SEC_BUS_NUM); 431 478 printf(NAME ": device is pci-to-pci bridge, " 432 479 "secondary bus number = %d.\n", bus_num); 433 480 if (child_bus > bus_num) 434 pci_bus_scan( parent, child_bus);481 pci_bus_scan(bus, child_bus); 435 482 } 436 483 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; 484 fun = pci_fun_new(bus); 442 485 } 443 486 } 444 487 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 { 488 if (fun->vendor_id == 0xffff) { 489 /* Free the auxiliary function structure. */ 490 pci_fun_delete(fun); 491 } 492 } 493 494 static int pci_add_device(ddf_dev_t *dnode) 495 { 496 pci_bus_t *bus = NULL; 497 ddf_fun_t *ctl = NULL; 498 bool got_res = false; 454 499 int rc; 455 500 456 501 printf(NAME ": pci_add_device\n"); 457 458 pci_bus_data_t *bus_data = create_pci_bus_data(); 459 if (bus_data == NULL) { 502 dnode->parent_phone = -1; 503 504 bus = pci_bus_new(); 505 if (bus == NULL) { 460 506 printf(NAME ": pci_add_device allocation failed.\n"); 461 return ENOMEM; 462 } 463 464 dev->parent_phone = devman_parent_device_connect(dev->handle, 507 rc = ENOMEM; 508 goto fail; 509 } 510 bus->dnode = dnode; 511 dnode->driver_data = bus; 512 513 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 465 514 IPC_FLAG_BLOCKING); 466 if (d ev->parent_phone < 0) {515 if (dnode->parent_phone < 0) { 467 516 printf(NAME ": pci_add_device failed to connect to the " 468 517 "parent's driver.\n"); 469 delete_pci_bus_data(bus_data);470 return dev->parent_phone;518 rc = dnode->parent_phone; 519 goto fail; 471 520 } 472 521 473 522 hw_resource_list_t hw_resources; 474 523 475 rc = hw_res_get_resource_list(d ev->parent_phone, &hw_resources);524 rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources); 476 525 if (rc != EOK) { 477 526 printf(NAME ": pci_add_device failed to get hw resources for " 478 527 "the device.\n"); 479 delete_pci_bus_data(bus_data); 480 ipc_hangup(dev->parent_phone); 481 return rc; 482 } 528 goto fail; 529 } 530 got_res = true; 483 531 484 532 printf(NAME ": conf_addr = %" PRIx64 ".\n", … … 489 537 assert(hw_resources.resources[0].res.io_range.size == 8); 490 538 491 bus _data->conf_io_addr =539 bus->conf_io_addr = 492 540 (uint32_t) hw_resources.resources[0].res.io_range.address; 493 541 494 if (pio_enable((void *)(uintptr_t)bus _data->conf_io_addr, 8,495 &bus _data->conf_addr_port)) {542 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 543 &bus->conf_addr_port)) { 496 544 printf(NAME ": failed to enable configuration ports.\n"); 497 delete_pci_bus_data(bus_data); 498 ipc_hangup(dev->parent_phone); 545 rc = EADDRNOTAVAIL; 546 goto fail; 547 } 548 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 549 550 /* Make the bus device more visible. It has no use yet. */ 551 printf(NAME ": adding a 'ctl' function\n"); 552 553 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 554 if (ctl == NULL) { 555 printf(NAME ": error creating control function.\n"); 556 rc = ENOMEM; 557 goto fail; 558 } 559 560 rc = ddf_fun_bind(ctl); 561 if (rc != EOK) { 562 printf(NAME ": error binding control function.\n"); 563 goto fail; 564 } 565 566 /* Enumerate functions. */ 567 printf(NAME ": scanning the bus\n"); 568 pci_bus_scan(bus, 0); 569 570 hw_res_clean_resource_list(&hw_resources); 571 572 return EOK; 573 574 fail: 575 if (bus != NULL) 576 pci_bus_delete(bus); 577 if (dnode->parent_phone >= 0) 578 async_hangup(dnode->parent_phone); 579 if (got_res) 499 580 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; 581 if (ctl != NULL) 582 ddf_fun_destroy(ctl); 583 584 return rc; 513 585 } 514 586 515 587 static void pciintel_init(void) 516 588 { 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; 589 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 590 } 591 592 pci_fun_t *pci_fun_new(pci_bus_t *bus) 593 { 594 pci_fun_t *fun; 595 596 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 597 if (fun == NULL) 598 return NULL; 599 600 fun->busptr = bus; 601 return fun; 602 } 603 604 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 605 { 606 fun->bus = bus; 607 fun->dev = dev; 608 fun->fn = fn; 609 } 610 611 void pci_fun_delete(pci_fun_t *fun) 612 { 613 assert(fun != NULL); 614 hw_res_clean_resource_list(&fun->hw_resources); 615 free(fun); 616 } 617 618 char *pci_fun_create_name(pci_fun_t *fun) 619 { 547 620 char *name = NULL; 548 621 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 = 622 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 623 fun->fn); 624 return name; 625 } 626 627 bool pci_alloc_resource_list(pci_fun_t *fun) 628 { 629 fun->hw_resources.resources = 559 630 (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. 631 return fun->hw_resources.resources != NULL; 632 } 633 634 void pci_clean_resource_list(pci_fun_t *fun) 635 { 636 if (fun->hw_resources.resources != NULL) { 637 free(fun->hw_resources.resources); 638 fun->hw_resources.resources = NULL; 639 } 640 } 641 642 /** Read the base address registers (BARs) of the function and add the addresses 643 * to its HW resource list. 575 644 * 576 * @param dev the pci device.645 * @param fun PCI function 577 646 */ 578 void pci_read_bars( device_t *dev)647 void pci_read_bars(pci_fun_t *fun) 579 648 { 580 649 /* … … 585 654 586 655 while (addr <= PCI_BASE_ADDR_5) 587 addr = pci_read_bar( dev, addr);656 addr = pci_read_bar(fun, addr); 588 657 } 589 658 … … 597 666 printf(NAME ": HelenOS pci bus driver (intel method 1).\n"); 598 667 pciintel_init(); 599 return d river_main(&pci_driver);668 return ddf_driver_main(&pci_driver); 600 669 } 601 670 -
uspace/drv/pciintel/pci.h
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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
r4837092 r92574f4 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/pci.c
r4837092 r92574f4 34 34 * PCI related functions needed by the UHCI driver. 35 35 */ 36 #include "uhci.h"37 36 #include <errno.h> 38 37 #include <assert.h> 39 38 #include <devman.h> 40 39 #include <device/hw_res.h> 40 41 #include "pci.h" 41 42 42 43 /** Get address of registers and IRQ for given device. … … 48 49 * @return Error code. 49 50 */ 50 int pci_get_my_registers(d evice_t *dev,51 int pci_get_my_registers(ddf_dev_t *dev, 51 52 uintptr_t *io_reg_address, size_t *io_reg_size, 52 53 int *irq_no) … … 116 117 rc = EOK; 117 118 leave: 118 ipc_hangup(parent_phone);119 async_hangup(parent_phone); 119 120 120 121 return rc; 121 122 } 123 /*----------------------------------------------------------------------------*/ 124 int pci_enable_interrupts(ddf_dev_t *device) 125 { 126 int parent_phone = devman_parent_device_connect(device->handle, 127 IPC_FLAG_BLOCKING); 128 bool enabled = hw_res_enable_interrupt(parent_phone); 129 return enabled ? EOK : EIO; 130 } 131 /** 132 * @} 133 */ 122 134 123 135 /** 124 136 * @} 125 137 */ 126 -
uspace/drv/uhci-hcd/pci.h
r4837092 r92574f4 33 33 * @brief UHCI driver 34 34 */ 35 #ifndef DRV_UHCI_ UHCI_H36 #define DRV_UHCI_ UHCI_H35 #ifndef DRV_UHCI_PCI_H 36 #define DRV_UHCI_PCI_H 37 37 38 #include < usbhc_iface.h>38 #include <ddf/driver.h> 39 39 40 #define NAME "uhci" 41 42 usbhc_iface_t uhci_iface; 43 44 int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *); 40 int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 int pci_enable_interrupts(ddf_dev_t *); 45 42 46 43 #endif … … 48 45 * @} 49 46 */ 47 -
uspace/drv/uhci-hcd/uhci-hcd.ma
r4837092 r92574f4 1 1 10 pci/ven=8086&dev=7020 2 2 10 pci/ven=8086&dev=7112 -
uspace/drv/usbhid/descdump.c
r4837092 r92574f4 35 35 36 36 #include <usb/classes/hid.h> 37 #include <stdio.h> 38 #include <assert.h> 37 39 38 40 #include "descdump.h" -
uspace/drv/usbhid/descparser.c
r4837092 r92574f4 36 36 #include <errno.h> 37 37 #include <stdint.h> 38 #include <stdio.h> 38 39 #include <usb/usb.h> 39 40 #include <usb/classes/hid.h> -
uspace/drv/usbhid/hid.h
r4837092 r92574f4 40 40 41 41 #include <usb/classes/hid.h> 42 #include <d river.h>42 #include <ddf/driver.h> 43 43 #include <usb/pipes.h> 44 44 … … 69 69 */ 70 70 typedef struct { 71 d evice_t *device;71 ddf_dev_t *device; 72 72 usb_hid_configuration_t *conf; 73 usb_address_t address;74 73 usb_hid_report_parser_t *parser; 75 74 76 75 usb_device_connection_t wire; 76 usb_endpoint_pipe_t ctrl_pipe; 77 77 usb_endpoint_pipe_t poll_pipe; 78 78 -
uspace/drv/usbhid/main.c
r4837092 r92574f4 36 36 */ 37 37 38 #include <usb/usbdrv.h> 39 #include <driver.h> 38 #include <ddf/driver.h> 40 39 #include <ipc/driver.h> 41 40 #include <ipc/kbd.h> … … 45 44 #include <str_error.h> 46 45 #include <fibril.h> 46 #include <usb/debug.h> 47 #include <usb/classes/classes.h> 47 48 #include <usb/classes/hid.h> 48 49 #include <usb/classes/hidparser.h> 49 #include <usb/ devreq.h>50 #include <usb/request.h> 50 51 #include <usb/descriptor.h> 51 #include <usb/debug.h>52 52 #include <io/console.h> 53 53 #include <stdint.h> … … 58 58 #include "layout.h" 59 59 60 #define BUFFER_SIZE 3260 #define BUFFER_SIZE 8 61 61 #define NAME "usbhid" 62 62 … … 64 64 #define BOOTP_REPORT_SIZE 6 65 65 66 static void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *); 67 static device_ops_t keyboard_ops = { 66 /** Keyboard polling endpoint description for boot protocol class. */ 67 static usb_endpoint_description_t poll_endpoint_description = { 68 .transfer_type = USB_TRANSFER_INTERRUPT, 69 .direction = USB_DIRECTION_IN, 70 .interface_class = USB_CLASS_HID, 71 .interface_subclass = USB_HID_SUBCLASS_BOOT, 72 .interface_protocol = USB_HID_PROTOCOL_KEYBOARD, 73 .flags = 0 74 }; 75 76 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 77 static ddf_dev_ops_t keyboard_ops = { 68 78 .default_handler = default_connection_handler 69 79 }; … … 77 87 * @param icall Call data. 78 88 */ 79 void default_connection_handler(d evice_t *dev,89 void default_connection_handler(ddf_fun_t *fun, 80 90 ipc_callid_t icallid, ipc_call_t *icall) 81 91 { … … 86 96 87 97 if (console_callback_phone != -1) { 88 ipc_answer_0(icallid, ELIMIT);98 async_answer_0(icallid, ELIMIT); 89 99 return; 90 100 } 91 101 92 102 console_callback_phone = callback; 93 ipc_answer_0(icallid, EOK);103 async_answer_0(icallid, EOK); 94 104 return; 95 105 } 96 106 97 ipc_answer_0(icallid, EINVAL);107 async_answer_0(icallid, EINVAL); 98 108 } 99 109 … … 387 397 388 398 // get the descriptor from the device 389 int rc = usb_ drv_req_get_descriptor(390 kbd_dev->device->parent_phone, kbd_dev->address,391 USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,392 0, i, kbd_dev->conf->interfaces[i].report_desc, length,399 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe, 400 USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 401 i, 0, 402 kbd_dev->conf->interfaces[i].report_desc, length, 393 403 &actual_size); 394 404 … … 411 421 usb_standard_configuration_descriptor_t config_desc; 412 422 413 int rc = usb_drv_req_get_bare_configuration_descriptor( 414 kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc); 423 int rc; 424 rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe, 425 0, &config_desc); 415 426 416 427 if (rc != EOK) { … … 426 437 size_t transferred = 0; 427 438 // get full configuration descriptor 428 rc = usb_ drv_req_get_full_configuration_descriptor(429 kbd_dev->device->parent_phone, kbd_dev->address,0, descriptors,439 rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe, 440 0, descriptors, 430 441 config_desc.total_length, &transferred); 431 442 … … 437 448 } 438 449 450 /* 451 * Initialize the interrupt in endpoint. 452 */ 453 usb_endpoint_mapping_t endpoint_mapping[1] = { 454 { 455 .pipe = &kbd_dev->poll_pipe, 456 .description = &poll_endpoint_description, 457 .interface_no = 458 usb_device_get_assigned_interface(kbd_dev->device) 459 } 460 }; 461 rc = usb_endpoint_pipe_initialize_from_configuration( 462 endpoint_mapping, 1, 463 descriptors, config_desc.total_length, 464 &kbd_dev->wire); 465 if (rc != EOK) { 466 usb_log_error("Failed to initialize poll pipe: %s.\n", 467 str_error(rc)); 468 return rc; 469 } 470 if (!endpoint_mapping[0].present) { 471 usb_log_warning("Not accepting device, " \ 472 "not boot-protocol keyboard.\n"); 473 return EREFUSED; 474 } 475 476 477 478 439 479 kbd_dev->conf = (usb_hid_configuration_t *)calloc(1, 440 480 sizeof(usb_hid_configuration_t)); … … 444 484 } 445 485 446 rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);486 /*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf); 447 487 free(descriptors); 448 488 if (rc != EOK) { … … 451 491 } 452 492 453 // get and report descriptors 493 // get and report descriptors*/ 454 494 rc = usbkbd_get_report_descriptor(kbd_dev); 455 495 if (rc != EOK) { … … 469 509 * as the endpoint for polling 470 510 */ 471 511 472 512 return EOK; 473 513 } 474 514 475 static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev) 476 { 515 static usb_hid_dev_kbd_t *usbkbd_init_device(ddf_dev_t *dev) 516 { 517 int rc; 518 477 519 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1, 478 520 sizeof(usb_hid_dev_kbd_t)); … … 485 527 kbd_dev->device = dev; 486 528 487 // get phone to my HC and save it as my parent's phone 488 // TODO: maybe not a good idea if DDF will use parent_phone 489 int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0); 490 if (rc < 0) { 491 usb_log_error("Problem setting phone to HC.\n"); 529 /* 530 * Initialize the backing connection to the host controller. 531 */ 532 rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev); 533 if (rc != EOK) { 534 printf("Problem initializing connection to device: %s.\n", 535 str_error(rc)); 492 536 goto error_leave; 493 537 } 494 538 495 rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev); 496 if (rc < 0) { 497 usb_log_error("Problem getting address of the device.\n"); 539 /* 540 * Initialize device pipes. 541 */ 542 rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe, 543 &kbd_dev->wire); 544 if (rc != EOK) { 545 printf("Failed to initialize default control pipe: %s.\n", 546 str_error(rc)); 498 547 goto error_leave; 499 548 } 500 549 501 // doesn't matter now that we have no address502 // if (kbd_dev->address < 0) {503 // usb_log_error("No device address!\n");504 // free(kbd_dev);505 // return NULL;506 // }507 508 550 /* 509 551 * will need all descriptors: 510 * 1) choose one configuration from configuration descriptors 552 * 1) choose one configuration from configuration descriptors 511 553 * (set it to the device) 512 554 * 2) set endpoints from endpoint descriptors 513 555 */ 514 556 515 usbkbd_process_descriptors(kbd_dev); 516 517 // save the size of the report 518 kbd_dev->keycode_count = BOOTP_REPORT_SIZE; 519 kbd_dev->keycodes = (uint8_t *)calloc( 520 kbd_dev->keycode_count, sizeof(uint8_t)); 521 522 if (kbd_dev->keycodes == NULL) { 523 usb_log_fatal("No memory!\n"); 557 // TODO: get descriptors, parse descriptors and save endpoints 558 usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe); 559 //usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1); 560 rc = usbkbd_process_descriptors(kbd_dev); 561 usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe); 562 if (rc != EOK) { 524 563 goto error_leave; 525 564 } 526 527 // set configuration to the first one528 // TODO: handle case with no configurations529 usb_drv_req_set_configuration(kbd_dev->device->parent_phone,530 kbd_dev->address,531 kbd_dev->conf->config_descriptor.configuration_number);532 533 /*534 * Initialize the backing connection to the host controller.535 */536 rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev);537 if (rc != EOK) {538 usb_log_error("Problem initializing connection to device: %s."539 "\n", str_error(rc));540 goto error_leave;541 }542 543 /*544 * Initialize device pipes.545 */546 rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire,547 GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, USB_DIRECTION_IN);548 if (rc != EOK) {549 usb_log_error("Failed to initialize interrupt in pipe: %s.\n",550 str_error(rc));551 goto error_leave;552 }553 554 565 555 566 return kbd_dev; … … 591 602 592 603 while (true) { 593 async_usleep(1000 * 10 00 * 2);604 async_usleep(1000 * 10); 594 605 595 606 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe); … … 643 654 } 644 655 645 d evice_t *dev = (device_t *)arg;656 ddf_dev_t *dev = (ddf_dev_t *)arg; 646 657 647 658 // initialize device (get and process descriptors, get address, etc.) … … 657 668 } 658 669 659 static int usbkbd_add_device(d evice_t *dev)670 static int usbkbd_add_device(ddf_dev_t *dev) 660 671 { 661 672 /* For now, fail immediately. */ … … 679 690 680 691 /* 692 * Create default function. 693 */ 694 // FIXME - check for errors 695 ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard"); 696 assert(kbd_fun != NULL); 697 kbd_fun->ops = &keyboard_ops; 698 699 int rc = ddf_fun_bind(kbd_fun); 700 assert(rc == EOK); 701 rc = ddf_fun_add_to_class(kbd_fun, "keyboard"); 702 assert(rc == EOK); 703 704 /* 681 705 * Create new fibril for handling this keyboard 682 706 */ … … 688 712 fibril_add_ready(fid); 689 713 690 dev->ops = &keyboard_ops; 691 692 add_device_to_class(dev, "keyboard"); 714 //dev->ops = &keyboard_ops; 715 (void)keyboard_ops; 716 717 //add_device_to_class(dev, "keyboard"); 693 718 694 719 /* … … 710 735 { 711 736 usb_log_enable(USB_LOG_LEVEL_MAX, NAME); 712 return d river_main(&kbd_driver);737 return ddf_driver_main(&kbd_driver); 713 738 } 714 739 -
uspace/drv/usbhub/main.c
r4837092 r92574f4 31 31 */ 32 32 33 #include <d river.h>33 #include <ddf/driver.h> 34 34 #include <errno.h> 35 35 #include <async.h> 36 37 #include <usb/usbdrv.h>38 36 39 37 #include "usbhub.h" … … 64 62 int main(int argc, char *argv[]) 65 63 { 66 usb_ dprintf_enable(NAME, 0);64 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 67 65 68 66 fibril_mutex_initialize(&usb_hub_list_lock); … … 79 77 fibril_add_ready(fid); 80 78 81 return d river_main(&hub_driver);79 return ddf_driver_main(&hub_driver); 82 80 } 83 81 -
uspace/drv/usbhub/port_status.h
r4837092 r92574f4 35 35 #include <bool.h> 36 36 #include <sys/types.h> 37 #include <usb/ devreq.h>37 #include <usb/request.h> 38 38 #include "usbhub_private.h" 39 39 -
uspace/drv/usbhub/usbhub.c
r4837092 r92574f4 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> 44 46 … … 47 49 #include "port_status.h" 48 50 #include "usb/usb.h" 49 50 static usb_iface_t hub_usb_iface = { 51 .get_hc_handle = usb_drv_find_hc 51 #include "usb/pipes.h" 52 #include "usb/classes/classes.h" 53 54 static ddf_dev_ops_t hub_device_ops = { 55 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl 52 56 }; 53 57 54 static device_ops_t hub_device_ops = { 55 .interfaces[USB_DEV_IFACE] = &hub_usb_iface 58 /** Hub status-change endpoint description */ 59 static usb_endpoint_description_t status_change_endpoint_description = { 60 .transfer_type = USB_TRANSFER_INTERRUPT, 61 .direction = USB_DIRECTION_IN, 62 .interface_class = USB_CLASS_HUB, 63 .flags = 0 56 64 }; 65 57 66 58 67 //********************************************* … … 62 71 //********************************************* 63 72 64 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) { 73 /** 74 * Initialize connnections to host controller, device, and device 75 * control endpoint 76 * @param hub 77 * @param device 78 * @return 79 */ 80 static int usb_hub_init_communication(usb_hub_info_t * hub){ 81 usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle); 82 int opResult; 83 opResult = usb_device_connection_initialize_from_device( 84 &hub->device_connection, 85 hub->device); 86 if(opResult != EOK){ 87 dprintf(USB_LOG_LEVEL_ERROR, 88 "could not initialize connection to hc, errno %d",opResult); 89 return opResult; 90 } 91 usb_log_debug("Initializing USB wire abstraction.\n"); 92 opResult = usb_hc_connection_initialize_from_device(&hub->connection, 93 hub->device); 94 if(opResult != EOK){ 95 dprintf(USB_LOG_LEVEL_ERROR, 96 "could not initialize connection to device, errno %d",opResult); 97 return opResult; 98 } 99 usb_log_debug("Initializing default control pipe.\n"); 100 opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control, 101 &hub->device_connection); 102 if(opResult != EOK){ 103 dprintf(USB_LOG_LEVEL_ERROR, 104 "could not initialize connection to device endpoint, errno %d",opResult); 105 } 106 return opResult; 107 } 108 109 /** 110 * When entering this function, hub->endpoints.control should be active. 111 * @param hub 112 * @return 113 */ 114 static int usb_hub_process_configuration_descriptors( 115 usb_hub_info_t * hub){ 116 if(hub==NULL) { 117 return EINVAL; 118 } 119 int opResult; 120 121 //device descriptor 122 usb_standard_device_descriptor_t std_descriptor; 123 opResult = usb_request_get_device_descriptor(&hub->endpoints.control, 124 &std_descriptor); 125 if(opResult!=EOK){ 126 dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult); 127 return opResult; 128 } 129 dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations", 130 std_descriptor.configuration_count); 131 if(std_descriptor.configuration_count<1){ 132 dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE"); 133 //shouldn`t I return? 134 } 135 136 //configuration descriptor 137 /// \TODO check other configurations 138 usb_standard_configuration_descriptor_t config_descriptor; 139 opResult = usb_request_get_bare_configuration_descriptor( 140 &hub->endpoints.control, 0, 141 &config_descriptor); 142 if(opResult!=EOK){ 143 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult); 144 return opResult; 145 } 146 //set configuration 147 opResult = usb_request_set_configuration(&hub->endpoints.control, 148 config_descriptor.configuration_number); 149 150 if (opResult != EOK) { 151 dprintf(USB_LOG_LEVEL_ERROR, 152 "something went wrong when setting hub`s configuration, %d", 153 opResult); 154 return opResult; 155 } 156 dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d", 157 config_descriptor.configuration_number); 158 159 //full configuration descriptor 160 size_t transferred = 0; 161 uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length); 162 if (descriptors == NULL) { 163 dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory"); 164 return ENOMEM; 165 } 166 opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control, 167 0, descriptors, 168 config_descriptor.total_length, &transferred); 169 if(opResult!=EOK){ 170 free(descriptors); 171 dprintf(USB_LOG_LEVEL_ERROR, 172 "could not get full configuration descriptor, %d",opResult); 173 return opResult; 174 } 175 if (transferred != config_descriptor.total_length) { 176 dprintf(USB_LOG_LEVEL_ERROR, 177 "received incorrect full configuration descriptor"); 178 return ELIMIT; 179 } 180 181 /** 182 * Initialize the interrupt in endpoint. 183 * \TODO this code should be checked... 184 */ 185 usb_endpoint_mapping_t endpoint_mapping[1] = { 186 { 187 .pipe = &hub->endpoints.status_change, 188 .description = &status_change_endpoint_description, 189 .interface_no = 190 usb_device_get_assigned_interface(hub->device) 191 } 192 }; 193 opResult = usb_endpoint_pipe_initialize_from_configuration( 194 endpoint_mapping, 1, 195 descriptors, config_descriptor.total_length, 196 &hub->device_connection); 197 if (opResult != EOK) { 198 dprintf(USB_LOG_LEVEL_ERROR, 199 "Failed to initialize status change pipe: %s", 200 str_error(opResult)); 201 return opResult; 202 } 203 if (!endpoint_mapping[0].present) { 204 dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \ 205 "cannot understand what is happenning"); 206 return EREFUSED; 207 } 208 209 free(descriptors); 210 return EOK; 211 212 213 // Initialize the interrupt(=status change) endpoint. 214 /*usb_endpoint_pipe_initialize( 215 &result->endpoints->status_change, 216 &result->device_connection, );USB_TRANSFER_INTERRUPT 217 USB_DIRECTION_IN*/ 218 219 } 220 221 222 /** 223 * Create hub representation from device information. 224 * @param device 225 * @return pointer to created structure or NULL in case of error 226 */ 227 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) { 65 228 usb_hub_info_t* result = usb_new(usb_hub_info_t); 229 result->device = device; 230 int opResult; 231 opResult = usb_hub_init_communication(result); 232 if(opResult != EOK){ 233 free(result); 234 return NULL; 235 } 236 66 237 //result->device = device; 67 238 result->port_count = -1; 68 /// \TODO is this correct? is the device stored?69 239 result->device = device; 70 240 71 72 //printf("[usb_hub] phone to hc = %d\n", hc); 73 if (hc < 0) { 74 return result; 75 } 76 //get some hub info 77 usb_address_t addr = usb_drv_get_my_address(hc, device); 78 dprintf(1, "address of newly created hub = %d", addr); 79 /*if(addr<0){ 80 //return result; 81 82 }*/ 83 84 result->usb_device = usb_new(usb_hcd_attached_device_info_t); 85 result->usb_device->address = addr; 241 //result->usb_device = usb_new(usb_hcd_attached_device_info_t); 242 size_t received_size; 86 243 87 244 // get hub descriptor 88 89 //printf("[usb_hub] creating serialized descriptor\n"); 245 dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton"); 90 246 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 91 247 usb_hub_descriptor_t * descriptor; 92 size_t received_size; 93 int opResult; 94 //printf("[usb_hub] starting control transaction\n"); 95 96 opResult = usb_drv_req_get_descriptor(hc, addr, 248 dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction"); 249 usb_endpoint_pipe_start_session(&result->endpoints.control); 250 opResult = usb_request_get_descriptor(&result->endpoints.control, 97 251 USB_REQUEST_TYPE_CLASS, 98 252 USB_DESCTYPE_HUB, 0, 0, serialized_descriptor, 99 253 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 100 101 if (opResult != EOK) { 102 dprintf(1, "failed when receiving hub descriptor, badcode = %d",opResult); 254 usb_endpoint_pipe_end_session(&result->endpoints.control); 255 256 if (opResult != EOK) { 257 dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult); 103 258 free(serialized_descriptor); 104 259 return result; 105 260 } 106 //printf("[usb_hub] deserializing descriptor\n");261 dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor"); 107 262 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor); 108 263 if(descriptor==NULL){ 109 dprintf( 1, "could not deserialize descriptor ");264 dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor "); 110 265 result->port_count = 1;///\TODO this code is only for debug!!! 111 266 return result; 112 267 } 113 //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count); 268 269 270 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 114 271 result->port_count = descriptor->ports_count; 115 result->attached_devs = (usb_h ub_attached_device_t*)116 malloc((result->port_count+1) * sizeof(usb_h ub_attached_device_t));272 result->attached_devs = (usb_hc_attached_device_t*) 273 malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t)); 117 274 int i; 118 275 for(i=0;i<result->port_count+1;++i){ 119 result->attached_devs[i]. devman_handle=0;276 result->attached_devs[i].handle=0; 120 277 result->attached_devs[i].address=0; 121 278 } 122 //printf("[usb_hub] freeing data\n");279 dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data"); 123 280 free(serialized_descriptor); 124 281 free(descriptor->devices_removable); … … 127 284 //finish 128 285 129 dprintf( 1, "hub info created");286 dprintf(USB_LOG_LEVEL_INFO, "hub info created"); 130 287 131 288 return result; 132 289 } 133 290 134 int usb_add_hub_device(device_t *dev) { 135 dprintf(1, "add_hub_device(handle=%d)", (int) dev->handle); 136 dprintf(1, "hub device"); 137 138 /* 139 * We are some (probably deeply nested) hub. 140 * Thus, assign our own operations and explore already 141 * connected devices. 142 */ 143 dev->ops = &hub_device_ops; 144 145 //create the hub structure 146 //get hc connection 147 int hc = usb_drv_hc_connect_auto(dev, 0); 148 if (hc < 0) { 149 return hc; 150 } 151 152 usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc); 291 /** 292 * Create hub representation and add it into hub list 293 * @param dev 294 * @return 295 */ 296 int usb_add_hub_device(ddf_dev_t *dev) { 297 dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle); 298 299 //dev->ops = &hub_device_ops; 300 (void) hub_device_ops; 301 302 usb_hub_info_t * hub_info = usb_create_hub_info(dev); 303 304 int opResult; 305 306 //perform final configurations 307 usb_endpoint_pipe_start_session(&hub_info->endpoints.control); 308 // process descriptors 309 opResult = usb_hub_process_configuration_descriptors(hub_info); 310 if(opResult != EOK){ 311 dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d", 312 opResult); 313 return opResult; 314 } 315 //power ports 316 usb_device_request_setup_packet_t request; 153 317 int port; 154 int opResult;155 usb_target_t target;156 target.address = hub_info->usb_device->address;157 target.endpoint = 0;158 159 //get configuration descriptor160 // this is not fully correct - there are more configurations161 // and all should be checked162 usb_standard_device_descriptor_t std_descriptor;163 opResult = usb_drv_req_get_device_descriptor(hc, target.address,164 &std_descriptor);165 if(opResult!=EOK){166 dprintf(1, "could not get device descriptor, %d",opResult);167 return opResult;168 }169 dprintf(1, "hub has %d configurations",std_descriptor.configuration_count);170 if(std_descriptor.configuration_count<1){171 dprintf(1, "THERE ARE NO CONFIGURATIONS AVAILABLE");172 //shouldn`t I return?173 }174 /// \TODO check other configurations175 usb_standard_configuration_descriptor_t config_descriptor;176 opResult = usb_drv_req_get_bare_configuration_descriptor(hc,177 target.address, 0,178 &config_descriptor);179 if(opResult!=EOK){180 dprintf(1, "could not get configuration descriptor, %d",opResult);181 return opResult;182 }183 //set configuration184 opResult = usb_drv_req_set_configuration(hc, target.address,185 config_descriptor.configuration_number);186 187 if (opResult != EOK) {188 dprintf(1, "something went wrong when setting hub`s configuration, %d", opResult);189 }190 191 usb_device_request_setup_packet_t request;192 318 for (port = 1; port < hub_info->port_count+1; ++port) { 193 319 usb_hub_set_power_port_request(&request, port); 194 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 195 dprintf(1, "powering port %d",port); 320 opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control, 321 &request,sizeof(usb_device_request_setup_packet_t), NULL, 0); 322 dprintf(USB_LOG_LEVEL_INFO, "powering port %d",port); 196 323 if (opResult != EOK) { 197 dprintf( 1, "something went wrong when setting hub`s %dth port", port);324 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port); 198 325 } 199 326 } 200 327 //ports powered, hub seems to be enabled 201 202 ipc_hangup(hc); 328 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 203 329 204 330 //add the hub to list … … 207 333 fibril_mutex_unlock(&usb_hub_list_lock); 208 334 209 dprintf( 1, "hub info added to list");335 dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list"); 210 336 //(void)hub_info; 211 337 usb_hub_check_hub_changes(); 212 213 338 214 215 dprintf(1, "hub dev added");216 dprintf( 1, "\taddress %d, has %d ports ",217 hub_info->usb_device->address,339 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); 340 //address is lost... 341 dprintf(USB_LOG_LEVEL_DEBUG, "\taddress %d, has %d ports ", 342 //hub_info->endpoints.control., 218 343 hub_info->port_count); 219 dprintf(1, "\tused configuration %d",config_descriptor.configuration_number);220 344 221 345 return EOK; … … 231 355 232 356 /** 233 * Convenience function for releasing default address and writing debug info234 * (these few lines are used too often to be written again and again).235 * @param hc236 * @return237 */238 inline static int usb_hub_release_default_address(int hc){239 int opResult;240 dprintf(1, "releasing default address");241 opResult = usb_drv_release_default_address(hc);242 if (opResult != EOK) {243 dprintf(1, "failed to release default address");244 }245 return opResult;246 }247 248 /**249 357 * Reset the port with new device and reserve the default address. 250 358 * @param hc … … 252 360 * @param target 253 361 */ 254 static void usb_hub_init_add_device( int hc, uint16_t port, usb_target_t target) {362 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) { 255 363 usb_device_request_setup_packet_t request; 256 364 int opResult; 257 dprintf(1, "some connection changed"); 365 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 366 assert(hub->endpoints.control.hc_phone); 258 367 //get default address 259 opResult = usb_drv_reserve_default_address(hc); 260 if (opResult != EOK) { 261 dprintf(1, "cannot assign default address, it is probably used"); 368 //opResult = usb_drv_reserve_default_address(hc); 369 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW); 370 371 if (opResult != EOK) { 372 dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used"); 262 373 return; 263 374 } 264 375 //reset port 265 376 usb_hub_set_reset_port_request(&request, port); 266 opResult = usb_ drv_sync_control_write(267 hc, target,268 &request, 377 opResult = usb_endpoint_pipe_control_write( 378 &hub->endpoints.control, 379 &request,sizeof(usb_device_request_setup_packet_t), 269 380 NULL, 0 270 381 ); 271 382 if (opResult != EOK) { 272 dprintf(1, "something went wrong when reseting a port"); 273 usb_hub_release_default_address(hc); 383 dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port"); 384 //usb_hub_release_default_address(hc); 385 usb_hc_release_default_address(&hub->connection); 274 386 } 275 387 } … … 282 394 */ 283 395 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 284 int hc, uint16_t port, usb_target_t target) {396 uint16_t port) { 285 397 286 398 int opResult; 287 dprintf( 1, "finalizing add device");288 opResult = usb_hub_clear_port_feature( hc, target.address,399 dprintf(USB_LOG_LEVEL_INFO, "finalizing add device"); 400 opResult = usb_hub_clear_port_feature(&hub->endpoints.control, 289 401 port, USB_HUB_FEATURE_C_PORT_RESET); 290 if (opResult != EOK) { 291 dprintf(1, "failed to clear port reset feature"); 292 usb_hub_release_default_address(hc); 293 return; 294 } 295 296 /* Request address at from host controller. */ 297 usb_address_t new_device_address = usb_drv_request_address(hc); 402 403 if (opResult != EOK) { 404 dprintf(USB_LOG_LEVEL_ERROR, "failed to clear port reset feature"); 405 usb_hc_release_default_address(&hub->connection); 406 return; 407 } 408 //create connection to device 409 usb_endpoint_pipe_t new_device_pipe; 410 usb_device_connection_t new_device_connection; 411 usb_device_connection_initialize_on_default_address( 412 &new_device_connection, 413 &hub->connection 414 ); 415 usb_endpoint_pipe_initialize_default_control( 416 &new_device_pipe, 417 &new_device_connection); 418 /// \TODO get highspeed info 419 420 421 422 423 424 /* Request address from host controller. */ 425 usb_address_t new_device_address = usb_hc_request_address( 426 &hub->connection, 427 USB_SPEED_LOW/// \TODO fullspeed?? 428 ); 298 429 if (new_device_address < 0) { 299 dprintf( 1, "failed to get free USB address");430 dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address"); 300 431 opResult = new_device_address; 301 usb_hub_release_default_address(hc); 302 return; 303 } 304 dprintf(1, "setting new address"); 305 opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 306 new_device_address); 307 308 if (opResult != EOK) { 309 dprintf(1, "could not set address for new device"); 310 usb_hub_release_default_address(hc); 311 return; 312 } 313 314 315 opResult = usb_hub_release_default_address(hc); 432 usb_hc_release_default_address(&hub->connection); 433 return; 434 } 435 dprintf(USB_LOG_LEVEL_INFO, "setting new address %d",new_device_address); 436 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 437 // new_device_address); 438 opResult = usb_request_set_address(&new_device_pipe,new_device_address); 439 440 if (opResult != EOK) { 441 dprintf(USB_LOG_LEVEL_ERROR, "could not set address for new device"); 442 usb_hc_release_default_address(&hub->connection); 443 return; 444 } 445 446 447 //opResult = usb_hub_release_default_address(hc); 448 opResult = usb_hc_release_default_address(&hub->connection); 316 449 if(opResult!=EOK){ 317 450 return; … … 319 452 320 453 devman_handle_t child_handle; 321 opResult = usb_drv_register_child_in_devman(hc, hub->device, 322 new_device_address, &child_handle); 323 if (opResult != EOK) { 324 dprintf(1, "could not start driver for new device"); 325 return; 326 } 327 hub->attached_devs[port].devman_handle = child_handle; 454 //?? 455 opResult = usb_device_register_child_in_devman(new_device_address, 456 hub->connection.hc_handle, hub->device, &child_handle, 457 NULL, NULL, NULL); 458 459 if (opResult != EOK) { 460 dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device"); 461 return; 462 } 463 hub->attached_devs[port].handle = child_handle; 328 464 hub->attached_devs[port].address = new_device_address; 329 465 330 opResult = usb_drv_bind_address(hc, new_device_address, child_handle); 331 if (opResult != EOK) { 332 dprintf(1, "could not assign address of device in hcd"); 333 return; 334 } 335 dprintf(1, "new device address %d, handle %zu", 466 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle); 467 opResult = usb_hc_register_device( 468 &hub->connection, 469 &hub->attached_devs[port]); 470 if (opResult != EOK) { 471 dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd"); 472 return; 473 } 474 dprintf(USB_LOG_LEVEL_INFO, "new device address %d, handle %zu", 336 475 new_device_address, child_handle); 337 476 … … 345 484 */ 346 485 static void usb_hub_removed_device( 347 usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {486 usb_hub_info_t * hub,uint16_t port) { 348 487 //usb_device_request_setup_packet_t request; 349 488 int opResult; … … 352 491 * devide manager 353 492 */ 354 355 hub->attached_devs[port].devman_handle=0; 493 356 494 //close address 357 495 if(hub->attached_devs[port].address!=0){ 358 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 496 //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 497 opResult = usb_hc_unregister_device( 498 &hub->connection, hub->attached_devs[port].address); 359 499 if(opResult != EOK) { 360 dprintf( 1, "could not release address of " \500 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \ 361 501 "removed device: %d", opResult); 362 502 } 363 503 hub->attached_devs[port].address = 0; 504 hub->attached_devs[port].handle = 0; 364 505 }else{ 365 dprintf( 1, "this is strange, disconnected device had no address");506 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address"); 366 507 //device was disconnected before it`s port was reset - return default address 367 usb_drv_release_default_address(hc); 508 //usb_drv_release_default_address(hc); 509 usb_hc_release_default_address(&hub->connection); 368 510 } 369 511 } … … 375 517 * @param target 376 518 */ 377 static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,378 uint16_t port , usb_address_t address) {379 dprintf( 1, "interrupt at port %d", port);519 static void usb_hub_process_interrupt(usb_hub_info_t * hub, 520 uint16_t port) { 521 dprintf(USB_LOG_LEVEL_DEBUG, "interrupt at port %d", port); 380 522 //determine type of change 523 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 524 int opResult = usb_endpoint_pipe_start_session(pipe); 525 526 if(opResult != EOK){ 527 dprintf(USB_LOG_LEVEL_ERROR, "cannot open pipe %d", opResult); 528 } 529 530 /* 381 531 usb_target_t target; 382 532 target.address=address; 383 533 target.endpoint=0; 534 */ 535 384 536 usb_port_status_t status; 385 537 size_t rcvd_size; 386 538 usb_device_request_setup_packet_t request; 387 int opResult;539 //int opResult; 388 540 usb_hub_set_port_status_request(&request, port); 389 541 //endpoint 0 390 542 391 opResult = usb_ drv_sync_control_read(392 hc, target,393 &request, 543 opResult = usb_endpoint_pipe_control_read( 544 pipe, 545 &request, sizeof(usb_device_request_setup_packet_t), 394 546 &status, 4, &rcvd_size 395 547 ); 396 548 if (opResult != EOK) { 397 dprintf( 1, "ERROR: could not get port status");549 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: could not get port status"); 398 550 return; 399 551 } 400 552 if (rcvd_size != sizeof (usb_port_status_t)) { 401 dprintf( 1, "ERROR: received status has incorrect size");553 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: received status has incorrect size"); 402 554 return; 403 555 } 404 556 //something connected/disconnected 405 557 if (usb_port_connect_change(&status)) { 406 opResult = usb_hub_clear_port_feature( hc, target.address,558 opResult = usb_hub_clear_port_feature(pipe, 407 559 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 408 560 // TODO: check opResult 409 561 if (usb_port_dev_connected(&status)) { 410 dprintf( 1, "some connection changed");411 usb_hub_init_add_device(h c, port, target);562 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 563 usb_hub_init_add_device(hub, port); 412 564 } else { 413 usb_hub_removed_device(hub, hc, port, target);565 usb_hub_removed_device(hub, port); 414 566 } 415 567 } 416 568 //port reset 417 569 if (usb_port_reset_completed(&status)) { 418 dprintf( 1, "port reset complete");570 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 419 571 if (usb_port_enabled(&status)) { 420 usb_hub_finalize_add_device(hub, hc, port, target);572 usb_hub_finalize_add_device(hub, port); 421 573 } else { 422 dprintf( 1, "ERROR: port reset, but port still not enabled");574 dprintf(USB_LOG_LEVEL_WARNING, "ERROR: port reset, but port still not enabled"); 423 575 } 424 576 } … … 429 581 usb_port_set_dev_connected(&status, false); 430 582 if (status>>16) { 431 dprintf( 1, "there was some unsupported change on port %d: %X",port,status);583 dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status); 432 584 433 585 } 434 586 /// \TODO handle other changes 435 587 /// \TODO debug log for various situations 588 usb_endpoint_pipe_end_session(pipe); 589 436 590 437 591 } … … 451 605 fibril_mutex_unlock(&usb_hub_list_lock); 452 606 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data); 607 int opResult; 608 609 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); 610 if(opResult != EOK){ 611 continue; 612 } 453 613 /* 454 614 * Check status change pipe of this hub. 455 615 */ 456 616 /* 457 617 usb_target_t target; 458 target.address = hub_info-> usb_device->address;618 target.address = hub_info->address; 459 619 target.endpoint = 1;/// \TODO get from endpoint descriptor 460 dprintf( 1, "checking changes for hub at addr %d",620 dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d", 461 621 target.address); 462 622 */ 463 623 size_t port_count = hub_info->port_count; 464 624 465 625 /* 466 626 * Connect to respective HC. 467 * /627 * 468 628 int hc = usb_drv_hc_connect_auto(hub_info->device, 0); 469 629 if (hc < 0) { 470 630 continue; 471 } 631 }*/ 472 632 473 633 /// FIXME: count properly … … 476 636 void *change_bitmap = malloc(byte_length); 477 637 size_t actual_size; 478 usb_handle_t handle;638 //usb_handle_t handle; 479 639 480 640 /* 481 641 * Send the request. 482 642 */ 483 int opResult = usb_drv_async_interrupt_in(hc, target, 484 change_bitmap, byte_length, &actual_size, 485 &handle); 486 487 usb_drv_async_wait_for(handle); 643 opResult = usb_endpoint_pipe_read( 644 &hub_info->endpoints.status_change, 645 change_bitmap, byte_length, &actual_size 646 ); 647 648 //usb_drv_async_wait_for(handle); 488 649 489 650 if (opResult != EOK) { 490 651 free(change_bitmap); 491 dprintf( 1, "something went wrong while getting status of hub");652 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 492 653 continue; 493 654 } … … 498 659 if (interrupt) { 499 660 usb_hub_process_interrupt( 500 hub_info, hc, port, hub_info->usb_device->address);661 hub_info, port); 501 662 } 502 663 } 664 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 503 665 free(change_bitmap); 504 505 ipc_hangup(hc); 666 667 668 //async_hangup(hc); 506 669 fibril_mutex_lock(&usb_hub_list_lock); 507 670 } -
uspace/drv/usbhub/usbhub.h
r4837092 r92574f4 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 … … 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 /** -
uspace/drv/usbhub/usbhub_private.h
r4837092 r92574f4 42 42 #include <adt/list.h> 43 43 #include <bool.h> 44 #include <d river.h>44 #include <ddf/driver.h> 45 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 /** … … 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 80 /** List of hubs maanged by this driver */ … … 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 /** … … 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 /** … … 146 147 * @return Operation result 147 148 */ 148 static inline int usb_hub_clear_port_feature( int hc, usb_address_t address,149 static inline int usb_hub_clear_port_feature(usb_endpoint_pipe_t *pipe, 149 150 int port_index, 150 151 usb_hub_class_feature_t feature) { 151 usb_target_t target = { 152 .address = address, 153 .endpoint = 0 154 }; 152 155 153 usb_device_request_setup_packet_t clear_request = { 156 154 .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE, … … 160 158 }; 161 159 clear_request.value = feature; 162 return usb_ drv_psync_control_write(hc, target, &clear_request,160 return usb_endpoint_pipe_control_write(pipe, &clear_request, 163 161 sizeof(clear_request), NULL, 0); 164 162 } -
uspace/drv/usbhub/utils.c
r4837092 r92574f4 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
r4837092 r92574f4 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 pci.c \ 37 transfers.c 38 usbmid.c 38 39 39 40 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/usbmid/main.c
r4837092 r92574f4 1 1 /* 2 * Copyright (c) 201 0Vojtech Horky2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 #include <usb/hcdhubd.h> 29 #include <usb_iface.h> 30 #include <usb/debug.h> 28 29 /** @addtogroup drvusbmid 30 * @{ 31 */ 32 /** 33 * @file 34 * Main routines of USB multi interface device driver. 35 */ 31 36 #include <errno.h> 32 37 #include <str_error.h> 33 #include <driver.h> 34 #include "uhci.h" 38 #include <usb/debug.h> 39 #include <usb/classes/classes.h> 40 #include <usb/request.h> 41 #include <usb/descriptor.h> 42 #include <usb/pipes.h> 35 43 36 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 44 #include "usbmid.h" 45 46 static int usbmid_add_device(ddf_dev_t *gen_dev) 37 47 { 38 /* This shall be called only for the UHCI itself. */ 39 assert(dev->parent == NULL); 48 usbmid_device_t *dev = usbmid_device_create(gen_dev); 49 if (dev == NULL) { 50 return ENOMEM; 51 } 40 52 41 *handle = dev->handle; 53 usb_log_info("Taking care of new MID: addr %d (HC %zu)\n", 54 dev->wire.address, dev->wire.hc_handle); 55 56 int rc; 57 58 rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe); 59 if (rc != EOK) { 60 usb_log_error("Failed to start session on control pipe: %s.\n", 61 str_error(rc)); 62 goto error_leave; 63 } 64 65 bool accept = usbmid_explore_device(dev); 66 67 rc = usb_endpoint_pipe_end_session(&dev->ctrl_pipe); 68 if (rc != EOK) { 69 usb_log_warning("Failed to end session on control pipe: %s.\n", 70 str_error(rc)); 71 } 72 73 if (!accept) { 74 rc = ENOTSUP; 75 goto error_leave; 76 } 77 78 gen_dev->driver_data = dev; 79 42 80 return EOK; 81 82 83 error_leave: 84 free(dev); 85 return rc; 43 86 } 44 87 45 static usb_iface_t hc_usb_iface= {46 . get_hc_handle = usb_iface_get_hc_handle88 static driver_ops_t mid_driver_ops = { 89 .add_device = usbmid_add_device, 47 90 }; 48 91 49 static device_ops_t uhci_ops = { 50 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 51 .interfaces[USBHC_DEV_IFACE] = &uhci_iface 52 }; 53 54 static int uhci_add_device(device_t *device) 55 { 56 usb_dprintf(NAME, 1, "uhci_add_device() called\n"); 57 device->ops = &uhci_ops; 58 59 uintptr_t io_reg_base; 60 size_t io_reg_size; 61 int irq; 62 63 int rc = pci_get_my_registers(device, 64 &io_reg_base, &io_reg_size, &irq); 65 66 if (rc != EOK) { 67 fprintf(stderr, 68 NAME ": failed to get I/O registers addresses: %s.\n", 69 str_error(rc)); 70 return rc; 71 } 72 73 usb_dprintf(NAME, 2, "I/O regs at 0x%X (size %zu), IRQ %d.\n", 74 io_reg_base, io_reg_size, irq); 75 76 /* 77 * We need to announce the presence of our root hub. 78 */ 79 usb_dprintf(NAME, 2, "adding root hub\n"); 80 usb_hcd_add_root_hub(device); 81 82 return EOK; 83 } 84 85 static driver_ops_t uhci_driver_ops = { 86 .add_device = uhci_add_device, 87 }; 88 89 static driver_t uhci_driver = { 92 static driver_t mid_driver = { 90 93 .name = NAME, 91 .driver_ops = & uhci_driver_ops94 .driver_ops = &mid_driver_ops 92 95 }; 93 96 94 97 int main(int argc, char *argv[]) 95 98 { 96 /* 97 * Do some global initializations. 98 */ 99 sleep(5); 100 usb_dprintf_enable(NAME, 5); 99 printf(NAME ": USB multi interface device driver.\n"); 101 100 102 return driver_main(&uhci_driver); 101 usb_log_enable(USB_LOG_LEVEL_INFO, NAME); 102 return ddf_driver_main(&mid_driver); 103 103 } 104 105 /** 106 * @} 107 */ -
uspace/drv/vhc/conn.h
r4837092 r92574f4 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(d evice_t *, ipc_callid_t, ipc_call_t *);53 void on_client_close(d evice_t *);53 void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 54 void on_client_close(ddf_fun_t *); 54 55 55 56 -
uspace/drv/vhc/conndev.c
r4837092 r92574f4 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 { … … 90 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]; … … 105 105 } 106 106 107 ipc_answer_0(icallid, EINVAL);107 async_answer_0(icallid, EINVAL); 108 108 } 109 109 … … 112 112 * @param d Device the client was connected to. 113 113 */ 114 void on_client_close(d evice_t *d)114 void on_client_close(ddf_fun_t *fun) 115 115 { 116 116 /* -
uspace/drv/vhc/connhost.c
r4837092 r92574f4 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" … … 47 48 usbhc_iface_transfer_out_callback_t out_callback; 48 49 usbhc_iface_transfer_in_callback_t in_callback; 49 d evice_t *dev;50 ddf_fun_t *fun; 50 51 size_t reported_size; 51 52 void *arg; … … 57 58 usbhc_iface_transfer_out_callback_t out_callback; 58 59 usbhc_iface_transfer_in_callback_t in_callback; 59 d evice_t *dev;60 ddf_fun_t *fun; 60 61 void *arg; 61 62 void *data_buffer; … … 64 65 65 66 static void universal_callback(void *buffer, size_t size, 66 usb_transaction_outcome_t outcome, void *arg)67 int outcome, void *arg) 67 68 { 68 69 transfer_info_t *transfer = (transfer_info_t *) arg; … … 74 75 switch (transfer->direction) { 75 76 case USB_DIRECTION_IN: 76 transfer->in_callback(transfer-> dev,77 transfer->in_callback(transfer->fun, 77 78 outcome, size, 78 79 transfer->arg); 79 80 break; 80 81 case USB_DIRECTION_OUT: 81 transfer->out_callback(transfer-> dev,82 transfer->out_callback(transfer->fun, 82 83 outcome, 83 84 transfer->arg); … … 91 92 } 92 93 93 static transfer_info_t *create_transfer_info(d evice_t *dev,94 static transfer_info_t *create_transfer_info(ddf_fun_t *fun, 94 95 usb_direction_t direction, void *arg) 95 96 { … … 100 101 transfer->out_callback = NULL; 101 102 transfer->arg = arg; 102 transfer-> dev = dev;103 transfer->fun = fun; 103 104 transfer->reported_size = (size_t) -1; 104 105 … … 107 108 108 109 static void control_abort_prematurely(control_transfer_info_t *transfer, 109 size_t size, usb_transaction_outcome_t outcome)110 size_t size, int outcome) 110 111 { 111 112 switch (transfer->direction) { 112 113 case USB_DIRECTION_IN: 113 transfer->in_callback(transfer-> dev,114 transfer->in_callback(transfer->fun, 114 115 outcome, size, 115 116 transfer->arg); 116 117 break; 117 118 case USB_DIRECTION_OUT: 118 transfer->out_callback(transfer-> dev,119 transfer->out_callback(transfer->fun, 119 120 outcome, 120 121 transfer->arg); … … 127 128 128 129 static void control_callback_two(void *buffer, size_t size, 129 usb_transaction_outcome_t outcome, void *arg)130 int outcome, void *arg) 130 131 { 131 132 control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg; 132 133 133 if (outcome != USB_OUTCOME_OK) {134 if (outcome != EOK) { 134 135 control_abort_prematurely(ctrl_transfer, outcome, size); 135 136 free(ctrl_transfer); … … 137 138 } 138 139 139 transfer_info_t *transfer = create_transfer_info(ctrl_transfer-> dev,140 transfer_info_t *transfer = create_transfer_info(ctrl_transfer->fun, 140 141 ctrl_transfer->direction, ctrl_transfer->arg); 141 142 transfer->out_callback = ctrl_transfer->out_callback; … … 165 166 166 167 static void control_callback_one(void *buffer, size_t size, 167 usb_transaction_outcome_t outcome, void *arg)168 int outcome, void *arg) 168 169 { 169 170 control_transfer_info_t *transfer = (control_transfer_info_t *) arg; 170 171 171 if (outcome != USB_OUTCOME_OK) {172 if (outcome != EOK) { 172 173 control_abort_prematurely(transfer, outcome, size); 173 174 free(transfer); … … 194 195 } 195 196 196 static control_transfer_info_t *create_control_transfer_info(d evice_t *dev,197 static control_transfer_info_t *create_control_transfer_info(ddf_fun_t *fun, 197 198 usb_direction_t direction, usb_target_t target, 198 199 void *data_buffer, size_t data_buffer_size, … … 207 208 transfer->out_callback = NULL; 208 209 transfer->arg = arg; 209 transfer-> dev = dev;210 transfer->fun = fun; 210 211 transfer->data_buffer = data_buffer; 211 212 transfer->data_buffer_size = data_buffer_size; … … 214 215 } 215 216 216 static int enqueue_transfer_out(d evice_t *dev,217 static int enqueue_transfer_out(ddf_fun_t *fun, 217 218 usb_target_t target, usb_transfer_type_t transfer_type, 218 219 void *buffer, size_t size, … … 225 226 226 227 transfer_info_t *transfer 227 = create_transfer_info( dev, USB_DIRECTION_OUT, arg);228 = create_transfer_info(fun, USB_DIRECTION_OUT, arg); 228 229 transfer->out_callback = callback; 229 230 … … 234 235 } 235 236 236 static int enqueue_transfer_setup(device_t *dev, 237 usb_target_t target, usb_transfer_type_t transfer_type, 238 void *buffer, size_t size, 239 usbhc_iface_transfer_out_callback_t callback, void *arg) 240 { 241 usb_log_debug2("Transfer SETUP [%d.%d (%s); %zu].\n", 242 target.address, target.endpoint, 243 usb_str_transfer_type(transfer_type), 244 size); 245 246 transfer_info_t *transfer 247 = create_transfer_info(dev, USB_DIRECTION_OUT, arg); 248 transfer->out_callback = callback; 249 250 hc_add_transaction_to_device(true, target, transfer_type, buffer, size, 251 universal_callback, transfer); 252 253 return EOK; 254 } 255 256 static int enqueue_transfer_in(device_t *dev, 237 static int enqueue_transfer_in(ddf_fun_t *fun, 257 238 usb_target_t target, usb_transfer_type_t transfer_type, 258 239 void *buffer, size_t size, … … 265 246 266 247 transfer_info_t *transfer 267 = create_transfer_info( dev, USB_DIRECTION_IN, arg);248 = create_transfer_info(fun, USB_DIRECTION_IN, arg); 268 249 transfer->in_callback = callback; 269 250 … … 275 256 276 257 277 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, 278 260 void *data, size_t size, 279 261 usbhc_iface_transfer_out_callback_t callback, void *arg) 280 262 { 281 return enqueue_transfer_out( dev, target, USB_TRANSFER_INTERRUPT,263 return enqueue_transfer_out(fun, target, USB_TRANSFER_INTERRUPT, 282 264 data, size, 283 265 callback, arg); 284 266 } 285 267 286 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, 287 270 void *data, size_t size, 288 271 usbhc_iface_transfer_in_callback_t callback, void *arg) 289 272 { 290 return enqueue_transfer_in( dev, target, USB_TRANSFER_INTERRUPT,273 return enqueue_transfer_in(fun, target, USB_TRANSFER_INTERRUPT, 291 274 data, size, 292 275 callback, arg); 293 276 } 294 277 295 static int control_write_setup(device_t *dev, usb_target_t target, 296 void *data, size_t size, 297 usbhc_iface_transfer_out_callback_t callback, void *arg) 298 { 299 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL, 300 data, size, 301 callback, arg); 302 } 303 304 static int control_write_data(device_t *dev, usb_target_t target, 305 void *data, size_t size, 306 usbhc_iface_transfer_out_callback_t callback, void *arg) 307 { 308 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL, 309 data, size, 310 callback, arg); 311 } 312 313 static int control_write_status(device_t *dev, usb_target_t target, 314 usbhc_iface_transfer_in_callback_t callback, void *arg) 315 { 316 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL, 317 NULL, 0, 318 callback, arg); 319 } 320 321 static int control_write(device_t *dev, usb_target_t target, 278 static int control_write(ddf_fun_t *fun, usb_target_t target, 279 size_t max_packet_size, 322 280 void *setup_packet, size_t setup_packet_size, 323 281 void *data, size_t data_size, … … 325 283 { 326 284 control_transfer_info_t *transfer 327 = create_control_transfer_info( dev, USB_DIRECTION_OUT, target,285 = create_control_transfer_info(fun, USB_DIRECTION_OUT, target, 328 286 data, data_size, arg); 329 287 transfer->out_callback = callback; … … 336 294 } 337 295 338 static int control_read_setup(device_t *dev, usb_target_t target, 339 void *data, size_t size, 340 usbhc_iface_transfer_out_callback_t callback, void *arg) 341 { 342 return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL, 343 data, size, 344 callback, arg); 345 } 346 347 static int control_read_data(device_t *dev, usb_target_t target, 348 void *data, size_t size, 349 usbhc_iface_transfer_in_callback_t callback, void *arg) 350 { 351 return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL, 352 data, size, 353 callback, arg); 354 } 355 356 static int control_read_status(device_t *dev, usb_target_t target, 357 usbhc_iface_transfer_out_callback_t callback, void *arg) 358 { 359 return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL, 360 NULL, 0, 361 callback, arg); 362 } 363 364 static int control_read(device_t *dev, usb_target_t target, 296 static int control_read(ddf_fun_t *fun, usb_target_t target, 297 size_t max_packet_size, 365 298 void *setup_packet, size_t setup_packet_size, 366 299 void *data, size_t data_size, … … 368 301 { 369 302 control_transfer_info_t *transfer 370 = create_control_transfer_info( dev, USB_DIRECTION_IN, target,303 = create_control_transfer_info(fun, USB_DIRECTION_IN, target, 371 304 data, data_size, arg); 372 305 transfer->in_callback = callback; … … 381 314 static usb_address_keeping_t addresses; 382 315 383 384 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) 385 331 { 386 332 usb_address_keeping_reserve_default(&addresses); … … 388 334 } 389 335 390 static int release_default_address(d evice_t *dev)336 static int release_default_address(ddf_fun_t *fun) 391 337 { 392 338 usb_address_keeping_release_default(&addresses); … … 394 340 } 395 341 396 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) 397 344 { 398 345 usb_address_t addr = usb_address_keeping_request(&addresses); … … 405 352 } 406 353 407 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) 408 355 { 409 356 return usb_address_keeping_release(&addresses, address); 410 357 } 411 358 412 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, 413 360 devman_handle_t handle) 414 361 { … … 417 364 } 418 365 419 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, 420 380 usb_address_t *address) 421 381 { 422 usb_address_t addr = usb_address_keeping_find(&addresses, handle); 423 if (addr < 0) { 424 return addr; 425 } 426 427 *address = addr; 428 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); 429 386 } 430 387 … … 435 392 436 393 usbhc_iface_t vhc_iface = { 437 .tell_address = tell_address,438 439 394 .reserve_default_address = reserve_default_address, 440 395 .release_default_address = release_default_address, … … 446 401 .interrupt_in = interrupt_in, 447 402 448 .control_write_setup = control_write_setup,449 .control_write_data = control_write_data,450 .control_write_status = control_write_status,451 452 403 .control_write = control_write, 453 454 .control_read_setup = control_read_setup,455 .control_read_data = control_read_data,456 .control_read_status = control_read_status,457 458 404 .control_read = control_read 459 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 460 417 461 418 /** -
uspace/drv/vhc/devices.c
r4837092 r92574f4 34 34 */ 35 35 36 #include <ipc/ipc.h>37 36 #include <adt/list.h> 38 37 #include <bool.h> … … 113 112 * @param transaction Transaction to be sent over the bus. 114 113 */ 115 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *transaction)114 int virtdev_send_to_all(transaction_t *transaction) 116 115 { 117 116 /* For easier debugging. */ … … 127 126 assert(false && "unreachable branch in switch()"); 128 127 } 129 usb_transaction_outcome_t outcome = USB_OUTCOME_BABBLE;128 int outcome = EBADCHECKSUM; 130 129 131 130 link_t *pos; … … 186 185 */ 187 186 if (rc == EOK) { 188 outcome = USB_OUTCOME_OK;187 outcome = EOK; 189 188 } 190 189 } … … 222 221 break; 223 222 } 224 outcome = USB_OUTCOME_OK;223 outcome = EOK; 225 224 } 226 225 -
uspace/drv/vhc/devices.h
r4837092 r92574f4 54 54 virtdev_connection_t *virtdev_find(sysarg_t); 55 55 void virtdev_destroy_device(virtdev_connection_t *); 56 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *);56 int virtdev_send_to_all(transaction_t *); 57 57 58 58 #endif -
uspace/drv/vhc/hc.c
r4837092 r92574f4 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)91 int outcome) 93 92 { 94 93 usb_log_debug2("Transaction " TRANSACTION_FORMAT " done: %s.\n", 95 94 TRANSACTION_PRINTF(*transaction), 96 usb_str_transaction_outcome(outcome));95 str_error(outcome)); 97 96 98 97 transaction->callback(transaction->buffer, transaction->actual_len, … … 128 127 TRANSACTION_PRINTF(*transaction), ports); 129 128 130 usb_transaction_outcome_t outcome;129 int outcome; 131 130 outcome = virtdev_send_to_all(transaction); 132 131 -
uspace/drv/vhc/hc.h
r4837092 r92574f4 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. */ -
uspace/drv/vhc/hcd.c
r4837092 r92574f4 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, 71 58 .close = on_client_close, 72 59 .default_handler = default_connection_handler 73 60 }; 74 61 75 static int vhc_count = 0; 76 static int vhc_add_device(device_t *dev) 62 static int vhc_add_device(ddf_dev_t *dev) 77 63 { 64 static int vhc_count = 0; 65 int rc; 66 78 67 /* 79 68 * Currently, we know how to simulate only single HC. … … 83 72 } 84 73 85 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 } 86 83 87 dev->ops = &vhc_ops;84 hc->ops = &vhc_ops; 88 85 89 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"); 90 94 91 95 /* 92 96 * Initialize our hub and announce its presence. 93 97 */ 94 virtual_hub_device_init( dev);98 virtual_hub_device_init(hc); 95 99 96 usb_log_info("Virtual USB host controller ready ( id =%zu).\n",97 (size_t) dev->handle );100 usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n", 101 (size_t) dev->handle, (size_t) hc->handle); 98 102 99 103 return EOK; … … 116 120 * in devman output. 117 121 */ 118 sleep(5);122 //sleep(5); 119 123 120 usb_log_enable(USB_LOG_LEVEL_ INFO, NAME);124 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 121 125 122 126 printf(NAME ": virtual USB host controller driver.\n"); … … 135 139 * We are also a driver within devman framework. 136 140 */ 137 return d river_main(&vhc_driver);141 return ddf_driver_main(&vhc_driver); 138 142 } 139 143 -
uspace/drv/vhc/hub.c
r4837092 r92574f4 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); … … 70 76 } 71 77 78 static int pretend_port_rest(int unused, void *unused2) 79 { 80 return EOK; 81 } 82 72 83 /** Register root hub in devman. 73 84 * … … 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; 92 /* 93 * Wait until parent device is properly initialized. 94 */ 95 int phone; 82 96 do { 83 hc = usb_drv_hc_connect(hc_dev, hc_dev->handle,84 IPC_FLAG_BLOCKING);85 } while (hc < 0);97 phone = devman_device_connect(hc_dev->handle, 0); 98 } while (phone < 0); 99 async_hangup(phone); 86 100 87 usb_drv_reserve_default_address(hc);101 int rc; 88 102 89 usb_address_t hub_address = usb_drv_request_address(hc); 90 usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, hub_address); 103 usb_hc_connection_t hc_conn; 104 rc = usb_hc_connection_initialize(&hc_conn, hc_dev->handle); 105 assert(rc == EOK); 91 106 92 usb_drv_release_default_address(hc); 107 rc = usb_hc_connection_open(&hc_conn); 108 assert(rc == EOK); 93 109 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); 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)); 118 } 97 119 98 return EOK; 120 usb_hc_connection_close(&hc_conn); 121 122 usb_log_info("Created root hub function (handle %zu).\n", 123 (size_t) hub_dev->handle); 124 125 return 0; 99 126 } 100 127 -
uspace/drv/vhc/hub.h
r4837092 r92574f4 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
r4837092 r92574f4 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" -
uspace/drv/vhc/hub/virthub.c
r4837092 r92574f4 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"
Note:
See TracChangeset
for help on using the changeset viewer.
