Changeset eb522e8 in mainline for uspace/drv
- Timestamp:
- 2011-06-01T08:43:42Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8d6c1f1
- Parents:
- 9e2e715 (diff), e51a514 (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:
-
- 147 added
- 1 deleted
- 6 edited
- 7 moved
-
ehci-hcd/Makefile (added)
-
ehci-hcd/ehci-hcd.ma (added)
-
ehci-hcd/ehci.h (added)
-
ehci-hcd/hc_iface.c (added)
-
ehci-hcd/main.c (added)
-
ehci-hcd/pci.c (added)
-
ehci-hcd/pci.h (added)
-
isa/isa.c (modified) (21 diffs)
-
ns8250/cyclic_buffer.h (modified) (1 diff)
-
ns8250/ns8250.c (modified) (35 diffs)
-
ohci/Makefile (added)
-
ohci/batch.c (added)
-
ohci/batch.h (added)
-
ohci/endpoint_list.c (added)
-
ohci/endpoint_list.h (added)
-
ohci/hc.c (added)
-
ohci/hc.h (added)
-
ohci/hcd_endpoint.c (added)
-
ohci/hcd_endpoint.h (added)
-
ohci/hw_struct/completion_codes.h (added)
-
ohci/hw_struct/endpoint_descriptor.c (added)
-
ohci/hw_struct/endpoint_descriptor.h (added)
-
ohci/hw_struct/hcca.h (added)
-
ohci/hw_struct/iso_transfer_descriptor.h (added)
-
ohci/hw_struct/transfer_descriptor.c (added)
-
ohci/hw_struct/transfer_descriptor.h (added)
-
ohci/iface.c (added)
-
ohci/iface.h (added)
-
ohci/main.c (added)
-
ohci/ohci.c (added)
-
ohci/ohci.h (added)
-
ohci/ohci.ma (added)
-
ohci/ohci_regs.h (added)
-
ohci/pci.c (added)
-
ohci/pci.h (added)
-
ohci/root_hub.c (added)
-
ohci/root_hub.h (added)
-
ohci/utils/malloc32.h (moved) (moved from uspace/srv/net/il/ip/ip_module.c ) (2 diffs)
-
pciintel/pci.c (modified) (17 diffs)
-
pciintel/pci.h (modified) (3 diffs)
-
root/root.c (modified) (6 diffs)
-
rootia32/rootia32.ma (deleted)
-
rootpc/Makefile (moved) (moved from uspace/drv/rootia32/Makefile ) (1 diff)
-
rootpc/rootpc.c (moved) (moved from uspace/drv/rootia32/rootia32.c ) (7 diffs)
-
rootpc/rootpc.ma (added)
-
rootvirt/Makefile (added)
-
rootvirt/devices.def (added)
-
rootvirt/rootvirt.c (added)
-
rootvirt/rootvirt.ma (added)
-
test1/Makefile (added)
-
test1/char.c (moved) (moved from uspace/lib/packet/include/packet_local.h ) (2 diffs)
-
test1/test1.c (added)
-
test1/test1.h (added)
-
test1/test1.ma (added)
-
test2/Makefile (added)
-
test2/test2.c (added)
-
test2/test2.ma (added)
-
uhci-hcd/Makefile (added)
-
uhci-hcd/batch.c (added)
-
uhci-hcd/batch.h (added)
-
uhci-hcd/hc.c (added)
-
uhci-hcd/hc.h (added)
-
uhci-hcd/hw_struct/link_pointer.h (added)
-
uhci-hcd/hw_struct/queue_head.h (added)
-
uhci-hcd/hw_struct/transfer_descriptor.c (added)
-
uhci-hcd/hw_struct/transfer_descriptor.h (added)
-
uhci-hcd/iface.c (added)
-
uhci-hcd/iface.h (added)
-
uhci-hcd/main.c (added)
-
uhci-hcd/pci.c (added)
-
uhci-hcd/pci.h (added)
-
uhci-hcd/root_hub.c (added)
-
uhci-hcd/root_hub.h (added)
-
uhci-hcd/transfer_list.c (added)
-
uhci-hcd/transfer_list.h (moved) (moved from uspace/app/netstart/netstart.c ) (2 diffs)
-
uhci-hcd/uhci-hcd.ma (added)
-
uhci-hcd/uhci.c (added)
-
uhci-hcd/uhci.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/root_hub.c (added)
-
uhci-rhd/root_hub.h (added)
-
uhci-rhd/uhci-rhd.ma (added)
-
usbflbk/Makefile (added)
-
usbflbk/main.c (added)
-
usbflbk/usbflbk.ma (added)
-
usbhid/Makefile (added)
-
usbhid/generic/hiddev.c (added)
-
usbhid/generic/hiddev.h (added)
-
usbhid/kbd.h (added)
-
usbhid/kbd/conv.c (added)
-
usbhid/kbd/conv.h (added)
-
usbhid/kbd/kbddev.c (added)
-
usbhid/kbd/kbddev.h (added)
-
usbhid/kbd/kbdrepeat.c (added)
-
usbhid/kbd/kbdrepeat.h (added)
-
usbhid/kbd/layout.h (added)
-
usbhid/kbd/main.c (added)
-
usbhid/layout.h (added)
-
usbhid/main.c (added)
-
usbhid/mouse/mousedev.c (added)
-
usbhid/mouse/mousedev.h (added)
-
usbhid/multimedia/keymap.c (added)
-
usbhid/multimedia/keymap.h (added)
-
usbhid/multimedia/multimedia.c (added)
-
usbhid/multimedia/multimedia.h (added)
-
usbhid/subdrivers.c (moved) (moved from uspace/lib/net/include/netif_interface.h ) (2 diffs)
-
usbhid/subdrivers.h (added)
-
usbhid/usbhid.c (added)
-
usbhid/usbhid.h (added)
-
usbhid/usbhid.ma (added)
-
usbhub/Makefile (added)
-
usbhub/main.c (moved) (moved from uspace/srv/net/tl/icmp/icmp_module.c ) (2 diffs)
-
usbhub/port_status.h (added)
-
usbhub/ports.c (added)
-
usbhub/ports.h (added)
-
usbhub/usbhub.c (added)
-
usbhub/usbhub.h (added)
-
usbhub/usbhub.ma (added)
-
usbhub/usbhub_private.h (added)
-
usbhub/utils.c (added)
-
usbmast/Makefile (added)
-
usbmast/cmds.h (added)
-
usbmast/inquiry.c (added)
-
usbmast/main.c (added)
-
usbmast/mast.c (added)
-
usbmast/mast.h (added)
-
usbmast/scsi.h (added)
-
usbmast/usbmast.ma (added)
-
usbmid/Makefile (added)
-
usbmid/dump.c (added)
-
usbmid/explore.c (added)
-
usbmid/main.c (added)
-
usbmid/usbmid.c (added)
-
usbmid/usbmid.h (added)
-
usbmid/usbmid.ma (added)
-
usbmouse/Makefile (added)
-
usbmouse/init.c (added)
-
usbmouse/main.c (added)
-
usbmouse/mouse.c (added)
-
usbmouse/mouse.h (added)
-
usbmouse/usbmouse.ma (added)
-
vhc/Makefile (added)
-
vhc/conn.h (added)
-
vhc/conndev.c (added)
-
vhc/connhost.c (added)
-
vhc/devconn.c (added)
-
vhc/hub.c (added)
-
vhc/hub.h (added)
-
vhc/hub/hub.c (added)
-
vhc/hub/hub.h (added)
-
vhc/hub/virthub.c (added)
-
vhc/hub/virthub.h (added)
-
vhc/hub/virthubops.c (added)
-
vhc/main.c (added)
-
vhc/transfer.c (added)
-
vhc/vhc.ma (added)
-
vhc/vhcd.h (added)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/isa/isa.c
r9e2e715 reb522e8 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 <driver.h> 53 #include <resource.h> 54 #include <ddf/driver.h> 55 #include <ddf/log.h> 56 #include <ops/hw_res.h> 54 57 55 58 #include <devman.h> … … 58 61 59 62 #define NAME "isa" 60 #define CHILD_DEV_CONF_PATH "/drv/isa/isa.dev" 63 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev" 64 65 /** Obtain soft-state pointer from function node pointer */ 66 #define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data)) 61 67 62 68 #define ISA_MAX_HW_RES 4 63 69 64 typedef struct isa_child_data { 70 typedef struct isa_fun { 71 ddf_fun_t *fnode; 65 72 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) 80 { 81 // TODO 73 } isa_fun_t; 74 75 static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode) 76 { 77 isa_fun_t *fun = ISA_FUN(fnode); 78 assert(fun != NULL); 79 80 return &fun->hw_resources; 81 } 82 83 static bool isa_enable_fun_interrupt(ddf_fun_t *fnode) 84 { 85 /* TODO */ 82 86 83 87 return false; 84 88 } 85 89 86 static resource_iface_t isa_child_res_iface= {87 &isa_get_ child_resources,88 &isa_enable_ child_interrupt90 static hw_res_ops_t isa_fun_hw_res_ops = { 91 &isa_get_fun_resources, 92 &isa_enable_fun_interrupt 89 93 }; 90 94 91 static d evice_ops_t isa_child_dev_ops;92 93 static int isa_add_device(d evice_t *dev);95 static ddf_dev_ops_t isa_fun_ops; 96 97 static int isa_add_device(ddf_dev_t *dev); 94 98 95 99 /** The isa device driver's standard operations */ … … 104 108 }; 105 109 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) 110 static isa_fun_t *isa_fun_create(ddf_dev_t *dev, const char *name) 111 { 112 isa_fun_t *fun = calloc(1, sizeof(isa_fun_t)); 113 if (fun == NULL) 122 114 return NULL; 123 115 124 isa_child_data_t *data = create_isa_child_data();125 if ( data== NULL) {126 delete_device(dev);116 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name); 117 if (fnode == NULL) { 118 free(fun); 127 119 return NULL; 128 120 } 129 121 130 dev->driver_data = data; 131 return dev; 132 } 133 134 static char *read_dev_conf(const char *conf_path) 122 fun->fnode = fnode; 123 fnode->driver_data = fun; 124 return fun; 125 } 126 127 static char *fun_conf_read(const char *conf_path) 135 128 { 136 129 bool suc = false; … … 142 135 fd = open(conf_path, O_RDONLY); 143 136 if (fd < 0) { 144 printf(NAME ": unable to open %s\n", conf_path);137 ddf_msg(LVL_ERROR, "Unable to open %s", conf_path); 145 138 goto cleanup; 146 139 } … … 149 142 150 143 len = lseek(fd, 0, SEEK_END); 151 lseek(fd, 0, SEEK_SET); 144 lseek(fd, 0, SEEK_SET); 152 145 if (len == 0) { 153 printf(NAME ": read_dev_conf error: configuration file '%s' "154 "is empty.\n",conf_path);146 ddf_msg(LVL_ERROR, "Configuration file '%s' is empty.", 147 conf_path); 155 148 goto cleanup; 156 149 } … … 158 151 buf = malloc(len + 1); 159 152 if (buf == NULL) { 160 printf(NAME ": read_dev_conf error: memory allocation failed.\n");153 ddf_msg(LVL_ERROR, "Memory allocation failed."); 161 154 goto cleanup; 162 155 } 163 156 164 157 if (0 >= read(fd, buf, len)) { 165 printf(NAME ": read_dev_conf error: unable to read file '%s'.\n", 166 conf_path); 158 ddf_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path); 167 159 goto cleanup; 168 160 } … … 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 ddf_msg(LVL_NOTE, "Added irq 0x%x to function %s", 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++; 282 283 printf(NAME ": added io range (addr=0x%x, size=0x%x) to " 284 "device %s\n", addr, len, dev->name); 285 } 286 } 287 288 static void get_dev_irq(device_t *dev, char *val) 270 fun->hw_resources.count++; 271 272 ddf_msg(LVL_NOTE, "Added io range (addr=0x%x, size=0x%x) to " 273 "function %s", (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) 289 279 { 290 280 int irq = 0; 291 281 char *end = NULL; 292 282 293 val = skip_spaces(val); 283 val = skip_spaces(val); 294 284 irq = (int)strtol(val, &end, 0x10); 295 285 296 286 if (val != end) 297 isa_ child_set_irq(dev, irq);298 } 299 300 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) 301 291 { 302 292 size_t addr, len; 303 293 char *end = NULL; 304 294 305 val = skip_spaces(val); 295 val = skip_spaces(val); 306 296 addr = strtol(val, &end, 0x10); 307 297 … … 309 299 return; 310 300 311 val = skip_spaces(end); 301 val = skip_spaces(end); 312 302 len = strtol(val, &end, 0x10); 313 303 … … 315 305 return; 316 306 317 isa_ child_set_io_range(dev, addr, len);307 isa_fun_set_io_range(fun, addr, len); 318 308 } 319 309 … … 330 320 } 331 321 332 static void get_dev_match_id(device_t *dev, char *val)322 static void fun_parse_match_id(isa_fun_t *fun, char *val) 333 323 { 334 324 char *id = NULL; 335 325 int score = 0; 336 326 char *end = NULL; 337 338 val = skip_spaces(val); 327 int rc; 328 329 val = skip_spaces(val); 339 330 340 331 score = (int)strtol(val, &end, 10); 341 332 if (val == end) { 342 printf(NAME " : error - could not read match score for"343 " device %s.\n", dev->name);333 ddf_msg(LVL_ERROR, "Cannot read match score for function " 334 "%s.", fun->fnode->name); 344 335 return; 345 336 } 346 337 347 match_id_t *match_id = create_match_id(); 348 if (match_id == NULL) { 349 printf(NAME " : failed to allocate match id for device %s.\n", 350 dev->name); 351 return; 352 } 353 354 val = skip_spaces(end); 338 val = skip_spaces(end); 355 339 get_match_id(&id, val); 356 340 if (id == NULL) { 357 printf(NAME " : error - could not read match id for " 358 "device %s.\n", dev->name); 359 delete_match_id(match_id); 341 ddf_msg(LVL_ERROR, "Cannot read match ID for function %s.", 342 fun->fnode->name); 360 343 return; 361 344 } 362 345 363 match_id->id = id; 364 match_id->score = score; 365 366 printf(NAME ": adding match id '%s' with score %d to device %s\n", id, 367 score, dev->name); 368 add_match_id(&dev->match_ids, match_id); 369 } 370 371 static bool read_dev_prop(device_t *dev, char *line, const char *prop, 372 void (*read_fn)(device_t *, char *)) 346 ddf_msg(LVL_DEBUG, "Adding match id '%s' with score %d to " 347 "function %s", id, score, fun->fnode->name); 348 349 rc = ddf_fun_add_match_id(fun->fnode, id, score); 350 if (rc != EOK) { 351 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", 352 str_error(rc)); 353 } 354 } 355 356 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop, 357 void (*read_fn)(isa_fun_t *, char *)) 373 358 { 374 359 size_t proplen = str_size(prop); … … 377 362 line += proplen; 378 363 line = skip_spaces(line); 379 (*read_fn)( dev, line);364 (*read_fn)(fun, line); 380 365 381 366 return true; … … 385 370 } 386 371 387 static void get_dev_prop(device_t *dev, char *line)372 static void fun_prop_parse(isa_fun_t *fun, char *line) 388 373 { 389 374 /* Skip leading spaces. */ 390 375 line = skip_spaces(line); 391 376 392 if (!read_dev_prop(dev, line, "io_range", &get_dev_io_range) && 393 !read_dev_prop(dev, line, "irq", &get_dev_irq) && 394 !read_dev_prop(dev, line, "match", &get_dev_match_id)) 395 { 396 printf(NAME " error undefined device property at line '%s'\n", 397 line); 398 } 399 } 400 401 static void child_alloc_hw_res(device_t *dev) 402 { 403 isa_child_data_t *data = (isa_child_data_t *)dev->driver_data; 404 data->hw_resources.resources = 377 if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) && 378 !prop_parse(fun, line, "irq", &fun_parse_irq) && 379 !prop_parse(fun, line, "match", &fun_parse_match_id)) { 380 381 ddf_msg(LVL_ERROR, "Undefined device property at line '%s'", 382 line); 383 } 384 } 385 386 static void fun_hw_res_alloc(isa_fun_t *fun) 387 { 388 fun->hw_resources.resources = 405 389 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 406 390 } 407 391 408 static char * read_isa_dev_info(char *dev_conf, device_t *parent)392 static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev) 409 393 { 410 394 char *line; 411 char * dev_name = NULL;395 char *fun_name = NULL; 412 396 413 397 /* Skip empty lines. */ 414 398 while (true) { 415 line = str_get_line( dev_conf, &dev_conf);399 line = str_get_line(fun_conf, &fun_conf); 416 400 417 401 if (line == NULL) { … … 425 409 426 410 /* Get device name. */ 427 dev_name = get_device_name(line);428 if ( dev_name == NULL)411 fun_name = get_device_name(line); 412 if (fun_name == NULL) 429 413 return NULL; 430 414 431 device_t *dev = create_isa_child_dev();432 if ( dev== NULL) {433 free( dev_name);415 isa_fun_t *fun = isa_fun_create(dev, fun_name); 416 if (fun == NULL) { 417 free(fun_name); 434 418 return NULL; 435 419 } 436 420 437 dev->name = dev_name;438 439 421 /* Allocate buffer for the list of hardware resources of the device. */ 440 child_alloc_hw_res(dev);422 fun_hw_res_alloc(fun); 441 423 442 424 /* Get properties of the device (match ids, irq and io range). */ 443 425 while (true) { 444 line = str_get_line( dev_conf, &dev_conf);426 line = str_get_line(fun_conf, &fun_conf); 445 427 446 428 if (line_empty(line)) { … … 453 435 * and store it in the device structure. 454 436 */ 455 get_dev_prop(dev, line); 456 457 //printf(NAME ": next line ='%s'\n", dev_conf); 458 //printf(NAME ": current line ='%s'\n", line); 437 fun_prop_parse(fun, line); 459 438 } 460 439 461 440 /* Set device operations to the device. */ 462 dev->ops = &isa_child_dev_ops; 463 464 printf(NAME ": child_device_register(dev, parent); device is %s.\n", 465 dev->name); 466 child_device_register(dev, parent); 467 468 return dev_conf; 469 } 470 471 static void parse_dev_conf(char *conf, device_t *parent) 441 fun->fnode->ops = &isa_fun_ops; 442 443 ddf_msg(LVL_DEBUG, "Binding function %s.", fun->fnode->name); 444 445 /* XXX Handle error */ 446 (void) ddf_fun_bind(fun->fnode); 447 448 return fun_conf; 449 } 450 451 static void fun_conf_parse(char *conf, ddf_dev_t *dev) 472 452 { 473 453 while (conf != NULL && *conf != '\0') { 474 conf = read_isa_dev_info(conf, parent); 475 } 476 } 477 478 static void add_legacy_children(device_t *parent) 479 { 480 char *dev_conf; 481 482 dev_conf = read_dev_conf(CHILD_DEV_CONF_PATH); 483 if (dev_conf != NULL) { 484 parse_dev_conf(dev_conf, parent); 485 free(dev_conf); 486 } 487 } 488 489 static int isa_add_device(device_t *dev) 490 { 491 printf(NAME ": isa_add_device, device handle = %d\n", dev->handle); 492 493 /* Add child devices. */ 494 add_legacy_children(dev); 495 printf(NAME ": finished the enumeration of legacy devices\n", 496 dev->handle); 454 conf = isa_fun_read_info(conf, dev); 455 } 456 } 457 458 static void isa_functions_add(ddf_dev_t *dev) 459 { 460 char *fun_conf; 461 462 fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH); 463 if (fun_conf != NULL) { 464 fun_conf_parse(fun_conf, dev); 465 free(fun_conf); 466 } 467 } 468 469 static int isa_add_device(ddf_dev_t *dev) 470 { 471 ddf_msg(LVL_DEBUG, "isa_add_device, device handle = %d", 472 (int) dev->handle); 473 474 /* Make the bus device more visible. Does not do anything. */ 475 ddf_msg(LVL_DEBUG, "Adding a 'ctl' function"); 476 477 ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl"); 478 if (ctl == NULL) { 479 ddf_msg(LVL_ERROR, "Failed creating control function."); 480 return EXDEV; 481 } 482 483 if (ddf_fun_bind(ctl) != EOK) { 484 ddf_msg(LVL_ERROR, "Failed binding control function."); 485 return EXDEV; 486 } 487 488 /* Add functions as specified in the configuration file. */ 489 isa_functions_add(dev); 490 ddf_msg(LVL_NOTE, "Finished enumerating legacy functions"); 497 491 498 492 return EOK; … … 501 495 static void isa_init() 502 496 { 503 isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_res_iface; 497 ddf_log_init(NAME, LVL_ERROR); 498 isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops; 504 499 } 505 500 … … 508 503 printf(NAME ": HelenOS ISA bus driver\n"); 509 504 isa_init(); 510 return d river_main(&isa_driver);505 return ddf_driver_main(&isa_driver); 511 506 } 512 507 … … 514 509 * @} 515 510 */ 516 -
uspace/drv/ns8250/cyclic_buffer.h
r9e2e715 reb522e8 45 45 46 46 /* 47 * @return sFalse if the buffer is full.47 * @return False if the buffer is full. 48 48 */ 49 49 static inline bool buf_push_back(cyclic_buffer_t *buf, uint8_t item) -
uspace/drv/ns8250/ns8250.c
r9e2e715 reb522e8 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 <char.h> 56 #include <resource.h> 55 #include <ddf/driver.h> 56 #include <ddf/interrupt.h> 57 #include <ddf/log.h> 58 #include <ops/char_dev.h> 57 59 58 60 #include <devman.h> … … 68 70 #define MAX_BAUD_RATE 115200 69 71 #define DLAB_MASK (1 << 7) 72 73 /** Obtain soft-state structure from function node */ 74 #define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data)) 75 76 /** Obtain soft-state structure from device node */ 77 #define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data)) 70 78 71 79 /** The number of bits of one data unit send by the serial port. */ … … 86 94 87 95 /** The driver data for the serial port devices. */ 88 typedef struct ns8250_dev_data { 96 typedef struct ns8250 { 97 /** DDF device node */ 98 ddf_dev_t *dev; 99 /** DDF function node */ 100 ddf_fun_t *fun; 89 101 /** Is there any client conntected to the device? */ 90 102 bool client_connected; … … 99 111 /** The fibril mutex for synchronizing the access to the device. */ 100 112 fibril_mutex_t mutex; 101 } ns8250_ dev_data_t;102 103 /** Create driver data for a device.104 * 105 * @return The driver data.106 */ 107 static ns8250_ dev_data_t *create_ns8250_dev_data(void)108 { 109 ns8250_ dev_data_t *data;110 111 data = (ns8250_dev_data_t *) malloc(sizeof(ns8250_dev_data_t));112 if ( NULL != data) {113 memset(data, 0, sizeof(ns8250_dev_data_t));114 fibril_mutex_initialize(&data->mutex);115 }116 return data;117 } 118 119 /** Delete driver data.120 * 121 * @param dataThe driver data structure.122 */ 123 static void delete_ns8250_dev_data(ns8250_dev_data_t *data)124 { 125 if (data != NULL)126 free(data);113 } ns8250_t; 114 115 /** Create per-device soft-state structure. 116 * 117 * @return Pointer to soft-state structure. 118 */ 119 static ns8250_t *ns8250_new(void) 120 { 121 ns8250_t *ns; 122 123 ns = (ns8250_t *) calloc(1, sizeof(ns8250_t)); 124 if (ns == NULL) 125 return NULL; 126 127 fibril_mutex_initialize(&ns->mutex); 128 return ns; 129 } 130 131 /** Delete soft-state structure. 132 * 133 * @param ns The driver data structure. 134 */ 135 static void ns8250_delete(ns8250_t *ns) 136 { 137 assert(ns != NULL); 138 free(ns); 127 139 } 128 140 … … 172 184 /** Read data from the serial port device. 173 185 * 174 * @param dev The serial port device.186 * @param fun The serial port function 175 187 * @param buf The ouput buffer for read data. 176 188 * @param count The number of bytes to be read. … … 179 191 * error number otherwise. 180 192 */ 181 static int ns8250_read(device_t *dev, char *buf, size_t count) 182 { 193 static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count) 194 { 195 ns8250_t *ns = NS8250(fun); 183 196 int ret = EOK; 184 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 185 186 fibril_mutex_lock(&data->mutex); 187 while (!buf_is_empty(&data->input_buffer) && (size_t)ret < count) { 188 buf[ret] = (char)buf_pop_front(&data->input_buffer); 197 198 fibril_mutex_lock(&ns->mutex); 199 while (!buf_is_empty(&ns->input_buffer) && (size_t)ret < count) { 200 buf[ret] = (char)buf_pop_front(&ns->input_buffer); 189 201 ret++; 190 202 } 191 fibril_mutex_unlock(& data->mutex);203 fibril_mutex_unlock(&ns->mutex); 192 204 193 205 return ret; … … 196 208 /** Write a character to the serial port. 197 209 * 198 * @param data The serial port device's driver data.199 * @param c The character to be written .200 */ 201 static inline void ns8250_putchar(ns8250_ dev_data_t *data, uint8_t c)202 { 203 fibril_mutex_lock(& data->mutex);204 ns8250_write_8( data->port, c);205 fibril_mutex_unlock(& data->mutex);210 * @param ns Serial port device 211 * @param c The character to be written 212 */ 213 static inline void ns8250_putchar(ns8250_t *ns, uint8_t c) 214 { 215 fibril_mutex_lock(&ns->mutex); 216 ns8250_write_8(ns->port, c); 217 fibril_mutex_unlock(&ns->mutex); 206 218 } 207 219 208 220 /** Write data to the serial port. 209 221 * 210 * @param dev The serial port device.211 * @param buf The data to be written .212 * @param count The number of bytes to be written .213 * @return Zero on success .214 */ 215 static int ns8250_write(d evice_t *dev, char *buf, size_t count)216 { 217 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;222 * @param fun The serial port function 223 * @param buf The data to be written 224 * @param count The number of bytes to be written 225 * @return Zero on success 226 */ 227 static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count) 228 { 229 ns8250_t *ns = NS8250(fun); 218 230 size_t idx; 219 231 220 232 for (idx = 0; idx < count; idx++) 221 ns8250_putchar( data, (uint8_t) buf[idx]);233 ns8250_putchar(ns, (uint8_t) buf[idx]); 222 234 223 235 return 0; 224 236 } 225 237 226 static d evice_ops_t ns8250_dev_ops;238 static ddf_dev_ops_t ns8250_dev_ops; 227 239 228 240 /** The character interface's callbacks. */ 229 static char_ iface_t ns8250_char_iface= {241 static char_dev_ops_t ns8250_char_dev_ops = { 230 242 .read = &ns8250_read, 231 243 .write = &ns8250_write 232 244 }; 233 245 234 static int ns8250_add_device(d evice_t *dev);246 static int ns8250_add_device(ddf_dev_t *dev); 235 247 236 248 /** The serial port device driver's standard operations. */ … … 245 257 }; 246 258 247 /** Clean up the serial port device structure. 248 * 249 * @param dev The device structure. 250 */ 251 static void ns8250_dev_cleanup(device_t *dev) 252 { 253 if (dev->driver_data != NULL) { 254 delete_ns8250_dev_data((ns8250_dev_data_t*) dev->driver_data); 255 dev->driver_data = NULL; 256 } 257 258 if (dev->parent_phone > 0) { 259 ipc_hangup(dev->parent_phone); 260 dev->parent_phone = 0; 259 /** Clean up the serial port soft-state 260 * 261 * @param ns Serial port device 262 */ 263 static void ns8250_dev_cleanup(ns8250_t *ns) 264 { 265 if (ns->dev->parent_phone > 0) { 266 async_hangup(ns->dev->parent_phone); 267 ns->dev->parent_phone = 0; 261 268 } 262 269 } … … 264 271 /** Enable the i/o ports of the device. 265 272 * 266 * @param dev The serial port device. 267 * @return True on success, false otherwise. 268 */ 269 static bool ns8250_pio_enable(device_t *dev) 270 { 271 printf(NAME ": ns8250_pio_enable %s\n", dev->name); 272 273 ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data; 273 * @param ns Serial port device 274 * @return True on success, false otherwise 275 */ 276 static bool ns8250_pio_enable(ns8250_t *ns) 277 { 278 ddf_msg(LVL_DEBUG, "ns8250_pio_enable %s", ns->dev->name); 274 279 275 280 /* Gain control over port's registers. */ 276 if (pio_enable((void *) data->io_addr, REG_COUNT,277 (void **) & data->port)) {278 printf(NAME ": error - cannot gain the port %lx for device "279 " %s.\n", data->io_addr,dev->name);281 if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT, 282 (void **) &ns->port)) { 283 ddf_msg(LVL_ERROR, "Cannot map the port %#" PRIx32 284 " for device %s.", ns->io_addr, ns->dev->name); 280 285 return false; 281 286 } … … 286 291 /** Probe the serial port device for its presence. 287 292 * 288 * @param dev The serial port device. 289 * @return True if the device is present, false otherwise. 290 */ 291 static bool ns8250_dev_probe(device_t *dev) 292 { 293 printf(NAME ": ns8250_dev_probe %s\n", dev->name); 294 295 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 296 ioport8_t *port_addr = data->port; 293 * @param ns Serial port device 294 * @return True if the device is present, false otherwise 295 */ 296 static bool ns8250_dev_probe(ns8250_t *ns) 297 { 298 ddf_msg(LVL_DEBUG, "ns8250_dev_probe %s", ns->dev->name); 299 300 ioport8_t *port_addr = ns->port; 297 301 bool res = true; 298 302 uint8_t olddata; … … 310 314 pio_write_8(port_addr + 4, olddata); 311 315 312 if (!res) 313 printf(NAME ": device %s is not present.\n", dev->name); 316 if (!res) { 317 ddf_msg(LVL_DEBUG, "Device %s is not present.", 318 ns->dev->name); 319 } 314 320 315 321 return res; … … 318 324 /** Initialize serial port device. 319 325 * 320 * @param dev The serial port device.321 * @return Zero on success, negative error number otherwise .322 */ 323 static int ns8250_dev_initialize( device_t *dev)324 { 325 printf(NAME ": ns8250_dev_initialize %s\n",dev->name);326 * @param ns Serial port device 327 * @return Zero on success, negative error number otherwise 328 */ 329 static int ns8250_dev_initialize(ns8250_t *ns) 330 { 331 ddf_msg(LVL_DEBUG, "ns8250_dev_initialize %s", ns->dev->name); 326 332 327 333 int ret = EOK; … … 330 336 memset(&hw_resources, 0, sizeof(hw_resource_list_t)); 331 337 332 /* Allocate driver data for the device. */333 ns8250_dev_data_t *data = create_ns8250_dev_data();334 if (data == NULL)335 return ENOMEM;336 dev->driver_data = data;337 338 338 /* Connect to the parent's driver. */ 339 dev->parent_phone = devman_parent_device_connect(dev->handle,339 ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle, 340 340 IPC_FLAG_BLOCKING); 341 if ( dev->parent_phone < 0) {342 printf(NAME ": failed to connect to the parent driver of the"343 "device %s. \n",dev->name);344 ret = EPARTY; /* FIXME: use another EC */341 if (ns->dev->parent_phone < 0) { 342 ddf_msg(LVL_ERROR, "Failed to connect to parent driver of " 343 "device %s.", ns->dev->name); 344 ret = ns->dev->parent_phone; 345 345 goto failed; 346 346 } 347 347 348 348 /* Get hw resources. */ 349 if (!get_hw_resources(dev->parent_phone, &hw_resources)) {350 printf(NAME ": failed to get hw resources for the device "351 "%s.\n", dev->name);352 ret = EPARTY; /* FIXME: use another EC */349 ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources); 350 if (ret != EOK) { 351 ddf_msg(LVL_ERROR, "Failed to get HW resources for device " 352 "%s.", ns->dev->name); 353 353 goto failed; 354 354 } … … 363 363 switch (res->type) { 364 364 case INTERRUPT: 365 data->irq = res->res.interrupt.irq;365 ns->irq = res->res.interrupt.irq; 366 366 irq = true; 367 printf(NAME ": the %s device was asigned irq = 0x%x.\n",368 dev->name, data->irq);367 ddf_msg(LVL_NOTE, "Device %s was asigned irq = 0x%x.", 368 ns->dev->name, ns->irq); 369 369 break; 370 370 371 371 case IO_RANGE: 372 data->io_addr = res->res.io_range.address;372 ns->io_addr = res->res.io_range.address; 373 373 if (res->res.io_range.size < REG_COUNT) { 374 printf(NAME ": i/o range assigned to the device"375 " %s is too small.\n",dev->name);376 ret = E PARTY; /* FIXME: use another EC */374 ddf_msg(LVL_ERROR, "I/O range assigned to " 375 "device %s is too small.", ns->dev->name); 376 ret = ELIMIT; 377 377 goto failed; 378 378 } 379 379 ioport = true; 380 printf(NAME ": the %s device was asigned i/oaddress = "381 "0x%x. \n", dev->name, data->io_addr);382 break;380 ddf_msg(LVL_NOTE, "Device %s was asigned I/O address = " 381 "0x%x.", ns->dev->name, ns->io_addr); 382 break; 383 383 384 384 default: … … 388 388 389 389 if (!irq || !ioport) { 390 printf(NAME ": missing hw resource(s) for the device %s.\n",391 dev->name);392 ret = E PARTY; /* FIXME: use another EC */390 ddf_msg(LVL_ERROR, "Missing HW resource(s) for device %s.", 391 ns->dev->name); 392 ret = ENOENT; 393 393 goto failed; 394 394 } 395 395 396 clean_hw_resource_list(&hw_resources);396 hw_res_clean_resource_list(&hw_resources); 397 397 return ret; 398 398 399 399 failed: 400 ns8250_dev_cleanup( dev);401 clean_hw_resource_list(&hw_resources);400 ns8250_dev_cleanup(ns); 401 hw_res_clean_resource_list(&hw_resources); 402 402 return ret; 403 403 } … … 405 405 /** Enable interrupts on the serial port device. 406 406 * 407 * Interrupt when data is received .407 * Interrupt when data is received 408 408 * 409 409 * @param port The base address of the serial port device's ports. 410 410 */ 411 411 static inline void ns8250_port_interrupts_enable(ioport8_t *port) 412 { 412 { 413 413 pio_write_8(port + 1, 0x1); /* Interrupt when data received. */ 414 414 pio_write_8(port + 4, 0xB); … … 417 417 /** Disable interrupts on the serial port device. 418 418 * 419 * @param port The base address of the serial port device's ports .419 * @param port The base address of the serial port device's ports 420 420 */ 421 421 static inline void ns8250_port_interrupts_disable(ioport8_t *port) … … 426 426 /** Enable interrupts for the serial port device. 427 427 * 428 * @param dev The device. 429 * @return Zero on success, negative error number otherwise. 430 */ 431 static int ns8250_interrupt_enable(device_t *dev) 432 { 433 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 434 int res; 435 436 /* Enable interrupt globally. */ 437 res = interrupt_enable(data->irq); 438 if (res != EOK) 439 return res; 440 428 * @param ns Serial port device 429 * @return Zero on success, negative error number otherwise 430 */ 431 static int ns8250_interrupt_enable(ns8250_t *ns) 432 { 441 433 /* Enable interrupt on the serial port. */ 442 ns8250_port_interrupts_enable( data->port);434 ns8250_port_interrupts_enable(ns->port); 443 435 444 436 return EOK; … … 481 473 482 474 if (baud_rate < 50 || MAX_BAUD_RATE % baud_rate != 0) { 483 printf(NAME ": error - somebody tried to set invalid baud rate "484 "%d\n",baud_rate);475 ddf_msg(LVL_ERROR, "Invalid baud rate %d requested.", 476 baud_rate); 485 477 return EINVAL; 486 478 } … … 625 617 * Set the default parameters of the serial communication. 626 618 * 627 * @param dev The serial port device. 628 */ 629 static void ns8250_initialize_port(device_t *dev) 630 { 631 ns8250_dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data; 632 ioport8_t *port = data->port; 619 * @param ns Serial port device 620 */ 621 static void ns8250_initialize_port(ns8250_t *ns) 622 { 623 ioport8_t *port = ns->port; 633 624 634 625 /* Disable interrupts. */ … … 650 641 * buffer. 651 642 * 652 * @param dev The serial port device. 653 */ 654 static void ns8250_read_from_device(device_t *dev) 655 { 656 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 657 ioport8_t *port = data->port; 643 * @param ns Serial port device 644 */ 645 static void ns8250_read_from_device(ns8250_t *ns) 646 { 647 ioport8_t *port = ns->port; 658 648 bool cont = true; 659 649 660 650 while (cont) { 661 fibril_mutex_lock(& data->mutex);651 fibril_mutex_lock(&ns->mutex); 662 652 663 653 cont = ns8250_received(port); … … 665 655 uint8_t val = ns8250_read_8(port); 666 656 667 if ( data->client_connected) {668 if (!buf_push_back(& data->input_buffer, val)) {669 printf(NAME ": buffer overflow on "670 "%s. \n",dev->name);657 if (ns->client_connected) { 658 if (!buf_push_back(&ns->input_buffer, val)) { 659 ddf_msg(LVL_WARN, "Buffer overflow on " 660 "%s.", ns->dev->name); 671 661 } else { 672 printf(NAME ": the character %c saved "673 "to the buffer of %s. \n",674 val, dev->name);662 ddf_msg(LVL_DEBUG2, "Character %c saved " 663 "to the buffer of %s.", 664 val, ns->dev->name); 675 665 } 676 666 } 677 667 } 678 668 679 fibril_mutex_unlock(& data->mutex);669 fibril_mutex_unlock(&ns->mutex); 680 670 fibril_yield(); 681 671 } … … 689 679 * @param dev The serial port device. 690 680 */ 691 static inline void ns8250_interrupt_handler(d evice_t *dev, ipc_callid_t iid,681 static inline void ns8250_interrupt_handler(ddf_dev_t *dev, ipc_callid_t iid, 692 682 ipc_call_t *icall) 693 683 { 694 ns8250_read_from_device( dev);684 ns8250_read_from_device(NS8250_FROM_DEV(dev)); 695 685 } 696 686 697 687 /** Register the interrupt handler for the device. 698 688 * 689 * @param ns Serial port device 690 */ 691 static inline int ns8250_register_interrupt_handler(ns8250_t *ns) 692 { 693 return register_interrupt_handler(ns->dev, ns->irq, 694 ns8250_interrupt_handler, NULL); 695 } 696 697 /** Unregister the interrupt handler for the device. 698 * 699 * @param ns Serial port device 700 */ 701 static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns) 702 { 703 return unregister_interrupt_handler(ns->dev, ns->irq); 704 } 705 706 /** The add_device callback method of the serial port driver. 707 * 708 * Probe and initialize the newly added device. 709 * 699 710 * @param dev The serial port device. 700 711 */ 701 static inline int ns8250_register_interrupt_handler(device_t *dev) 702 { 703 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 704 705 return register_interrupt_handler(dev, data->irq, 706 ns8250_interrupt_handler, NULL); 707 } 708 709 /** Unregister the interrupt handler for the device. 710 * 711 * @param dev The serial port device. 712 */ 713 static inline int ns8250_unregister_interrupt_handler(device_t *dev) 714 { 715 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 716 717 return unregister_interrupt_handler(dev, data->irq); 718 } 719 720 /** The add_device callback method of the serial port driver. 721 * 722 * Probe and initialize the newly added device. 723 * 724 * @param dev The serial port device. 725 */ 726 static int ns8250_add_device(device_t *dev) 727 { 728 printf(NAME ": ns8250_add_device %s (handle = %d)\n", 729 dev->name, dev->handle); 730 731 int res = ns8250_dev_initialize(dev); 732 if (res != EOK) 733 return res; 734 735 if (!ns8250_pio_enable(dev)) { 736 ns8250_dev_cleanup(dev); 737 return EADDRNOTAVAIL; 712 static int ns8250_add_device(ddf_dev_t *dev) 713 { 714 ns8250_t *ns = NULL; 715 ddf_fun_t *fun = NULL; 716 bool need_cleanup = false; 717 int rc; 718 719 ddf_msg(LVL_DEBUG, "ns8250_add_device %s (handle = %d)", 720 dev->name, (int) dev->handle); 721 722 /* Allocate soft-state for the device */ 723 ns = ns8250_new(); 724 if (ns == NULL) { 725 rc = ENOMEM; 726 goto fail; 727 } 728 729 ns->dev = dev; 730 dev->driver_data = ns; 731 732 rc = ns8250_dev_initialize(ns); 733 if (rc != EOK) 734 goto fail; 735 736 need_cleanup = true; 737 738 if (!ns8250_pio_enable(ns)) { 739 rc = EADDRNOTAVAIL; 740 goto fail; 738 741 } 739 742 740 743 /* Find out whether the device is present. */ 741 if (!ns8250_dev_probe( dev)) {742 ns8250_dev_cleanup(dev);743 return ENOENT;744 if (!ns8250_dev_probe(ns)) { 745 rc = ENOENT; 746 goto fail; 744 747 } 745 748 746 749 /* Serial port initialization (baud rate etc.). */ 747 ns8250_initialize_port( dev);750 ns8250_initialize_port(ns); 748 751 749 752 /* Register interrupt handler. */ 750 if (ns8250_register_interrupt_handler( dev) != EOK) {751 printf(NAME ": failed to register interrupt handler.\n");752 ns8250_dev_cleanup(dev);753 return res;753 if (ns8250_register_interrupt_handler(ns) != EOK) { 754 ddf_msg(LVL_ERROR, "Failed to register interrupt handler."); 755 rc = EADDRNOTAVAIL; 756 goto fail; 754 757 } 755 758 756 759 /* Enable interrupt. */ 757 res = ns8250_interrupt_enable(dev); 758 if (res != EOK) { 759 printf(NAME ": failed to enable the interrupt. Error code = " 760 "%d.\n", res); 761 ns8250_dev_cleanup(dev); 762 ns8250_unregister_interrupt_handler(dev); 763 return res; 760 rc = ns8250_interrupt_enable(ns); 761 if (rc != EOK) { 762 ddf_msg(LVL_ERROR, "Failed to enable the interrupt. Error code = " 763 "%d.", rc); 764 goto fail; 765 } 766 767 fun = ddf_fun_create(dev, fun_exposed, "a"); 768 if (fun == NULL) { 769 ddf_msg(LVL_ERROR, "Failed creating function."); 770 goto fail; 764 771 } 765 772 766 773 /* Set device operations. */ 767 dev->ops = &ns8250_dev_ops; 768 769 add_device_to_class(dev, "serial"); 770 771 printf(NAME ": the %s device has been successfully initialized.\n", 774 fun->ops = &ns8250_dev_ops; 775 rc = ddf_fun_bind(fun); 776 if (rc != EOK) { 777 ddf_msg(LVL_ERROR, "Failed binding function."); 778 goto fail; 779 } 780 781 ns->fun = fun; 782 783 ddf_fun_add_to_class(fun, "serial"); 784 785 ddf_msg(LVL_NOTE, "Device %s successfully initialized.", 772 786 dev->name); 773 787 774 788 return EOK; 789 fail: 790 if (fun != NULL) 791 ddf_fun_destroy(fun); 792 if (need_cleanup) 793 ns8250_dev_cleanup(ns); 794 if (ns != NULL) 795 ns8250_delete(ns); 796 return rc; 775 797 } 776 798 … … 782 804 * @param dev The device. 783 805 */ 784 static int ns8250_open(d evice_t *dev)785 { 786 ns8250_ dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;806 static int ns8250_open(ddf_fun_t *fun) 807 { 808 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 787 809 int res; 788 810 … … 795 817 } 796 818 fibril_mutex_unlock(&data->mutex); 797 819 798 820 return res; 799 821 } … … 806 828 * @param dev The device. 807 829 */ 808 static void ns8250_close(d evice_t *dev)809 { 810 ns8250_ dev_data_t *data = (ns8250_dev_data_t *)dev->driver_data;830 static void ns8250_close(ddf_fun_t *fun) 831 { 832 ns8250_t *data = (ns8250_t *) fun->dev->driver_data; 811 833 812 834 fibril_mutex_lock(&data->mutex); … … 830 852 */ 831 853 static void 832 ns8250_get_props(d evice_t *dev, unsigned int *baud_rate, unsigned int *parity,854 ns8250_get_props(ddf_dev_t *dev, unsigned int *baud_rate, unsigned int *parity, 833 855 unsigned int *word_length, unsigned int* stop_bits) 834 856 { 835 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;857 ns8250_t *data = (ns8250_t *) dev->driver_data; 836 858 ioport8_t *port = data->port; 837 859 … … 843 865 fibril_mutex_unlock(&data->mutex); 844 866 845 printf(NAME ":ns8250_get_props: baud rate %d, parity 0x%x, word "846 "length %d, stop bits %d \n", *baud_rate, *parity, *word_length,867 ddf_msg(LVL_DEBUG, "ns8250_get_props: baud rate %d, parity 0x%x, word " 868 "length %d, stop bits %d", *baud_rate, *parity, *word_length, 847 869 *stop_bits); 848 870 } … … 857 879 * @param stop_bits The number of stop bits to be used. 858 880 */ 859 static int ns8250_set_props(d evice_t *dev, unsigned int baud_rate,881 static int ns8250_set_props(ddf_dev_t *dev, unsigned int baud_rate, 860 882 unsigned int parity, unsigned int word_length, unsigned int stop_bits) 861 883 { 862 printf(NAME ":ns8250_set_props: baud rate %d, parity 0x%x, word "863 "length %d, stop bits %d \n", baud_rate, parity, word_length,884 ddf_msg(LVL_DEBUG, "ns8250_set_props: baud rate %d, parity 0x%x, word " 885 "length %d, stop bits %d", baud_rate, parity, word_length, 864 886 stop_bits); 865 887 866 ns8250_ dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;888 ns8250_t *data = (ns8250_t *) dev->driver_data; 867 889 ioport8_t *port = data->port; 868 890 int ret; … … 884 906 * Configure the parameters of the serial communication. 885 907 */ 886 static void ns8250_default_handler(d evice_t *dev, ipc_callid_t callid,908 static void ns8250_default_handler(ddf_fun_t *fun, ipc_callid_t callid, 887 909 ipc_call_t *call) 888 910 { 889 ipcarg_t method = IPC_GET_METHOD(*call);911 sysarg_t method = IPC_GET_IMETHOD(*call); 890 912 int ret; 891 913 unsigned int baud_rate, parity, word_length, stop_bits; … … 893 915 switch (method) { 894 916 case SERIAL_GET_COM_PROPS: 895 ns8250_get_props( dev, &baud_rate, &parity, &word_length,917 ns8250_get_props(fun->dev, &baud_rate, &parity, &word_length, 896 918 &stop_bits); 897 ipc_answer_4(callid, EOK, baud_rate, parity, word_length,919 async_answer_4(callid, EOK, baud_rate, parity, word_length, 898 920 stop_bits); 899 921 break; … … 904 926 word_length = IPC_GET_ARG3(*call); 905 927 stop_bits = IPC_GET_ARG4(*call); 906 ret = ns8250_set_props( dev, baud_rate, parity, word_length,928 ret = ns8250_set_props(fun->dev, baud_rate, parity, word_length, 907 929 stop_bits); 908 ipc_answer_0(callid, ret);930 async_answer_0(callid, ret); 909 931 break; 910 932 911 933 default: 912 ipc_answer_0(callid, ENOTSUP);934 async_answer_0(callid, ENOTSUP); 913 935 } 914 936 } … … 921 943 static void ns8250_init(void) 922 944 { 945 ddf_log_init(NAME, LVL_ERROR); 946 923 947 ns8250_dev_ops.open = &ns8250_open; 924 948 ns8250_dev_ops.close = &ns8250_close; 925 949 926 ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_ iface;950 ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_dev_ops; 927 951 ns8250_dev_ops.default_handler = &ns8250_default_handler; 928 952 } … … 932 956 printf(NAME ": HelenOS serial port driver\n"); 933 957 ns8250_init(); 934 return d river_main(&ns8250_driver);958 return ddf_driver_main(&ns8250_driver); 935 959 } 936 960 -
uspace/drv/ohci/utils/malloc32.h
r9e2e715 reb522e8 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2010 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 /** @addtogroup ip 28 /** @addtogroup drvusbohci 30 29 * @{ 31 30 */ 31 /** @file 32 * @brief OHCI driver 33 */ 34 #ifndef DRV_OHCI_UTILS_MALLOC32_H 35 #define DRV_OHCI_UTILS_MALLOC32_H 32 36 33 /** @file 34 * IP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry 37 * points. 37 #include <assert.h> 38 #include <malloc.h> 39 #include <errno.h> 40 #include <mem.h> 41 #include <as.h> 42 43 /** Get physical address translation 38 44 * 39 * @see module.c 45 * @param[in] addr Virtual address to translate 46 * @return Physical address if exists, NULL otherwise. 40 47 */ 48 static inline uintptr_t addr_to_phys(void *addr) 49 { 50 uintptr_t result; 51 int ret = as_get_physical_mapping(addr, &result); 41 52 42 #include <async.h> 43 #include <stdio.h> 44 #include <ipc/ipc.h> 45 #include <ipc/services.h> 46 #include <errno.h> 47 48 #include <net/modules.h> 49 #include <net_interface.h> 50 #include <net/packet.h> 51 #include <il_local.h> 52 53 #include "ip.h" 54 #include "ip_module.h" 55 56 /** IP module global data. */ 57 extern ip_globals_t ip_globals; 58 59 int 60 il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 61 ipc_call_t *answer, int *answer_count) 62 { 63 return ip_message_standalone(callid, call, answer, answer_count); 53 if (ret != EOK) 54 return 0; 55 return (result | ((uintptr_t)addr & 0xfff)); 64 56 } 65 66 int il_module_start_standalone(async_client_conn_t client_connection) 67 { 68 ipcarg_t phonehash; 69 int rc; 70 71 async_set_client_connection(client_connection); 72 ip_globals.net_phone = net_connect_module(); 73 74 rc = pm_init(); 75 if (rc != EOK) 76 return rc; 77 78 rc = ip_initialize(client_connection); 79 if (rc != EOK) 80 goto out; 81 82 rc = REGISTER_ME(SERVICE_IP, &phonehash); 83 if (rc != EOK) 84 goto out; 85 86 async_manager(); 87 88 out: 89 pm_destroy(); 90 return rc; 91 } 92 93 /** @} 57 /*----------------------------------------------------------------------------*/ 58 /** Physical mallocator simulator 59 * 60 * @param[in] size Size of the required memory space 61 * @return Address of the aligned and big enough memory place, NULL on failure. 94 62 */ 63 static inline void * malloc32(size_t size) 64 { return memalign(size, size); } 65 /*----------------------------------------------------------------------------*/ 66 /** Physical mallocator simulator 67 * 68 * @param[in] addr Address of the place allocated by malloc32 69 */ 70 static inline void free32(void *addr) 71 { if (addr) free(addr); } 72 #endif 73 /** 74 * @} 75 */ -
uspace/drv/pciintel/pci.c
r9e2e715 reb522e8 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> 50 #include <ddf/log.h> 48 51 #include <devman.h> 49 52 #include <ipc/devman.h> 50 53 #include <ipc/dev_iface.h> 51 #include <resource.h> 54 #include <ipc/irc.h> 55 #include <ipc/ns.h> 56 #include <ipc/services.h> 57 #include <sysinfo.h> 58 #include <ops/hw_res.h> 52 59 #include <device/hw_res.h> 53 60 #include <ddi.h> 54 61 #include <libarch/ddi.h> 62 #include <pci_dev_iface.h> 55 63 56 64 #include "pci.h" … … 61 69 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 62 70 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) 71 /** Obtain PCI function soft-state from DDF function node */ 72 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 73 74 /** Obtain PCI bus soft-state from DDF device node */ 75 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 76 77 /** Obtain PCI bus soft-state from function soft-state */ 78 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 79 80 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) 81 { 82 pci_fun_t *fun = PCI_FUN(fnode); 83 84 if (fun == NULL) 68 85 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 resource_iface_t pciintel_child_res_iface = { 80 &pciintel_get_child_resources, 81 &pciintel_enable_child_interrupt 86 return &fun->hw_resources; 87 } 88 89 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 90 { 91 /* This is an old ugly way, copied from ne2000 driver */ 92 assert(fnode); 93 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data; 94 95 sysarg_t apic; 96 sysarg_t i8259; 97 98 int irc_phone = ENOTSUP; 99 100 if (((sysinfo_get_value("apic", &apic) == EOK) && (apic)) 101 || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) { 102 irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0); 103 } 104 105 if (irc_phone < 0) { 106 return false; 107 } 108 109 size_t i = 0; 110 hw_resource_list_t *res = &dev_data->hw_resources; 111 for (; i < res->count; i++) { 112 if (res->resources[i].type == INTERRUPT) { 113 const int irq = res->resources[i].res.interrupt.irq; 114 const int rc = 115 async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq); 116 if (rc != EOK) { 117 async_hangup(irc_phone); 118 return false; 119 } 120 } 121 } 122 123 async_hangup(irc_phone); 124 return true; 125 } 126 127 static int pci_config_space_write_32( 128 ddf_fun_t *fun, uint32_t address, uint32_t data) 129 { 130 if (address > 252) 131 return EINVAL; 132 pci_conf_write_32(PCI_FUN(fun), address, data); 133 return EOK; 134 } 135 136 static int pci_config_space_write_16( 137 ddf_fun_t *fun, uint32_t address, uint16_t data) 138 { 139 if (address > 254) 140 return EINVAL; 141 pci_conf_write_16(PCI_FUN(fun), address, data); 142 return EOK; 143 } 144 145 static int pci_config_space_write_8( 146 ddf_fun_t *fun, uint32_t address, uint8_t data) 147 { 148 if (address > 255) 149 return EINVAL; 150 pci_conf_write_8(PCI_FUN(fun), address, data); 151 return EOK; 152 } 153 154 static int pci_config_space_read_32( 155 ddf_fun_t *fun, uint32_t address, uint32_t *data) 156 { 157 if (address > 252) 158 return EINVAL; 159 *data = pci_conf_read_32(PCI_FUN(fun), address); 160 return EOK; 161 } 162 163 static int pci_config_space_read_16( 164 ddf_fun_t *fun, uint32_t address, uint16_t *data) 165 { 166 if (address > 254) 167 return EINVAL; 168 *data = pci_conf_read_16(PCI_FUN(fun), address); 169 return EOK; 170 } 171 172 static int pci_config_space_read_8( 173 ddf_fun_t *fun, uint32_t address, uint8_t *data) 174 { 175 if (address > 255) 176 return EINVAL; 177 *data = pci_conf_read_8(PCI_FUN(fun), address); 178 return EOK; 179 } 180 181 static hw_res_ops_t pciintel_hw_res_ops = { 182 &pciintel_get_resources, 183 &pciintel_enable_interrupt 82 184 }; 83 185 84 static device_ops_t pci_child_ops; 85 86 static int pci_add_device(device_t *); 87 88 /** The pci bus driver's standard operations. */ 186 static pci_dev_iface_t pci_dev_ops = { 187 .config_space_read_8 = &pci_config_space_read_8, 188 .config_space_read_16 = &pci_config_space_read_16, 189 .config_space_read_32 = &pci_config_space_read_32, 190 .config_space_write_8 = &pci_config_space_write_8, 191 .config_space_write_16 = &pci_config_space_write_16, 192 .config_space_write_32 = &pci_config_space_write_32 193 }; 194 195 static ddf_dev_ops_t pci_fun_ops = { 196 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 197 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 198 }; 199 200 static int pci_add_device(ddf_dev_t *); 201 202 /** PCI bus driver standard operations */ 89 203 static driver_ops_t pci_ops = { 90 204 .add_device = &pci_add_device 91 205 }; 92 206 93 /** The pci bus driver structure.*/207 /** PCI bus driver structure */ 94 208 static driver_t pci_driver = { 95 209 .name = NAME, … … 97 211 }; 98 212 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); 213 static pci_bus_t *pci_bus_new(void) 214 { 215 pci_bus_t *bus; 216 217 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t)); 218 if (bus == NULL) 219 return NULL; 220 221 fibril_mutex_initialize(&bus->conf_mutex); 222 return bus; 223 } 224 225 static void pci_bus_delete(pci_bus_t *bus) 226 { 227 assert(bus != NULL); 228 free(bus); 229 } 230 231 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 232 { 233 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 234 235 fibril_mutex_lock(&bus->conf_mutex); 132 236 133 237 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);238 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 239 void *addr = bus->conf_data_port + (reg & 3); 240 241 pio_write_32(bus->conf_addr_port, conf_addr); 138 242 139 243 switch (len) { … … 149 253 } 150 254 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); 255 fibril_mutex_unlock(&bus->conf_mutex); 256 } 257 258 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 259 { 260 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 261 262 fibril_mutex_lock(&bus->conf_mutex); 162 263 163 264 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);265 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 266 void *addr = bus->conf_data_port + (reg & 3); 267 268 pio_write_32(bus->conf_addr_port, conf_addr); 168 269 169 270 switch (len) { … … 179 280 } 180 281 181 fibril_mutex_unlock(&bus _data->conf_mutex);182 } 183 184 uint8_t pci_conf_read_8( device_t *dev, int reg)282 fibril_mutex_unlock(&bus->conf_mutex); 283 } 284 285 uint8_t pci_conf_read_8(pci_fun_t *fun, int reg) 185 286 { 186 287 uint8_t res; 187 pci_conf_read( dev, reg, &res, 1);288 pci_conf_read(fun, reg, &res, 1); 188 289 return res; 189 290 } 190 291 191 uint16_t pci_conf_read_16( device_t *dev, int reg)292 uint16_t pci_conf_read_16(pci_fun_t *fun, int reg) 192 293 { 193 294 uint16_t res; 194 pci_conf_read( dev, reg, (uint8_t *) &res, 2);295 pci_conf_read(fun, reg, (uint8_t *) &res, 2); 195 296 return res; 196 297 } 197 298 198 uint32_t pci_conf_read_32( device_t *dev, int reg)299 uint32_t pci_conf_read_32(pci_fun_t *fun, int reg) 199 300 { 200 301 uint32_t res; 201 pci_conf_read( dev, reg, (uint8_t *) &res, 4);302 pci_conf_read(fun, reg, (uint8_t *) &res, 4); 202 303 return res; 203 304 } 204 305 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; 306 void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val) 307 { 308 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 309 } 310 311 void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val) 312 { 313 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 314 } 315 316 void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val) 317 { 318 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 319 } 320 321 void pci_fun_create_match_ids(pci_fun_t *fun) 322 { 224 323 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 324 int rc; 325 326 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 327 fun->vendor_id, fun->device_id); 328 329 if (match_id_str == NULL) { 330 ddf_msg(LVL_ERROR, "Out of memory creating match ID."); 331 return; 332 } 333 334 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 335 if (rc != EOK) { 336 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", 337 str_error(rc)); 338 } 339 235 340 /* TODO add more ids (with subsys ids, using class id etc.) */ 236 341 } 237 342 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; 343 void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size, 344 bool io) 345 { 346 hw_resource_list_t *hw_res_list = &fun->hw_resources; 243 347 hw_resource_t *hw_resources = hw_res_list->resources; 244 348 size_t count = hw_res_list->count; … … 265 369 * address add it to the devices hw resource list. 266 370 * 267 * @param dev The pci device.371 * @param fun PCI function 268 372 * @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 .373 * the device 374 * @return The addr the address of the BAR which should be read next 271 375 */ 272 int pci_read_bar( device_t *dev, int addr)273 { 376 int pci_read_bar(pci_fun_t *fun, int addr) 377 { 274 378 /* Value of the BAR */ 275 379 uint32_t val, mask; … … 285 389 286 390 /* Get the value of the BAR. */ 287 val = pci_conf_read_32(dev, addr); 391 val = pci_conf_read_32(fun, addr); 392 393 #define IO_MASK (~0x3) 394 #define MEM_MASK (~0xf) 288 395 289 396 io = (bool) (val & 1); 290 397 if (io) { 291 398 addrw64 = false; 399 mask = IO_MASK; 292 400 } else { 401 mask = MEM_MASK; 293 402 switch ((val >> 1) & 3) { 294 403 case 0: … … 305 414 306 415 /* Get the address mask. */ 307 pci_conf_write_32( dev, addr, 0xffffffff);308 mask = pci_conf_read_32(dev, addr);416 pci_conf_write_32(fun, addr, 0xffffffff); 417 mask &= pci_conf_read_32(fun, addr); 309 418 310 419 /* Restore the original value. */ 311 pci_conf_write_32( dev, addr, val);312 val = pci_conf_read_32( dev, addr);420 pci_conf_write_32(fun, addr, val); 421 val = pci_conf_read_32(fun, addr); 313 422 314 423 range_size = pci_bar_mask_to_size(mask); 315 424 316 425 if (addrw64) { 317 range_addr = ((uint64_t)pci_conf_read_32( dev, addr + 4) << 32) |426 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | 318 427 (val & 0xfffffff0); 319 428 } else { … … 322 431 323 432 if (range_addr != 0) { 324 printf(NAME ": device %s : ", dev->name);325 printf("address = %x", range_addr);326 printf(", size = %x\n",range_size);327 } 328 329 pci_add_range( dev, range_addr, range_size, io);433 ddf_msg(LVL_DEBUG, "Function %s : address = %" PRIx64 434 ", size = %x", fun->fnode->name, range_addr, 435 (unsigned int) range_size); 436 } 437 438 pci_add_range(fun, range_addr, range_size, io); 330 439 331 440 if (addrw64) … … 335 444 } 336 445 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; 446 void pci_add_interrupt(pci_fun_t *fun, int irq) 447 { 448 hw_resource_list_t *hw_res_list = &fun->hw_resources; 341 449 hw_resource_t *hw_resources = hw_res_list->resources; 342 450 size_t count = hw_res_list->count; … … 350 458 hw_res_list->count++; 351 459 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);460 ddf_msg(LVL_NOTE, "Function %s uses irq %x.", fun->fnode->name, irq); 461 } 462 463 void pci_read_interrupt(pci_fun_t *fun) 464 { 465 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 358 466 if (irq != 0xff) 359 pci_add_interrupt( dev, irq);467 pci_add_interrupt(fun, irq); 360 468 } 361 469 362 470 /** Enumerate (recursively) and register the devices connected to a pci bus. 363 471 * 364 * @param parent The host-to-pci bridge device.365 * @param bus_num The bus number.472 * @param bus Host-to-PCI bridge 473 * @param bus_num Bus number 366 474 */ 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; 475 void pci_bus_scan(pci_bus_t *bus, int bus_num) 476 { 477 ddf_fun_t *fnode; 478 pci_fun_t *fun; 373 479 374 480 int child_bus = 0; 375 481 int dnum, fnum; 376 482 bool multi; 377 uint8_t header_type; 483 uint8_t header_type; 484 485 fun = pci_fun_new(bus); 378 486 379 487 for (dnum = 0; dnum < 32; dnum++) { 380 488 multi = true; 381 489 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,490 pci_fun_init(fun, bus_num, dnum, fnum); 491 fun->vendor_id = pci_conf_read_16(fun, 384 492 PCI_VENDOR_ID); 385 dev_data->device_id = pci_conf_read_16(dev,493 fun->device_id = pci_conf_read_16(fun, 386 494 PCI_DEVICE_ID); 387 if ( dev_data->vendor_id == 0xffff) {495 if (fun->vendor_id == 0xffff) { 388 496 /* 389 497 * The device is not present, go on scanning the … … 396 504 } 397 505 398 header_type = pci_conf_read_8( dev, PCI_HEADER_TYPE);506 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 399 507 if (fnum == 0) { 400 508 /* Is the device multifunction? */ … … 404 512 header_type = header_type & 0x7F; 405 513 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; 514 char *fun_name = pci_fun_create_name(fun); 515 if (fun_name == NULL) { 516 ddf_msg(LVL_ERROR, "Out of memory."); 517 return; 518 } 519 520 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 521 if (fnode == NULL) { 522 ddf_msg(LVL_ERROR, "Failed creating function."); 523 return; 524 } 525 526 free(fun_name); 527 fun->fnode = fnode; 528 529 pci_alloc_resource_list(fun); 530 pci_read_bars(fun); 531 pci_read_interrupt(fun); 532 533 fnode->ops = &pci_fun_ops; 534 fnode->driver_data = fun; 535 536 ddf_msg(LVL_DEBUG, "Adding new function %s.", 537 fnode->name); 538 539 pci_fun_create_match_ids(fun); 540 541 if (ddf_fun_bind(fnode) != EOK) { 542 pci_clean_resource_list(fun); 543 clean_match_ids(&fnode->match_ids); 544 free((char *) fnode->name); 545 fnode->name = NULL; 424 546 continue; 425 547 } … … 427 549 if (header_type == PCI_HEADER_TYPE_BRIDGE || 428 550 header_type == PCI_HEADER_TYPE_CARDBUS) { 429 child_bus = pci_conf_read_8( dev,551 child_bus = pci_conf_read_8(fun, 430 552 PCI_BRIDGE_SEC_BUS_NUM); 431 printf(NAME ": device is pci-to-pci bridge, " 432 "secondary bus number = %d.\n", bus_num); 553 ddf_msg(LVL_DEBUG, "Device is pci-to-pci " 554 "bridge, secondary bus number = %d.", 555 bus_num); 433 556 if (child_bus > bus_num) 434 pci_bus_scan( parent, child_bus);557 pci_bus_scan(bus, child_bus); 435 558 } 436 559 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; 560 fun = pci_fun_new(bus); 442 561 } 443 562 } 444 563 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 { 454 printf(NAME ": pci_add_device\n"); 455 456 pci_bus_data_t *bus_data = create_pci_bus_data(); 457 if (bus_data == NULL) { 458 printf(NAME ": pci_add_device allocation failed.\n"); 459 return ENOMEM; 460 } 461 462 dev->parent_phone = devman_parent_device_connect(dev->handle, 564 if (fun->vendor_id == 0xffff) { 565 /* Free the auxiliary function structure. */ 566 pci_fun_delete(fun); 567 } 568 } 569 570 static int pci_add_device(ddf_dev_t *dnode) 571 { 572 pci_bus_t *bus = NULL; 573 ddf_fun_t *ctl = NULL; 574 bool got_res = false; 575 int rc; 576 577 ddf_msg(LVL_DEBUG, "pci_add_device"); 578 dnode->parent_phone = -1; 579 580 bus = pci_bus_new(); 581 if (bus == NULL) { 582 ddf_msg(LVL_ERROR, "pci_add_device allocation failed."); 583 rc = ENOMEM; 584 goto fail; 585 } 586 bus->dnode = dnode; 587 dnode->driver_data = bus; 588 589 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 463 590 IPC_FLAG_BLOCKING); 464 if (d ev->parent_phone < 0) {465 printf(NAME ":pci_add_device failed to connect to the "466 "parent's driver. \n");467 delete_pci_bus_data(bus_data);468 return EPARTY; /* FIXME: use another EC */591 if (dnode->parent_phone < 0) { 592 ddf_msg(LVL_ERROR, "pci_add_device failed to connect to the " 593 "parent's driver."); 594 rc = dnode->parent_phone; 595 goto fail; 469 596 } 470 597 471 598 hw_resource_list_t hw_resources; 472 599 473 if (!get_hw_resources(dev->parent_phone, &hw_resources)) {474 printf(NAME ": pci_add_device failed to get hw resources for "475 "the device.\n");476 delete_pci_bus_data(bus_data);477 ipc_hangup(dev->parent_phone);478 return EPARTY; /* FIXME: use another EC */479 }480 481 printf(NAME ": conf_addr = %x.\n",600 rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources); 601 if (rc != EOK) { 602 ddf_msg(LVL_ERROR, "pci_add_device failed to get hw resources " 603 "for the device."); 604 goto fail; 605 } 606 got_res = true; 607 608 ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".", 482 609 hw_resources.resources[0].res.io_range.address); 483 610 … … 486 613 assert(hw_resources.resources[0].res.io_range.size == 8); 487 614 488 bus _data->conf_io_addr =615 bus->conf_io_addr = 489 616 (uint32_t) hw_resources.resources[0].res.io_range.address; 490 617 491 if (pio_enable((void *)bus_data->conf_io_addr, 8, 492 &bus_data->conf_addr_port)) { 493 printf(NAME ": failed to enable configuration ports.\n"); 494 delete_pci_bus_data(bus_data); 495 ipc_hangup(dev->parent_phone); 496 clean_hw_resource_list(&hw_resources); 497 return EADDRNOTAVAIL; 498 } 499 bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4; 500 501 dev->driver_data = bus_data; 502 503 /* Enumerate child devices. */ 504 printf(NAME ": scanning the bus\n"); 505 pci_bus_scan(dev, 0); 506 507 clean_hw_resource_list(&hw_resources); 618 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 619 &bus->conf_addr_port)) { 620 ddf_msg(LVL_ERROR, "Failed to enable configuration ports."); 621 rc = EADDRNOTAVAIL; 622 goto fail; 623 } 624 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 625 626 /* Make the bus device more visible. It has no use yet. */ 627 ddf_msg(LVL_DEBUG, "Adding a 'ctl' function"); 628 629 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 630 if (ctl == NULL) { 631 ddf_msg(LVL_ERROR, "Failed creating control function."); 632 rc = ENOMEM; 633 goto fail; 634 } 635 636 rc = ddf_fun_bind(ctl); 637 if (rc != EOK) { 638 ddf_msg(LVL_ERROR, "Failed binding control function."); 639 goto fail; 640 } 641 642 /* Enumerate functions. */ 643 ddf_msg(LVL_DEBUG, "Scanning the bus"); 644 pci_bus_scan(bus, 0); 645 646 hw_res_clean_resource_list(&hw_resources); 508 647 509 648 return EOK; 649 650 fail: 651 if (bus != NULL) 652 pci_bus_delete(bus); 653 if (dnode->parent_phone >= 0) 654 async_hangup(dnode->parent_phone); 655 if (got_res) 656 hw_res_clean_resource_list(&hw_resources); 657 if (ctl != NULL) 658 ddf_fun_destroy(ctl); 659 660 return rc; 510 661 } 511 662 512 663 static void pciintel_init(void) 513 664 { 514 pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_res_iface; 515 } 516 517 pci_dev_data_t *create_pci_dev_data(void) 518 { 519 pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t)); 520 521 if (res != NULL) 522 memset(res, 0, sizeof(pci_dev_data_t)); 523 return res; 524 } 525 526 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn) 527 { 528 dev_data->bus = bus; 529 dev_data->dev = dev; 530 dev_data->fn = fn; 531 } 532 533 void delete_pci_dev_data(pci_dev_data_t *dev_data) 534 { 535 if (dev_data != NULL) { 536 clean_hw_resource_list(&dev_data->hw_resources); 537 free(dev_data); 538 } 539 } 540 541 void create_pci_dev_name(device_t *dev) 542 { 543 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 665 ddf_log_init(NAME, LVL_ERROR); 666 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 667 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops; 668 } 669 670 pci_fun_t *pci_fun_new(pci_bus_t *bus) 671 { 672 pci_fun_t *fun; 673 674 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 675 if (fun == NULL) 676 return NULL; 677 678 fun->busptr = bus; 679 return fun; 680 } 681 682 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 683 { 684 fun->bus = bus; 685 fun->dev = dev; 686 fun->fn = fn; 687 } 688 689 void pci_fun_delete(pci_fun_t *fun) 690 { 691 assert(fun != NULL); 692 hw_res_clean_resource_list(&fun->hw_resources); 693 free(fun); 694 } 695 696 char *pci_fun_create_name(pci_fun_t *fun) 697 { 544 698 char *name = NULL; 545 699 546 asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev, 547 dev_data->fn); 548 dev->name = name; 549 } 550 551 bool pci_alloc_resource_list(device_t *dev) 552 { 553 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 554 555 dev_data->hw_resources.resources = 700 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 701 fun->fn); 702 return name; 703 } 704 705 bool pci_alloc_resource_list(pci_fun_t *fun) 706 { 707 fun->hw_resources.resources = 556 708 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 557 return dev_data->hw_resources.resources != NULL; 558 } 559 560 void pci_clean_resource_list(device_t *dev) 561 { 562 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 563 564 if (dev_data->hw_resources.resources != NULL) { 565 free(dev_data->hw_resources.resources); 566 dev_data->hw_resources.resources = NULL; 567 } 568 } 569 570 /** Read the base address registers (BARs) of the device and adds the addresses 571 * to its hw resource list. 709 return fun->hw_resources.resources != NULL; 710 } 711 712 void pci_clean_resource_list(pci_fun_t *fun) 713 { 714 if (fun->hw_resources.resources != NULL) { 715 free(fun->hw_resources.resources); 716 fun->hw_resources.resources = NULL; 717 } 718 } 719 720 /** Read the base address registers (BARs) of the function and add the addresses 721 * to its HW resource list. 572 722 * 573 * @param dev the pci device.723 * @param fun PCI function 574 724 */ 575 void pci_read_bars( device_t *dev)725 void pci_read_bars(pci_fun_t *fun) 576 726 { 577 727 /* … … 582 732 583 733 while (addr <= PCI_BASE_ADDR_5) 584 addr = pci_read_bar( dev, addr);734 addr = pci_read_bar(fun, addr); 585 735 } 586 736 587 737 size_t pci_bar_mask_to_size(uint32_t mask) 588 738 { 589 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 739 size_t size = mask & ~(mask - 1); 740 return size; 590 741 } 591 742 592 743 int main(int argc, char *argv[]) 593 744 { 594 printf(NAME ": HelenOS pci bus driver (intel method 1).\n");745 printf(NAME ": HelenOS PCI bus driver (Intel method 1).\n"); 595 746 pciintel_init(); 596 return d river_main(&pci_driver);747 return ddf_driver_main(&pci_driver); 597 748 } 598 749 -
uspace/drv/pciintel/pci.h
r9e2e715 reb522e8 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
r9e2e715 reb522e8 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2010 Vojtech Horky 4 * Copyright (c) 2011 Jiri Svoboda 3 5 * All rights reserved. 4 6 * … … 43 45 #include <stdlib.h> 44 46 #include <str.h> 47 #include <str_error.h> 45 48 #include <ctype.h> 46 49 #include <macros.h> 47 48 #include <driver.h> 50 #include <inttypes.h> 51 #include <sysinfo.h> 52 53 #include <ddf/driver.h> 54 #include <ddf/log.h> 49 55 #include <devman.h> 50 56 #include <ipc/devman.h> … … 52 58 #define NAME "root" 53 59 54 static int root_add_device(device_t *dev); 60 #define PLATFORM_FUN_NAME "hw" 61 #define PLATFORM_FUN_MATCH_ID_FMT "platform/%s" 62 #define PLATFORM_FUN_MATCH_SCORE 100 63 64 #define VIRTUAL_FUN_NAME "virt" 65 #define VIRTUAL_FUN_MATCH_ID "rootvirt" 66 #define VIRTUAL_FUN_MATCH_SCORE 100 67 68 static int root_add_device(ddf_dev_t *dev); 55 69 56 70 /** The root device driver's standard operations. */ … … 65 79 }; 66 80 67 /** Create the device which represents the root of HW device tree. 68 * 69 * @param parent Parent of the newly created device. 70 * @return 0 on success, negative error number otherwise. 71 */ 72 static int add_platform_child(device_t *parent) 73 { 74 printf(NAME ": adding new child for platform device.\n"); 75 76 int res = EOK; 77 device_t *platform = NULL; 78 match_id_t *match_id = NULL; 79 80 /* Create new device. */ 81 platform = create_device(); 82 if (NULL == platform) { 83 res = ENOMEM; 84 goto failure; 85 } 86 87 platform->name = "hw"; 88 printf(NAME ": the new device's name is %s.\n", platform->name); 89 90 /* Initialize match id list. */ 91 match_id = create_match_id(); 92 if (NULL == match_id) { 93 res = ENOMEM; 94 goto failure; 95 } 96 97 /* TODO - replace this with some better solution (sysinfo ?) */ 98 match_id->id = STRING(UARCH); 99 match_id->score = 100; 100 add_match_id(&platform->match_ids, match_id); 101 102 /* Register child device. */ 103 res = child_device_register(platform, parent); 104 if (EOK != res) 105 goto failure; 106 107 return res; 108 109 failure: 110 if (NULL != match_id) 111 match_id->id = NULL; 112 113 if (NULL != platform) { 114 platform->name = NULL; 115 delete_device(platform); 116 } 117 118 return res; 81 /** Create the function which represents the root of virtual device tree. 82 * 83 * @param dev Device 84 * @return EOK on success or negative error code 85 */ 86 static int add_virtual_root_fun(ddf_dev_t *dev) 87 { 88 const char *name = VIRTUAL_FUN_NAME; 89 ddf_fun_t *fun; 90 int rc; 91 92 ddf_msg(LVL_DEBUG, "Adding new function for virtual devices. " 93 "Function node is `%s' (%d %s)", name, 94 VIRTUAL_FUN_MATCH_SCORE, VIRTUAL_FUN_MATCH_ID); 95 96 fun = ddf_fun_create(dev, fun_inner, name); 97 if (fun == NULL) { 98 ddf_msg(LVL_ERROR, "Failed creating function %s", name); 99 return ENOMEM; 100 } 101 102 rc = ddf_fun_add_match_id(fun, VIRTUAL_FUN_MATCH_ID, 103 VIRTUAL_FUN_MATCH_SCORE); 104 if (rc != EOK) { 105 ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s", 106 name); 107 ddf_fun_destroy(fun); 108 return rc; 109 } 110 111 rc = ddf_fun_bind(fun); 112 if (rc != EOK) { 113 ddf_msg(LVL_ERROR, "Failed binding function %s: %s", name, 114 str_error(rc)); 115 ddf_fun_destroy(fun); 116 return rc; 117 } 118 119 return EOK; 120 } 121 122 /** Create the function which represents the root of HW device tree. 123 * 124 * @param dev Device 125 * @return EOK on success or negative error code 126 */ 127 static int add_platform_fun(ddf_dev_t *dev) 128 { 129 char *match_id; 130 char *platform; 131 size_t platform_size; 132 133 const char *name = PLATFORM_FUN_NAME; 134 ddf_fun_t *fun; 135 int rc; 136 137 /* Get platform name from sysinfo. */ 138 platform = sysinfo_get_data("platform", &platform_size); 139 if (platform == NULL) { 140 ddf_msg(LVL_ERROR, "Failed to obtain platform name."); 141 return ENOENT; 142 } 143 144 /* Null-terminate string. */ 145 platform = realloc(platform, platform_size + 1); 146 if (platform == NULL) { 147 ddf_msg(LVL_ERROR, "Memory allocation failed."); 148 return ENOMEM; 149 } 150 151 platform[platform_size] = '\0'; 152 153 /* Construct match ID. */ 154 if (asprintf(&match_id, PLATFORM_FUN_MATCH_ID_FMT, platform) == -1) { 155 ddf_msg(LVL_ERROR, "Memory allocation failed."); 156 return ENOMEM; 157 } 158 159 /* Add function. */ 160 ddf_msg(LVL_DEBUG, "Adding platform function. Function node is `%s' " 161 " (%d %s)", PLATFORM_FUN_NAME, PLATFORM_FUN_MATCH_SCORE, 162 match_id); 163 164 fun = ddf_fun_create(dev, fun_inner, name); 165 if (fun == NULL) { 166 ddf_msg(LVL_ERROR, "Error creating function %s", name); 167 return ENOMEM; 168 } 169 170 rc = ddf_fun_add_match_id(fun, match_id, PLATFORM_FUN_MATCH_SCORE); 171 if (rc != EOK) { 172 ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s", 173 name); 174 ddf_fun_destroy(fun); 175 return rc; 176 } 177 178 rc = ddf_fun_bind(fun); 179 if (rc != EOK) { 180 ddf_msg(LVL_ERROR, "Failed binding function %s: %s", name, 181 str_error(rc)); 182 ddf_fun_destroy(fun); 183 return rc; 184 } 185 186 return EOK; 119 187 } 120 188 … … 124 192 * of HW and pseudo devices). 125 193 */ 126 static int root_add_device(device_t *dev) 127 { 128 printf(NAME ": root_add_device, device handle = %d\n", dev->handle); 129 194 static int root_add_device(ddf_dev_t *dev) 195 { 196 ddf_msg(LVL_DEBUG, "root_add_device, device handle=%" PRIun, 197 dev->handle); 198 199 /* 200 * Register virtual devices root. 201 * We ignore error occurrence because virtual devices shall not be 202 * vital for the system. 203 */ 204 add_virtual_root_fun(dev); 205 130 206 /* Register root device's children. */ 131 int res = add_platform_ child(dev);207 int res = add_platform_fun(dev); 132 208 if (EOK != res) 133 printf(NAME ": failed to add child device for platform.\n");134 209 ddf_msg(LVL_ERROR, "Failed adding child device for platform."); 210 135 211 return res; 136 212 } … … 139 215 { 140 216 printf(NAME ": HelenOS root device driver\n"); 141 return driver_main(&root_driver); 217 218 ddf_log_init(NAME, LVL_ERROR); 219 return ddf_driver_main(&root_driver); 142 220 } 143 221 -
uspace/drv/rootpc/Makefile
r9e2e715 reb522e8 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include 32 BINARY = root ia3232 BINARY = rootpc 33 33 34 34 SOURCES = \ 35 root ia32.c35 rootpc.c 36 36 37 37 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/rootpc/rootpc.c
r9e2e715 reb522e8 28 28 29 29 /** 30 * @defgroup root_ ia32 Root HW device driver for ia32 platform.31 * @brief HelenOS root HW device driver for ia32 platform.30 * @defgroup root_pc PC platform driver. 31 * @brief HelenOS PC platform driver. 32 32 * @{ 33 33 */ … … 46 46 #include <macros.h> 47 47 48 #include <driver.h> 48 #include <ddf/driver.h> 49 #include <ddf/log.h> 49 50 #include <devman.h> 50 51 #include <ipc/devman.h> 51 52 #include <ipc/dev_iface.h> 52 #include < resource.h>53 #include <ops/hw_res.h> 53 54 #include <device/hw_res.h> 54 55 55 #define NAME "rootia32" 56 57 typedef struct rootia32_child_dev_data { 56 #define NAME "rootpc" 57 58 /** Obtain function soft-state from DDF function node */ 59 #define ROOTPC_FUN(fnode) ((rootpc_fun_t *) (fnode)->driver_data) 60 61 typedef struct rootpc_fun { 58 62 hw_resource_list_t hw_resources; 59 } root ia32_child_dev_data_t;60 61 static int root ia32_add_device(device_t *dev);62 static void root_ ia32_init(void);63 } rootpc_fun_t; 64 65 static int rootpc_add_device(ddf_dev_t *dev); 66 static void root_pc_init(void); 63 67 64 68 /** The root device driver's standard operations. */ 65 static driver_ops_t root ia32_ops = {66 .add_device = &root ia32_add_device69 static driver_ops_t rootpc_ops = { 70 .add_device = &rootpc_add_device 67 71 }; 68 72 69 73 /** The root device driver structure. */ 70 static driver_t root ia32_driver = {74 static driver_t rootpc_driver = { 71 75 .name = NAME, 72 .driver_ops = &root ia32_ops76 .driver_ops = &rootpc_ops 73 77 }; 74 78 … … 82 86 }; 83 87 84 static root ia32_child_dev_data_t pci_data = {88 static rootpc_fun_t pci_data = { 85 89 .hw_resources = { 86 90 1, … … 89 93 }; 90 94 91 static hw_resource_list_t *rootia32_get_child_resources(device_t *dev) 92 { 93 rootia32_child_dev_data_t *data; 94 95 data = (rootia32_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 rootia32_enable_child_interrupt(device_t *dev) 95 static hw_resource_list_t *rootpc_get_resources(ddf_fun_t *fnode) 96 { 97 rootpc_fun_t *fun = ROOTPC_FUN(fnode); 98 99 assert(fun != NULL); 100 return &fun->hw_resources; 101 } 102 103 static bool rootpc_enable_interrupt(ddf_fun_t *fun) 103 104 { 104 105 /* TODO */ … … 107 108 } 108 109 109 static resource_iface_t child_res_iface= {110 &root ia32_get_child_resources,111 &root ia32_enable_child_interrupt112 }; 113 114 /* Initialized in root_ ia32_init() function. */115 static d evice_ops_t rootia32_child_ops;110 static hw_res_ops_t fun_hw_res_ops = { 111 &rootpc_get_resources, 112 &rootpc_enable_interrupt 113 }; 114 115 /* Initialized in root_pc_init() function. */ 116 static ddf_dev_ops_t rootpc_fun_ops; 116 117 117 118 static bool 118 root ia32_add_child(device_t *parent, const char *name, const char *str_match_id,119 root ia32_child_dev_data_t *drv_data)120 { 121 printf(NAME ": adding new child device '%s'.\n", name);122 123 d evice_t *child= NULL;119 rootpc_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id, 120 rootpc_fun_t *fun) 121 { 122 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name); 123 124 ddf_fun_t *fnode = NULL; 124 125 match_id_t *match_id = NULL; 125 126 126 127 /* Create new device. */ 127 child = create_device();128 if ( NULL == child)128 fnode = ddf_fun_create(dev, fun_inner, name); 129 if (fnode == NULL) 129 130 goto failure; 130 131 131 child->name = name; 132 child->driver_data = drv_data; 132 fnode->driver_data = fun; 133 133 134 134 /* Initialize match id list */ 135 135 match_id = create_match_id(); 136 if ( NULL == match_id)136 if (match_id == NULL) 137 137 goto failure; 138 138 139 139 match_id->id = str_match_id; 140 140 match_id->score = 100; 141 add_match_id(& child->match_ids, match_id);141 add_match_id(&fnode->match_ids, match_id); 142 142 143 143 /* Set provided operations to the device. */ 144 child->ops = &rootia32_child_ops; 145 146 /* Register child device. */ 147 if (EOK != child_device_register(child, parent)) 144 fnode->ops = &rootpc_fun_ops; 145 146 /* Register function. */ 147 if (ddf_fun_bind(fnode) != EOK) { 148 ddf_msg(LVL_ERROR, "Failed binding function %s.", name); 148 149 goto failure; 150 } 149 151 150 152 return true; 151 153 152 154 failure: 153 if ( NULL != match_id)155 if (match_id != NULL) 154 156 match_id->id = NULL; 155 157 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); 158 if (fnode != NULL) 159 ddf_fun_destroy(fnode); 160 161 ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name); 162 162 163 163 return false; 164 164 } 165 165 166 static bool root ia32_add_children(device_t *dev)167 { 168 return root ia32_add_child(dev, "pci0", "intel_pci", &pci_data);166 static bool rootpc_add_functions(ddf_dev_t *dev) 167 { 168 return rootpc_add_fun(dev, "pci0", "intel_pci", &pci_data); 169 169 } 170 170 … … 175 175 * @return Zero on success, negative error number otherwise. 176 176 */ 177 static int root ia32_add_device(device_t *dev)178 { 179 printf(NAME ": rootia32_add_device, device handle = %d\n", dev->handle);180 181 /* Register child devices. */182 if (!rootia32_add_children(dev)) {183 printf(NAME ": failed to add child devices for platform "184 "ia32.\n");177 static int rootpc_add_device(ddf_dev_t *dev) 178 { 179 ddf_msg(LVL_DEBUG, "rootpc_add_device, device handle = %d", 180 (int)dev->handle); 181 182 /* Register functions. */ 183 if (!rootpc_add_functions(dev)) { 184 ddf_msg(LVL_ERROR, "Failed to add functions for PC platform."); 185 185 } 186 186 … … 188 188 } 189 189 190 static void root_ia32_init(void) 191 { 192 rootia32_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_res_iface; 190 static void root_pc_init(void) 191 { 192 ddf_log_init(NAME, LVL_ERROR); 193 rootpc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops; 193 194 } 194 195 195 196 int main(int argc, char *argv[]) 196 197 { 197 printf(NAME ": HelenOS rootia32 devicedriver\n");198 root_ ia32_init();199 return d river_main(&rootia32_driver);198 printf(NAME ": HelenOS PC platform driver\n"); 199 root_pc_init(); 200 return ddf_driver_main(&rootpc_driver); 200 201 } 201 202 -
uspace/drv/test1/char.c
r9e2e715 reb522e8 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2010 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libpacket30 * @{31 */32 33 29 /** @file 34 30 */ 35 31 36 #ifndef LIBPACKET_PACKET_LOCAL_H_ 37 #define LIBPACKET_PACKET_LOCAL_H_ 32 #include <assert.h> 33 #include <errno.h> 34 #include <mem.h> 35 #include <ops/char_dev.h> 38 36 39 #include <net/packet.h>37 #include "test1.h" 40 38 41 /** @name Packet local interface 42 */ 43 /*@{*/ 39 static int impl_char_read(ddf_fun_t *fun, char *buf, size_t count) { 40 memset(buf, 0, count); 41 return count; 42 } 44 43 45 extern int packet_translate_local(int, packet_ref, packet_id_t); 46 extern packet_t packet_get_4_local(int, size_t, size_t, size_t, size_t); 47 extern packet_t packet_get_1_local(int, size_t); 48 extern void pq_release_local(int, packet_id_t); 44 static int imp_char_write(ddf_fun_t *fun, char *buf, size_t count) { 45 return count; 46 } 49 47 50 /*@}*/ 48 static char_dev_ops_t char_dev_ops = { 49 .read = &impl_char_read, 50 .write = &imp_char_write 51 }; 51 52 52 #endif 53 ddf_dev_ops_t char_device_ops = { 54 .interfaces[CHAR_DEV_IFACE] = &char_dev_ops 55 }; 53 56 54 /** @}55 */ -
uspace/drv/uhci-hcd/transfer_list.h
r9e2e715 reb522e8 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2011 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 /** @addtogroup net 28 /** @addtogroup drvusbuhcihc 30 29 * @{ 31 30 */ 31 /** @file 32 * @brief UHCI driver transfer list structure 33 */ 34 #ifndef DRV_UHCI_TRANSFER_LIST_H 35 #define DRV_UHCI_TRANSFER_LIST_H 32 36 33 /** @file 34 * Start the networking subsystem. 37 #include <fibril_synch.h> 38 #include <usb/host/batch.h> 39 40 #include "hw_struct/queue_head.h" 41 42 /** Structure maintaining both hw queue and software list 43 * of currently executed transfers 35 44 */ 45 typedef struct transfer_list { 46 /** Guard against multiple add/remove races */ 47 fibril_mutex_t guard; 48 /** UHCI hw structure represeting this queue */ 49 qh_t *queue_head; 50 /** Assigned name, for nicer debug output */ 51 const char *name; 52 /** List of all batches in this list */ 53 link_t batch_list; 54 } transfer_list_t; 36 55 37 #define NAME "netstart" 38 39 #include <async.h> 40 #include <stdio.h> 41 #include <task.h> 42 #include <str_error.h> 43 #include <ipc/ipc.h> 44 #include <ipc/services.h> 45 #include <ipc/net_net.h> 46 47 #include <net/modules.h> 48 49 /** Start a module. 50 * 51 * @param[in] desc The module description 52 * @param[in] path The module absolute path. 53 * @returns True on succesful spanwning. 54 * @returns False on failure 56 void transfer_list_fini(transfer_list_t *instance); 57 int transfer_list_init(transfer_list_t *instance, const char *name); 58 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next); 59 void transfer_list_add_batch( 60 transfer_list_t *instance, usb_transfer_batch_t *batch); 61 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done); 62 void transfer_list_abort_all(transfer_list_t *instance); 63 #endif 64 /** 65 * @} 55 66 */ 56 static bool spawn(const char *desc, const char *path)57 {58 int rc;59 60 printf("%s: Spawning %s (%s)\n", NAME, desc, path);61 rc = task_spawnl(NULL, path, path, NULL);62 if (rc != EOK) {63 fprintf(stderr, "%s: Error spawning %s (%s)\n", NAME, path,64 str_error(rc));65 return false;66 }67 68 return true;69 }70 71 int main(int argc, char *argv[])72 {73 int rc;74 75 if (!spawn("networking service", "/srv/net"))76 return EINVAL;77 78 printf("%s: Initializing networking\n", NAME);79 80 int net_phone = connect_to_service(SERVICE_NETWORKING);81 rc = ipc_call_sync_0_0(net_phone, NET_NET_STARTUP);82 if (rc != EOK) {83 fprintf(stderr, "%s: Startup error %d\n", NAME, rc);84 return rc;85 }86 87 return EOK;88 }89 90 /** @}91 */ -
uspace/drv/usbhid/subdrivers.c
r9e2e715 reb522e8 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2011 Lubos Slovak 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libnet29 /** @addtogroup drvusbhid 30 30 * @{ 31 31 */ 32 /** @file 33 * USB HID subdriver mappings. 34 */ 32 35 33 #ifndef LIBNET_NETIF_INTERFACE_H_ 34 #define LIBNET_NETIF_INTERFACE_H_ 36 #include "subdrivers.h" 37 #include <usb/hid/usages/core.h> 38 #include <usb/hid/hidpath.h> 35 39 36 #include <netif_remote.h> 37 #include <packet_client.h> 40 #include "multimedia/multimedia.h" 41 #include "mouse/mousedev.h" 42 #include "generic/hiddev.h" 38 43 39 #define netif_module_message netif_module_message_standalone 40 #define netif_module_start netif_module_start_standalone 41 #define netif_get_addr_req netif_get_addr_req_remote 42 #define netif_probe_req netif_probe_req_remote 43 #define netif_send_msg netif_send_msg_remote 44 #define netif_start_req netif_start_req_remote 45 #define netif_stop_req netif_stop_req_remote 46 #define netif_stats_req netif_stats_req_remote 47 #define netif_bind_service netif_bind_service_remote 44 static usb_hid_subdriver_usage_t path_kbd[] = { 45 {USB_HIDUT_PAGE_GENERIC_DESKTOP, 46 USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 47 {0, 0} 48 }; 48 49 49 #endif 50 static usb_hid_subdriver_usage_t path_mouse[] = { 51 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE}, 52 {0, 0} 53 }; 50 54 51 /** @} 55 static usb_hid_subdriver_usage_t multim_key_path[] = { 56 {USB_HIDUT_PAGE_CONSUMER, USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL}, 57 {0, 0} 58 }; 59 60 const usb_hid_subdriver_mapping_t usb_hid_subdrivers[] = { 61 { 62 path_kbd, 63 0, 64 USB_HID_PATH_COMPARE_BEGIN, 65 -1, 66 -1, 67 { 68 .init = usb_kbd_init, 69 .deinit = usb_kbd_deinit, 70 .poll = usb_kbd_polling_callback, 71 .poll_end = NULL 72 }, 73 74 }, 75 { 76 multim_key_path, 77 1, 78 USB_HID_PATH_COMPARE_BEGIN, 79 -1, 80 -1, 81 { 82 .init = usb_multimedia_init, 83 .deinit = usb_multimedia_deinit, 84 .poll = usb_multimedia_polling_callback, 85 .poll_end = NULL 86 } 87 }, 88 { 89 path_mouse, 90 0, 91 USB_HID_PATH_COMPARE_BEGIN, 92 -1, 93 -1, 94 { 95 .init = usb_mouse_init, 96 .deinit = usb_mouse_deinit, 97 .poll = usb_mouse_polling_callback, 98 .poll_end = NULL 99 } 100 }, 101 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}} 102 }; 103 104 /** 105 * @} 52 106 */ -
uspace/drv/usbhub/main.c
r9e2e715 reb522e8 1 1 /* 2 * Copyright (c) 20 08 Lukas Mejdrech2 * Copyright (c) 2010 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup icmp29 /** @addtogroup drvusbhub 30 30 * @{ 31 31 */ 32 32 33 /** @file 34 * ICMP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 33 #include <ddf/driver.h> 34 #include <errno.h> 35 #include <async.h> 36 #include <stdio.h> 37 38 #include <usb/dev/driver.h> 39 #include <usb/classes/classes.h> 40 41 #include "usbhub.h" 42 #include "usbhub_private.h" 43 44 /** Hub status-change endpoint description. 45 * 46 * For more information see section 11.15.1 of USB 1.1 specification. 47 */ 48 static usb_endpoint_description_t hub_status_change_endpoint_description = { 49 .transfer_type = USB_TRANSFER_INTERRUPT, 50 .direction = USB_DIRECTION_IN, 51 .interface_class = USB_CLASS_HUB, 52 .interface_subclass = 0, 53 .interface_protocol = 0, 54 .flags = 0 55 }; 56 57 /** 58 * usb hub driver operations 59 * 60 * The most important one is add_device, which is set to usb_hub_add_device. 61 */ 62 static usb_driver_ops_t usb_hub_driver_ops = { 63 .add_device = usb_hub_add_device 64 }; 65 66 /** 67 * hub endpoints, excluding control endpoint 68 */ 69 static usb_endpoint_description_t *usb_hub_endpoints[] = { 70 &hub_status_change_endpoint_description, 71 NULL 72 }; 73 74 /** 75 * static usb hub driver information 76 */ 77 static usb_driver_t usb_hub_driver = { 78 .name = NAME, 79 .ops = &usb_hub_driver_ops, 80 .endpoints = usb_hub_endpoints 81 }; 82 83 84 int main(int argc, char *argv[]) 85 { 86 printf(NAME ": HelenOS USB hub driver.\n"); 87 88 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 89 90 return usb_driver_main(&usb_hub_driver); 91 } 92 93 /** 94 * @} 38 95 */ 39 96 40 #include "icmp.h"41 #include "icmp_module.h"42 43 #include <async.h>44 #include <stdio.h>45 #include <errno.h>46 #include <ipc/ipc.h>47 #include <ipc/services.h>48 49 #include <net/modules.h>50 #include <net/packet.h>51 #include <net_interface.h>52 53 #include <tl_local.h>54 55 /** ICMP module global data. */56 extern icmp_globals_t icmp_globals;57 58 int tl_module_start_standalone(async_client_conn_t client_connection)59 {60 ipcarg_t phonehash;61 int rc;62 63 async_set_client_connection(client_connection);64 icmp_globals.net_phone = net_connect_module();65 if (icmp_globals.net_phone < 0)66 return icmp_globals.net_phone;67 68 rc = pm_init();69 if (rc != EOK)70 return rc;71 72 rc = icmp_initialize(client_connection);73 if (rc != EOK)74 goto out;75 76 rc = REGISTER_ME(SERVICE_ICMP, &phonehash);77 if (rc != EOK)78 goto out;79 80 async_manager();81 82 out:83 pm_destroy();84 return rc;85 }86 87 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,88 ipc_call_t *answer, int *answer_count)89 {90 return icmp_message_standalone(callid, call, answer, answer_count);91 }92 93 /** @}94 */
Note:
See TracChangeset
for help on using the changeset viewer.
