Changeset b0f00a9 in mainline for uspace/drv
- Timestamp:
- 2011-11-06T22:21:05Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 898e847
- Parents:
- 2bdf8313 (diff), 7b5f4c9 (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:
-
- 135 added
- 1 deleted
- 35 moved
-
bus/isa/Makefile (moved) (moved from uspace/drv/isa/Makefile ) (1 diff)
-
bus/isa/isa.c (moved) (moved from uspace/drv/isa/isa.c ) (11 diffs)
-
bus/isa/isa.dev (moved) (moved from uspace/drv/isa/isa.dev )
-
bus/isa/isa.ma (moved) (moved from uspace/drv/isa/isa.ma )
-
bus/pci/pciintel/Makefile (moved) (moved from uspace/drv/pciintel/Makefile ) (1 diff)
-
bus/pci/pciintel/pci.c (moved) (moved from uspace/drv/pciintel/pci.c ) (20 diffs)
-
bus/pci/pciintel/pci.h (moved) (moved from uspace/drv/pciintel/pci.h ) (1 diff)
-
bus/pci/pciintel/pci_regs.h (moved) (moved from uspace/drv/pciintel/pci_regs.h )
-
bus/pci/pciintel/pciintel.ma (moved) (moved from uspace/drv/pciintel/pciintel.ma )
-
bus/usb/ehci/Makefile (added)
-
bus/usb/ehci/ehci.h (moved) (moved from uspace/lib/c/include/ipc/mouse.h ) (2 diffs)
-
bus/usb/ehci/ehci.ma (added)
-
bus/usb/ehci/hc_iface.c (added)
-
bus/usb/ehci/main.c (added)
-
bus/usb/ehci/pci.c (added)
-
bus/usb/ehci/pci.h (added)
-
bus/usb/ohci/Makefile (added)
-
bus/usb/ohci/endpoint_list.c (added)
-
bus/usb/ohci/endpoint_list.h (added)
-
bus/usb/ohci/hc.c (added)
-
bus/usb/ohci/hc.h (added)
-
bus/usb/ohci/hw_struct/completion_codes.h (added)
-
bus/usb/ohci/hw_struct/endpoint_descriptor.c (added)
-
bus/usb/ohci/hw_struct/endpoint_descriptor.h (added)
-
bus/usb/ohci/hw_struct/hcca.h (added)
-
bus/usb/ohci/hw_struct/iso_transfer_descriptor.h (added)
-
bus/usb/ohci/hw_struct/transfer_descriptor.c (added)
-
bus/usb/ohci/hw_struct/transfer_descriptor.h (added)
-
bus/usb/ohci/main.c (added)
-
bus/usb/ohci/ohci.c (added)
-
bus/usb/ohci/ohci.h (added)
-
bus/usb/ohci/ohci.ma (added)
-
bus/usb/ohci/ohci_batch.c (added)
-
bus/usb/ohci/ohci_batch.h (added)
-
bus/usb/ohci/ohci_endpoint.c (added)
-
bus/usb/ohci/ohci_endpoint.h (added)
-
bus/usb/ohci/ohci_regs.h (added)
-
bus/usb/ohci/pci.c (added)
-
bus/usb/ohci/pci.h (added)
-
bus/usb/ohci/root_hub.c (added)
-
bus/usb/ohci/root_hub.h (added)
-
bus/usb/ohci/utils/malloc32.h (added)
-
bus/usb/uhci/Makefile (added)
-
bus/usb/uhci/hc.c (added)
-
bus/usb/uhci/hc.h (added)
-
bus/usb/uhci/hw_struct/link_pointer.h (added)
-
bus/usb/uhci/hw_struct/queue_head.h (added)
-
bus/usb/uhci/hw_struct/transfer_descriptor.c (added)
-
bus/usb/uhci/hw_struct/transfer_descriptor.h (added)
-
bus/usb/uhci/main.c (added)
-
bus/usb/uhci/pci.c (added)
-
bus/usb/uhci/pci.h (added)
-
bus/usb/uhci/root_hub.c (added)
-
bus/usb/uhci/root_hub.h (added)
-
bus/usb/uhci/transfer_list.c (added)
-
bus/usb/uhci/transfer_list.h (added)
-
bus/usb/uhci/uhci.c (added)
-
bus/usb/uhci/uhci.h (moved) (moved from uspace/srv/hid/char_mouse/include/char_mouse.h ) (2 diffs)
-
bus/usb/uhci/uhci.ma (added)
-
bus/usb/uhci/uhci_batch.c (added)
-
bus/usb/uhci/uhci_batch.h (added)
-
bus/usb/uhci/utils/malloc32.h (added)
-
bus/usb/uhcirh/Makefile (added)
-
bus/usb/uhcirh/main.c (added)
-
bus/usb/uhcirh/port.c (added)
-
bus/usb/uhcirh/port.h (added)
-
bus/usb/uhcirh/root_hub.c (added)
-
bus/usb/uhcirh/root_hub.h (added)
-
bus/usb/uhcirh/uhcirh.ma (added)
-
bus/usb/usbflbk/Makefile (added)
-
bus/usb/usbflbk/main.c (added)
-
bus/usb/usbflbk/usbflbk.ma (added)
-
bus/usb/usbhid/Makefile (added)
-
bus/usb/usbhid/generic/hiddev.c (added)
-
bus/usb/usbhid/generic/hiddev.h (added)
-
bus/usb/usbhid/kbd/conv.c (added)
-
bus/usb/usbhid/kbd/conv.h (added)
-
bus/usb/usbhid/kbd/kbddev.c (added)
-
bus/usb/usbhid/kbd/kbddev.h (added)
-
bus/usb/usbhid/kbd/kbdrepeat.c (added)
-
bus/usb/usbhid/kbd/kbdrepeat.h (added)
-
bus/usb/usbhid/main.c (added)
-
bus/usb/usbhid/mouse/mousedev.c (added)
-
bus/usb/usbhid/mouse/mousedev.h (added)
-
bus/usb/usbhid/multimedia/keymap.c (added)
-
bus/usb/usbhid/multimedia/keymap.h (added)
-
bus/usb/usbhid/multimedia/multimedia.c (added)
-
bus/usb/usbhid/multimedia/multimedia.h (added)
-
bus/usb/usbhid/subdrivers.c (added)
-
bus/usb/usbhid/subdrivers.h (added)
-
bus/usb/usbhid/usbhid.c (added)
-
bus/usb/usbhid/usbhid.h (added)
-
bus/usb/usbhid/usbhid.ma (added)
-
bus/usb/usbhub/Makefile (added)
-
bus/usb/usbhub/main.c (added)
-
bus/usb/usbhub/port.c (added)
-
bus/usb/usbhub/port.h (added)
-
bus/usb/usbhub/status.h (added)
-
bus/usb/usbhub/usbhub.c (added)
-
bus/usb/usbhub/usbhub.h (added)
-
bus/usb/usbhub/usbhub.ma (added)
-
bus/usb/usbmast/Makefile (moved) (moved from uspace/srv/hw/netif/ne2000/Makefile ) (2 diffs)
-
bus/usb/usbmast/bo_trans.c (added)
-
bus/usb/usbmast/bo_trans.h (added)
-
bus/usb/usbmast/cmdw.c (added)
-
bus/usb/usbmast/cmdw.h (added)
-
bus/usb/usbmast/main.c (added)
-
bus/usb/usbmast/scsi_ms.c (added)
-
bus/usb/usbmast/scsi_ms.h (added)
-
bus/usb/usbmast/usbmast.h (added)
-
bus/usb/usbmast/usbmast.ma (added)
-
bus/usb/usbmid/Makefile (added)
-
bus/usb/usbmid/dump.c (added)
-
bus/usb/usbmid/explore.c (added)
-
bus/usb/usbmid/main.c (added)
-
bus/usb/usbmid/usbmid.c (added)
-
bus/usb/usbmid/usbmid.h (added)
-
bus/usb/usbmid/usbmid.ma (added)
-
bus/usb/vhc/Makefile (added)
-
bus/usb/vhc/conn.h (added)
-
bus/usb/vhc/conndev.c (added)
-
bus/usb/vhc/connhost.c (added)
-
bus/usb/vhc/devconn.c (added)
-
bus/usb/vhc/hub.c (added)
-
bus/usb/vhc/hub.h (added)
-
bus/usb/vhc/hub/hub.c (added)
-
bus/usb/vhc/hub/hub.h (added)
-
bus/usb/vhc/hub/virthub.c (added)
-
bus/usb/vhc/hub/virthub.h (added)
-
bus/usb/vhc/hub/virthubops.c (added)
-
bus/usb/vhc/main.c (added)
-
bus/usb/vhc/transfer.c (added)
-
bus/usb/vhc/vhc.ma (added)
-
bus/usb/vhc/vhcd.h (added)
-
char/ns8250/Makefile (moved) (moved from uspace/drv/ns8250/Makefile ) (1 diff)
-
char/ns8250/cyclic_buffer.h (moved) (moved from uspace/drv/ns8250/cyclic_buffer.h )
-
char/ns8250/ns8250.c (moved) (moved from uspace/drv/ns8250/ns8250.c ) (12 diffs)
-
char/ns8250/ns8250.ma (moved) (moved from uspace/drv/ns8250/ns8250.ma )
-
infrastructure/root/Makefile (moved) (moved from uspace/drv/root/Makefile ) (1 diff)
-
infrastructure/root/root.c (moved) (moved from uspace/drv/root/root.c ) (3 diffs)
-
infrastructure/root/root.ma (moved) (moved from uspace/drv/root/root.ma )
-
infrastructure/rootmac/Makefile (added)
-
infrastructure/rootmac/rootmac.c (added)
-
infrastructure/rootmac/rootmac.ma (added)
-
infrastructure/rootpc/Makefile (moved) (moved from uspace/drv/rootpc/Makefile ) (1 diff)
-
infrastructure/rootpc/rootpc.c (moved) (moved from uspace/drv/rootpc/rootpc.c )
-
infrastructure/rootpc/rootpc.ma (moved) (moved from uspace/drv/rootpc/rootpc.ma )
-
infrastructure/rootvirt/Makefile (moved) (moved from uspace/drv/rootvirt/Makefile ) (1 diff)
-
infrastructure/rootvirt/devices.def (moved) (moved from uspace/drv/rootvirt/devices.def ) (2 diffs)
-
infrastructure/rootvirt/rootvirt.c (moved) (moved from uspace/drv/rootvirt/rootvirt.c ) (6 diffs)
-
infrastructure/rootvirt/rootvirt.ma (moved) (moved from uspace/drv/rootvirt/rootvirt.ma )
-
nic/lo/Makefile (added)
-
nic/lo/lo.c (added)
-
nic/lo/lo.ma (added)
-
nic/ne2k/Makefile (added)
-
nic/ne2k/dp8390.c (moved) (moved from uspace/srv/hw/netif/ne2000/dp8390.c ) (20 diffs)
-
nic/ne2k/dp8390.h (moved) (moved from uspace/srv/hw/netif/ne2000/dp8390.h ) (6 diffs)
-
nic/ne2k/ne2k.c (added)
-
nic/ne2k/ne2k.ma (added)
-
test/test1/Makefile (moved) (moved from uspace/drv/test1/Makefile ) (1 diff)
-
test/test1/char.c (moved) (moved from uspace/drv/test1/char.c )
-
test/test1/test1.c (moved) (moved from uspace/drv/test1/test1.c ) (9 diffs)
-
test/test1/test1.h (moved) (moved from uspace/drv/test1/test1.h )
-
test/test1/test1.ma (moved) (moved from uspace/drv/test1/test1.ma )
-
test/test2/Makefile (moved) (moved from uspace/drv/test2/Makefile ) (1 diff)
-
test/test2/test2.c (added)
-
test/test2/test2.ma (moved) (moved from uspace/drv/test2/test2.ma )
-
test/test3/Makefile (added)
-
test/test3/test3.c (added)
-
test/test3/test3.ma (added)
-
test2/test2.c (deleted)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -
uspace/drv/bus/isa/isa.c
r2bdf8313 rb0f00a9 37 37 */ 38 38 39 #include <adt/list.h> 39 40 #include <assert.h> 40 41 #include <stdio.h> … … 63 64 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev" 64 65 65 /** Obtain soft-state pointer from function node pointer */ 66 #define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data)) 66 /** Obtain soft-state from device node */ 67 #define ISA_BUS(dev) ((isa_bus_t *) ((dev)->driver_data)) 68 69 /** Obtain soft-state from function node */ 70 #define ISA_FUN(fun) ((isa_fun_t *) ((fun)->driver_data)) 67 71 68 72 #define ISA_MAX_HW_RES 4 69 73 74 typedef struct { 75 fibril_mutex_t mutex; 76 ddf_dev_t *dev; 77 ddf_fun_t *fctl; 78 list_t functions; 79 } isa_bus_t; 80 70 81 typedef struct isa_fun { 82 fibril_mutex_t mutex; 71 83 ddf_fun_t *fnode; 72 84 hw_resource_list_t hw_resources; 85 link_t bus_link; 73 86 } isa_fun_t; 74 87 … … 96 109 97 110 static int isa_add_device(ddf_dev_t *dev); 111 static int isa_dev_remove(ddf_dev_t *dev); 112 static int isa_fun_online(ddf_fun_t *fun); 113 static int isa_fun_offline(ddf_fun_t *fun); 98 114 99 115 /** The isa device driver's standard operations */ 100 116 static driver_ops_t isa_ops = { 101 .add_device = &isa_add_device 117 .add_device = &isa_add_device, 118 .dev_remove = &isa_dev_remove, 119 .fun_online = &isa_fun_online, 120 .fun_offline = &isa_fun_offline 102 121 }; 103 122 … … 108 127 }; 109 128 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)); 129 static isa_fun_t *isa_fun_create(isa_bus_t *isa, const char *name) 130 { 131 ddf_fun_t *fnode = ddf_fun_create(isa->dev, fun_inner, name); 132 if (fnode == NULL) 133 return NULL; 134 135 isa_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(isa_fun_t)); 113 136 if (fun == NULL) 114 137 return NULL; 115 138 116 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name); 117 if (fnode == NULL) { 118 free(fun); 119 return NULL; 120 } 121 139 fibril_mutex_initialize(&fun->mutex); 122 140 fun->fnode = fnode; 123 fnode->driver_data = fun;124 141 return fun; 125 142 } … … 352 369 str_error(rc)); 353 370 } 371 372 free(id); 354 373 } 355 374 … … 386 405 static void fun_hw_res_alloc(isa_fun_t *fun) 387 406 { 388 fun->hw_resources.resources = 407 fun->hw_resources.resources = 389 408 (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES); 390 409 } 391 410 392 static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev) 411 static void fun_hw_res_free(isa_fun_t *fun) 412 { 413 free(fun->hw_resources.resources); 414 fun->hw_resources.resources = NULL; 415 } 416 417 static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa) 393 418 { 394 419 char *line; … … 413 438 return NULL; 414 439 415 isa_fun_t *fun = isa_fun_create( dev, fun_name);440 isa_fun_t *fun = isa_fun_create(isa, fun_name); 416 441 if (fun == NULL) { 417 442 free(fun_name); … … 446 471 (void) ddf_fun_bind(fun->fnode); 447 472 473 list_append(&fun->bus_link, &isa->functions); 474 448 475 return fun_conf; 449 476 } 450 477 451 static void fun_conf_parse(char *conf, ddf_dev_t *dev)478 static void fun_conf_parse(char *conf, isa_bus_t *isa) 452 479 { 453 480 while (conf != NULL && *conf != '\0') { 454 conf = isa_fun_read_info(conf, dev);455 } 456 } 457 458 static void isa_functions_add( ddf_dev_t *dev)481 conf = isa_fun_read_info(conf, isa); 482 } 483 } 484 485 static void isa_functions_add(isa_bus_t *isa) 459 486 { 460 487 char *fun_conf; … … 462 489 fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH); 463 490 if (fun_conf != NULL) { 464 fun_conf_parse(fun_conf, dev);491 fun_conf_parse(fun_conf, isa); 465 492 free(fun_conf); 466 493 } … … 469 496 static int isa_add_device(ddf_dev_t *dev) 470 497 { 498 isa_bus_t *isa; 499 471 500 ddf_msg(LVL_DEBUG, "isa_add_device, device handle = %d", 472 501 (int) dev->handle); 473 502 503 isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t)); 504 if (isa == NULL) 505 return ENOMEM; 506 507 fibril_mutex_initialize(&isa->mutex); 508 isa->dev = dev; 509 list_initialize(&isa->functions); 510 474 511 /* Make the bus device more visible. Does not do anything. */ 475 512 ddf_msg(LVL_DEBUG, "Adding a 'ctl' function"); 476 513 477 ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl"); 478 if (ctl == NULL) { 514 fibril_mutex_lock(&isa->mutex); 515 516 isa->fctl = ddf_fun_create(dev, fun_exposed, "ctl"); 517 if (isa->fctl == NULL) { 479 518 ddf_msg(LVL_ERROR, "Failed creating control function."); 480 519 return EXDEV; 481 520 } 482 521 483 if (ddf_fun_bind(ctl) != EOK) { 522 if (ddf_fun_bind(isa->fctl) != EOK) { 523 ddf_fun_destroy(isa->fctl); 484 524 ddf_msg(LVL_ERROR, "Failed binding control function."); 485 525 return EXDEV; … … 487 527 488 528 /* Add functions as specified in the configuration file. */ 489 isa_functions_add( dev);529 isa_functions_add(isa); 490 530 ddf_msg(LVL_NOTE, "Finished enumerating legacy functions"); 491 531 532 fibril_mutex_unlock(&isa->mutex); 533 492 534 return EOK; 493 535 } 536 537 static int isa_dev_remove(ddf_dev_t *dev) 538 { 539 isa_bus_t *isa = ISA_BUS(dev); 540 int rc; 541 542 fibril_mutex_lock(&isa->mutex); 543 544 while (!list_empty(&isa->functions)) { 545 isa_fun_t *fun = list_get_instance(list_first(&isa->functions), 546 isa_fun_t, bus_link); 547 548 rc = ddf_fun_offline(fun->fnode); 549 if (rc != EOK) { 550 fibril_mutex_unlock(&isa->mutex); 551 ddf_msg(LVL_ERROR, "Failed offlining %s", fun->fnode->name); 552 return rc; 553 } 554 555 rc = ddf_fun_unbind(fun->fnode); 556 if (rc != EOK) { 557 fibril_mutex_unlock(&isa->mutex); 558 ddf_msg(LVL_ERROR, "Failed unbinding %s", fun->fnode->name); 559 return rc; 560 } 561 562 list_remove(&fun->bus_link); 563 564 fun_hw_res_free(fun); 565 ddf_fun_destroy(fun->fnode); 566 } 567 568 if (ddf_fun_unbind(isa->fctl) != EOK) { 569 fibril_mutex_unlock(&isa->mutex); 570 ddf_msg(LVL_ERROR, "Failed unbinding control function."); 571 return EXDEV; 572 } 573 574 fibril_mutex_unlock(&isa->mutex); 575 576 return EOK; 577 } 578 579 static int isa_fun_online(ddf_fun_t *fun) 580 { 581 ddf_msg(LVL_DEBUG, "isa_fun_online()"); 582 return ddf_fun_online(fun); 583 } 584 585 static int isa_fun_offline(ddf_fun_t *fun) 586 { 587 ddf_msg(LVL_DEBUG, "isa_fun_offline()"); 588 return ddf_fun_offline(fun); 589 } 590 494 591 495 592 static void isa_init() -
uspace/drv/bus/pci/pciintel/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -
uspace/drv/bus/pci/pciintel/pci.c
r2bdf8313 rb0f00a9 52 52 #include <ipc/devman.h> 53 53 #include <ipc/dev_iface.h> 54 #include <ipc/irc.h> 55 #include <ns.h> 56 #include <ipc/services.h> 57 #include <sysinfo.h> 54 58 #include <ops/hw_res.h> 55 59 #include <device/hw_res.h> 56 60 #include <ddi.h> 57 61 #include <libarch/ddi.h> 62 #include <pci_dev_iface.h> 58 63 59 64 #include "pci.h" … … 72 77 /** Obtain PCI bus soft-state from function soft-state */ 73 78 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 79 80 /** Max is 47, align to something nice. */ 81 #define ID_MAX_STR_LEN 50 74 82 75 83 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) … … 84 92 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 85 93 { 86 /* TODO */ 87 88 return false; 94 /* This is an old ugly way, copied from ne2000 driver */ 95 assert(fnode); 96 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data; 97 98 sysarg_t apic; 99 sysarg_t i8259; 100 101 async_sess_t *irc_sess = NULL; 102 103 if (((sysinfo_get_value("apic", &apic) == EOK) && (apic)) 104 || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) { 105 irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 106 SERVICE_IRC, 0, 0); 107 } 108 109 if (!irc_sess) 110 return false; 111 112 size_t i = 0; 113 hw_resource_list_t *res = &dev_data->hw_resources; 114 for (; i < res->count; i++) { 115 if (res->resources[i].type == INTERRUPT) { 116 const int irq = res->resources[i].res.interrupt.irq; 117 118 async_exch_t *exch = async_exchange_begin(irc_sess); 119 const int rc = 120 async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq); 121 async_exchange_end(exch); 122 123 if (rc != EOK) { 124 async_hangup(irc_sess); 125 return false; 126 } 127 } 128 } 129 130 async_hangup(irc_sess); 131 return true; 132 } 133 134 static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address, 135 uint32_t data) 136 { 137 if (address > 252) 138 return EINVAL; 139 pci_conf_write_32(PCI_FUN(fun), address, data); 140 return EOK; 141 } 142 143 static int pci_config_space_write_16( 144 ddf_fun_t *fun, uint32_t address, uint16_t data) 145 { 146 if (address > 254) 147 return EINVAL; 148 pci_conf_write_16(PCI_FUN(fun), address, data); 149 return EOK; 150 } 151 152 static int pci_config_space_write_8( 153 ddf_fun_t *fun, uint32_t address, uint8_t data) 154 { 155 if (address > 255) 156 return EINVAL; 157 pci_conf_write_8(PCI_FUN(fun), address, data); 158 return EOK; 159 } 160 161 static int pci_config_space_read_32( 162 ddf_fun_t *fun, uint32_t address, uint32_t *data) 163 { 164 if (address > 252) 165 return EINVAL; 166 *data = pci_conf_read_32(PCI_FUN(fun), address); 167 return EOK; 168 } 169 170 static int pci_config_space_read_16( 171 ddf_fun_t *fun, uint32_t address, uint16_t *data) 172 { 173 if (address > 254) 174 return EINVAL; 175 *data = pci_conf_read_16(PCI_FUN(fun), address); 176 return EOK; 177 } 178 179 static int pci_config_space_read_8( 180 ddf_fun_t *fun, uint32_t address, uint8_t *data) 181 { 182 if (address > 255) 183 return EINVAL; 184 *data = pci_conf_read_8(PCI_FUN(fun), address); 185 return EOK; 89 186 } 90 187 … … 94 191 }; 95 192 96 static ddf_dev_ops_t pci_fun_ops; 193 static pci_dev_iface_t pci_dev_ops = { 194 .config_space_read_8 = &pci_config_space_read_8, 195 .config_space_read_16 = &pci_config_space_read_16, 196 .config_space_read_32 = &pci_config_space_read_32, 197 .config_space_write_8 = &pci_config_space_write_8, 198 .config_space_write_16 = &pci_config_space_write_16, 199 .config_space_write_32 = &pci_config_space_write_32 200 }; 201 202 static ddf_dev_ops_t pci_fun_ops = { 203 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 204 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 205 }; 97 206 98 207 static int pci_add_device(ddf_dev_t *); 208 static int pci_fun_online(ddf_fun_t *); 209 static int pci_fun_offline(ddf_fun_t *); 99 210 100 211 /** PCI bus driver standard operations */ 101 212 static driver_ops_t pci_ops = { 102 .add_device = &pci_add_device 213 .add_device = &pci_add_device, 214 .fun_online = &pci_fun_online, 215 .fun_offline = &pci_fun_offline, 103 216 }; 104 217 … … 109 222 }; 110 223 111 static pci_bus_t *pci_bus_new(void)112 {113 pci_bus_t *bus;114 115 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t));116 if (bus == NULL)117 return NULL;118 119 fibril_mutex_initialize(&bus->conf_mutex);120 return bus;121 }122 123 static void pci_bus_delete(pci_bus_t *bus)124 {125 assert(bus != NULL);126 free(bus);127 }128 129 224 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 130 225 { … … 133 228 fibril_mutex_lock(&bus->conf_mutex); 134 229 135 uint32_t conf_addr; 136 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 230 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 137 231 void *addr = bus->conf_data_port + (reg & 3); 138 232 … … 219 313 void pci_fun_create_match_ids(pci_fun_t *fun) 220 314 { 221 char *match_id_str;222 315 int rc; 223 224 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 316 char match_id_str[ID_MAX_STR_LEN]; 317 318 /* Vendor ID & Device ID, length(incl \0) 22 */ 319 rc = snprintf(match_id_str, ID_MAX_STR_LEN, "pci/ven=%04x&dev=%04x", 225 320 fun->vendor_id, fun->device_id); 226 227 if (match_id_str == NULL) { 228 ddf_msg(LVL_ERROR, "Out of memory creating match ID."); 229 return; 321 if (rc < 0) { 322 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 323 str_error(rc)); 230 324 } 231 325 232 326 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 233 327 if (rc != EOK) { 234 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", 328 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 329 } 330 331 /* Class, subclass, prog IF, revision, length(incl \0) 47 */ 332 rc = snprintf(match_id_str, ID_MAX_STR_LEN, 333 "pci/class=%02x&subclass=%02x&progif=%02x&revision=%02x", 334 fun->class_code, fun->subclass_code, fun->prog_if, fun->revision); 335 if (rc < 0) { 336 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 235 337 str_error(rc)); 236 338 } 237 238 /* TODO add more ids (with subsys ids, using class id etc.) */ 339 340 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 70); 341 if (rc != EOK) { 342 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 343 } 344 345 /* Class, subclass, prog IF, length(incl \0) 35 */ 346 rc = snprintf(match_id_str, ID_MAX_STR_LEN, 347 "pci/class=%02x&subclass=%02x&progif=%02x", 348 fun->class_code, fun->subclass_code, fun->prog_if); 349 if (rc < 0) { 350 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 351 str_error(rc)); 352 } 353 354 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 60); 355 if (rc != EOK) { 356 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 357 } 358 359 /* Class, subclass, length(incl \0) 25 */ 360 rc = snprintf(match_id_str, ID_MAX_STR_LEN, 361 "pci/class=%02x&subclass=%02x", 362 fun->class_code, fun->subclass_code); 363 if (rc < 0) { 364 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 365 str_error(rc)); 366 } 367 368 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 50); 369 if (rc != EOK) { 370 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 371 } 372 373 /* Class, length(incl \0) 13 */ 374 rc = snprintf(match_id_str, ID_MAX_STR_LEN, "pci/class=%02x", 375 fun->class_code); 376 if (rc < 0) { 377 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 378 str_error(rc)); 379 } 380 381 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 40); 382 if (rc != EOK) { 383 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 384 } 385 386 /* TODO add subsys ids, but those exist only in header type 0 */ 239 387 } 240 388 … … 288 436 /* Get the value of the BAR. */ 289 437 val = pci_conf_read_32(fun, addr); 438 439 #define IO_MASK (~0x3) 440 #define MEM_MASK (~0xf) 290 441 291 442 io = (bool) (val & 1); 292 443 if (io) { 293 444 addrw64 = false; 445 mask = IO_MASK; 294 446 } else { 447 mask = MEM_MASK; 295 448 switch ((val >> 1) & 3) { 296 449 case 0: … … 308 461 /* Get the address mask. */ 309 462 pci_conf_write_32(fun, addr, 0xffffffff); 310 mask = pci_conf_read_32(fun, addr);463 mask &= pci_conf_read_32(fun, addr); 311 464 312 465 /* Restore the original value. */ … … 382 535 for (fnum = 0; multi && fnum < 8; fnum++) { 383 536 pci_fun_init(fun, bus_num, dnum, fnum); 384 fun->vendor_id = pci_conf_read_16(fun,385 PCI_VENDOR_ID);386 fun->device_id = pci_conf_read_16(fun,387 PCI_DEVICE_ID);388 537 if (fun->vendor_id == 0xffff) { 389 538 /* … … 412 561 413 562 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 563 free(fun_name); 414 564 if (fnode == NULL) { 415 565 ddf_msg(LVL_ERROR, "Failed creating function."); … … 417 567 } 418 568 419 free(fun_name);420 569 fun->fnode = fnode; 421 570 … … 469 618 470 619 ddf_msg(LVL_DEBUG, "pci_add_device"); 471 dnode->parent_ phone = -1;472 473 bus = pci_bus_new();620 dnode->parent_sess = NULL; 621 622 bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t)); 474 623 if (bus == NULL) { 475 624 ddf_msg(LVL_ERROR, "pci_add_device allocation failed."); … … 477 626 goto fail; 478 627 } 628 fibril_mutex_initialize(&bus->conf_mutex); 629 479 630 bus->dnode = dnode; 480 631 dnode->driver_data = bus; 481 632 482 dnode->parent_ phone = devman_parent_device_connect(dnode->handle,483 IPC_FLAG_BLOCKING);484 if ( dnode->parent_phone < 0) {633 dnode->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE, 634 dnode->handle, IPC_FLAG_BLOCKING); 635 if (!dnode->parent_sess) { 485 636 ddf_msg(LVL_ERROR, "pci_add_device failed to connect to the " 486 "parent 'sdriver.");487 rc = dnode->parent_phone;637 "parent driver."); 638 rc = ENOENT; 488 639 goto fail; 489 640 } … … 491 642 hw_resource_list_t hw_resources; 492 643 493 rc = hw_res_get_resource_list(dnode->parent_ phone, &hw_resources);644 rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources); 494 645 if (rc != EOK) { 495 646 ddf_msg(LVL_ERROR, "pci_add_device failed to get hw resources " … … 542 693 543 694 fail: 544 if (bus != NULL) 545 pci_bus_delete(bus); 546 if (dnode->parent_phone >= 0) 547 async_hangup(dnode->parent_phone); 695 if (dnode->parent_sess) 696 async_hangup(dnode->parent_sess); 697 548 698 if (got_res) 549 699 hw_res_clean_resource_list(&hw_resources); 700 550 701 if (ctl != NULL) 551 702 ddf_fun_destroy(ctl); 552 703 553 704 return rc; 705 } 706 707 static int pci_fun_online(ddf_fun_t *fun) 708 { 709 ddf_msg(LVL_DEBUG, "pci_fun_online()"); 710 return ddf_fun_online(fun); 711 } 712 713 static int pci_fun_offline(ddf_fun_t *fun) 714 { 715 ddf_msg(LVL_DEBUG, "pci_fun_offline()"); 716 return ddf_fun_offline(fun); 554 717 } 555 718 … … 558 721 ddf_log_init(NAME, LVL_ERROR); 559 722 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 723 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops; 560 724 } 561 725 … … 577 741 fun->dev = dev; 578 742 fun->fn = fn; 743 fun->vendor_id = pci_conf_read_16(fun, PCI_VENDOR_ID); 744 fun->device_id = pci_conf_read_16(fun, PCI_DEVICE_ID); 745 fun->class_code = pci_conf_read_8(fun, PCI_BASE_CLASS); 746 fun->subclass_code = pci_conf_read_8(fun, PCI_SUB_CLASS); 747 fun->prog_if = pci_conf_read_8(fun, PCI_PROG_IF); 748 fun->revision = pci_conf_read_8(fun, PCI_REVISION_ID); 579 749 } 580 750 … … 597 767 bool pci_alloc_resource_list(pci_fun_t *fun) 598 768 { 599 fun->hw_resources.resources = 600 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 601 return fun->hw_resources.resources != NULL; 769 fun->hw_resources.resources = fun->resources; 770 return true; 602 771 } 603 772 604 773 void pci_clean_resource_list(pci_fun_t *fun) 605 774 { 606 if (fun->hw_resources.resources != NULL) { 607 free(fun->hw_resources.resources); 608 fun->hw_resources.resources = NULL; 609 } 775 fun->hw_resources.resources = NULL; 610 776 } 611 777 … … 629 795 size_t pci_bar_mask_to_size(uint32_t mask) 630 796 { 631 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 797 size_t size = mask & ~(mask - 1); 798 return size; 632 799 } 633 800 -
uspace/drv/bus/pci/pciintel/pci.h
r2bdf8313 rb0f00a9 60 60 int vendor_id; 61 61 int device_id; 62 uint8_t class_code; 63 uint8_t subclass_code; 64 uint8_t prog_if; 65 uint8_t revision; 62 66 hw_resource_list_t hw_resources; 67 hw_resource_t resources[PCI_MAX_HW_RES]; 63 68 } pci_fun_t; 64 69 -
uspace/drv/bus/usb/ehci/ehci.h
r2bdf8313 rb0f00a9 1 1 /* 2 * Copyright (c) 20 09 Jiri Svoboda2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup mouse 30 * @brief 29 /** @addtogroup drvusbehci 31 30 * @{ 32 31 */ 33 32 /** @file 33 * Common EHCI definitions. 34 34 */ 35 #ifndef DRV_EHCI_EHCI_H 36 #define DRV_EHCI_EHCI_H 35 37 36 #ifndef LIBC_IPC_MOUSE_H_ 37 #define LIBC_IPC_MOUSE_H_ 38 #include <usbhc_iface.h> 38 39 39 # include <ipc/common.h>40 #define NAME "ehci" 40 41 41 typedef enum { 42 MEVENT_BUTTON = IPC_FIRST_USER_METHOD, 43 MEVENT_MOVE 44 } mouse_notif_t; 42 extern usbhc_iface_t ehci_hc_iface; 45 43 46 44 #endif 47 48 45 /** 49 46 * @} 50 47 */ 48 -
uspace/drv/bus/usb/uhci/uhci.h
r2bdf8313 rb0f00a9 1 1 /* 2 * Copyright (c) 20 09 Jiri Svoboda2 * Copyright (c) 2011 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup mouse 30 * @brief 29 /** @addtogroup drvusbuhci 31 30 * @{ 32 31 */ 33 32 /** @file 33 * @brief UHCI driver main structure for both host controller and root-hub. 34 34 */ 35 #ifndef DRV_UHCI_UHCI_H 36 #define DRV_UHCI_UHCI_H 37 #include <ddf/driver.h> 35 38 36 #ifndef CHAR_MOUSE_H_ 37 #define CHAR_MOUSE_H_ 38 39 extern void mouse_handle_byte(int); 40 extern void mouse_ev_btn(int button, int press); 41 extern void mouse_ev_move(int dx, int dy); 42 39 int device_setup_uhci(ddf_dev_t *device); 43 40 #endif 44 45 41 /** 46 42 * @} -
uspace/drv/bus/usb/usbmast/Makefile
r2bdf8313 rb0f00a9 1 1 # 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 2 # Copyright (c) 2011 Vojtech Horky 4 3 # All rights reserved. 5 4 # … … 29 28 30 29 USPACE_PREFIX = ../../../.. 31 ROOT_PATH = $(USPACE_PREFIX)/..32 LIBS = $(LIBNET_PREFIX)/libnet.a33 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include34 30 35 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common 36 CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config 31 LIBS = \ 32 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 33 $(LIBUSB_PREFIX)/libusb.a \ 34 $(LIBDRV_PREFIX)/libdrv.a \ 35 $(LIBSCSI_PREFIX)/libscsi.a 37 36 38 -include $(COMMON_MAKEFILE) 39 -include $(CONFIG_MAKEFILE) 37 EXTRA_CFLAGS += \ 38 -I$(LIBUSB_PREFIX)/include \ 39 -I$(LIBUSBDEV_PREFIX)/include \ 40 -I$(LIBDRV_PREFIX)/include \ 41 -I$(LIBSCSI_PREFIX)/include 40 42 41 BINARY = ne200043 BINARY = usbmast 42 44 43 45 SOURCES = \ 44 dp8390.c \ 45 ne2000.c 46 bo_trans.c \ 47 cmdw.c \ 48 main.c \ 49 scsi_ms.c 46 50 47 51 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/char/ns8250/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -
uspace/drv/char/ns8250/ns8250.c
r2bdf8313 rb0f00a9 59 59 60 60 #include <devman.h> 61 #include <ns.h> 61 62 #include <ipc/devman.h> 63 #include <ipc/services.h> 64 #include <ipc/irc.h> 62 65 #include <device/hw_res.h> 63 66 #include <ipc/serial_ctl.h> … … 111 114 /** The fibril mutex for synchronizing the access to the device. */ 112 115 fibril_mutex_t mutex; 116 /** True if device is removed. */ 117 bool removed; 113 118 } 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);139 }140 119 141 120 /** Find out if there is some incomming data available on the serial port. … … 245 224 246 225 static int ns8250_add_device(ddf_dev_t *dev); 226 static int ns8250_dev_remove(ddf_dev_t *dev); 247 227 248 228 /** The serial port device driver's standard operations. */ 249 229 static driver_ops_t ns8250_ops = { 250 .add_device = &ns8250_add_device 230 .add_device = &ns8250_add_device, 231 .dev_remove = &ns8250_dev_remove 251 232 }; 252 233 … … 263 244 static void ns8250_dev_cleanup(ns8250_t *ns) 264 245 { 265 if (ns->dev->parent_ phone > 0) {266 async_hangup(ns->dev->parent_ phone);267 ns->dev->parent_ phone = 0;246 if (ns->dev->parent_sess) { 247 async_hangup(ns->dev->parent_sess); 248 ns->dev->parent_sess = NULL; 268 249 } 269 250 } … … 337 318 338 319 /* Connect to the parent's driver. */ 339 ns->dev->parent_ phone = devman_parent_device_connect(ns->dev->handle,340 IPC_FLAG_BLOCKING);341 if ( ns->dev->parent_phone < 0) {320 ns->dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE, 321 ns->dev->handle, IPC_FLAG_BLOCKING); 322 if (!ns->dev->parent_sess) { 342 323 ddf_msg(LVL_ERROR, "Failed to connect to parent driver of " 343 324 "device %s.", ns->dev->name); 344 ret = ns->dev->parent_phone;325 ret = ENOENT; 345 326 goto failed; 346 327 } 347 328 348 329 /* Get hw resources. */ 349 ret = hw_res_get_resource_list(ns->dev->parent_ phone, &hw_resources);330 ret = hw_res_get_resource_list(ns->dev->parent_sess, &hw_resources); 350 331 if (ret != EOK) { 351 332 ddf_msg(LVL_ERROR, "Failed to get HW resources for device " … … 431 412 static int ns8250_interrupt_enable(ns8250_t *ns) 432 413 { 414 /* 415 * Enable interrupt using IRC service. 416 * TODO: This is a temporary solution until the device framework 417 * takes care of this itself. 418 */ 419 async_sess_t *irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 420 SERVICE_IRC, 0, 0); 421 if (!irc_sess) { 422 return EIO; 423 } 424 425 async_exch_t *exch = async_exchange_begin(irc_sess); 426 if (!exch) { 427 return EIO; 428 } 429 async_msg_1(exch, IRC_ENABLE_INTERRUPT, ns->irq); 430 async_exchange_end(exch); 431 433 432 /* Enable interrupt on the serial port. */ 434 433 ns8250_port_interrupts_enable(ns->port); … … 636 635 */ 637 636 pio_write_8(port + 4, 0x0B); 637 } 638 639 /** Deinitialize the serial port device. 640 * 641 * @param ns Serial port device 642 */ 643 static void ns8250_port_cleanup(ns8250_t *ns) 644 { 645 /* Disable FIFO */ 646 pio_write_8(ns->port + 2, 0x00); 647 /* Disable DTR, RTS, OUT1, OUT2 (int. enable) */ 648 pio_write_8(ns->port + 4, 0x00); 649 /* Disable all interrupts from the port */ 650 ns8250_port_interrupts_disable(ns->port); 638 651 } 639 652 … … 721 734 722 735 /* Allocate soft-state for the device */ 723 ns = ns8250_new();736 ns = ddf_dev_data_alloc(dev, sizeof(ns8250_t)); 724 737 if (ns == NULL) { 725 738 rc = ENOMEM; … … 727 740 } 728 741 742 fibril_mutex_initialize(&ns->mutex); 729 743 ns->dev = dev; 730 dev->driver_data = ns;731 744 732 745 rc = ns8250_dev_initialize(ns); … … 781 794 ns->fun = fun; 782 795 783 ddf_fun_add_to_c lass(fun, "serial");796 ddf_fun_add_to_category(fun, "serial"); 784 797 785 798 ddf_msg(LVL_NOTE, "Device %s successfully initialized.", … … 792 805 if (need_cleanup) 793 806 ns8250_dev_cleanup(ns); 794 if (ns != NULL)795 ns8250_delete(ns);796 807 return rc; 808 } 809 810 static int ns8250_dev_remove(ddf_dev_t *dev) 811 { 812 ns8250_t *ns = NS8250_FROM_DEV(dev); 813 int rc; 814 815 fibril_mutex_lock(&ns->mutex); 816 if (ns->client_connected) { 817 fibril_mutex_unlock(&ns->mutex); 818 return EBUSY; 819 } 820 ns->removed = true; 821 fibril_mutex_unlock(&ns->mutex); 822 823 rc = ddf_fun_unbind(ns->fun); 824 if (rc != EOK) { 825 ddf_msg(LVL_ERROR, "Failed to unbind function."); 826 return rc; 827 } 828 829 ddf_fun_destroy(ns->fun); 830 831 ns8250_port_cleanup(ns); 832 ns8250_unregister_interrupt_handler(ns); 833 ns8250_dev_cleanup(ns); 834 return EOK; 797 835 } 798 836 … … 806 844 static int ns8250_open(ddf_fun_t *fun) 807 845 { 808 ns8250_t * data = (ns8250_t *) fun->dev->driver_data;846 ns8250_t *ns = NS8250(fun); 809 847 int res; 810 848 811 fibril_mutex_lock(& data->mutex);812 if ( data->client_connected) {849 fibril_mutex_lock(&ns->mutex); 850 if (ns->client_connected) { 813 851 res = ELIMIT; 852 } else if (ns->removed) { 853 res = ENXIO; 814 854 } else { 815 855 res = EOK; 816 data->client_connected = true;817 } 818 fibril_mutex_unlock(& data->mutex);856 ns->client_connected = true; 857 } 858 fibril_mutex_unlock(&ns->mutex); 819 859 820 860 return res; -
uspace/drv/infrastructure/root/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -
uspace/drv/infrastructure/root/root.c
r2bdf8313 rb0f00a9 67 67 68 68 static int root_add_device(ddf_dev_t *dev); 69 static int root_fun_online(ddf_fun_t *fun); 70 static int root_fun_offline(ddf_fun_t *fun); 69 71 70 72 /** The root device driver's standard operations. */ 71 73 static driver_ops_t root_ops = { 72 .add_device = &root_add_device 74 .add_device = &root_add_device, 75 .fun_online = &root_fun_online, 76 .fun_offline = &root_fun_offline 73 77 }; 74 78 … … 175 179 return rc; 176 180 } 181 182 free(match_id); 177 183 178 184 rc = ddf_fun_bind(fun); … … 212 218 } 213 219 220 static int root_fun_online(ddf_fun_t *fun) 221 { 222 ddf_msg(LVL_DEBUG, "root_fun_online()"); 223 return ddf_fun_online(fun); 224 } 225 226 static int root_fun_offline(ddf_fun_t *fun) 227 { 228 ddf_msg(LVL_DEBUG, "root_fun_offline()"); 229 return ddf_fun_offline(fun); 230 } 231 214 232 int main(int argc, char *argv[]) 215 233 { -
uspace/drv/infrastructure/rootpc/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -
uspace/drv/infrastructure/rootvirt/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -
uspace/drv/infrastructure/rootvirt/devices.def
r2bdf8313 rb0f00a9 4 4 * Unless the list is empty, the last item shall be followed by a comma. 5 5 */ 6 7 /* Loopback network interface */ 8 { 9 .name = "lo", 10 .match_id = "virtual&loopback" 11 }, 12 6 13 #ifdef CONFIG_TEST_DRIVERS 14 7 15 { 8 16 .name = "test1", … … 21 29 .match_id = "virtual&test1" 22 30 }, 31 { 32 .name = "test3", 33 .match_id = "virtual&test3" 34 }, 35 23 36 #endif 37 38 #ifdef CONFIG_RUN_VIRTUAL_USB_HC 39 40 /* Virtual USB host controller. */ 41 { 42 .name = "usbhc", 43 .match_id = "usb&hc=vhc" 44 }, 45 46 #endif -
uspace/drv/infrastructure/rootvirt/rootvirt.c
r2bdf8313 rb0f00a9 63 63 64 64 static int rootvirt_add_device(ddf_dev_t *dev); 65 static int rootvirt_dev_remove(ddf_dev_t *dev); 66 static int rootvirt_fun_online(ddf_fun_t *fun); 67 static int rootvirt_fun_offline(ddf_fun_t *fun); 65 68 66 69 static driver_ops_t rootvirt_ops = { 67 .add_device = &rootvirt_add_device 70 .add_device = &rootvirt_add_device, 71 .dev_remove = &rootvirt_dev_remove, 72 .fun_online = &rootvirt_fun_online, 73 .fun_offline = &rootvirt_fun_offline 68 74 }; 69 75 … … 73 79 }; 74 80 81 /* Device soft state */ 82 typedef struct { 83 ddf_dev_t *dev; 84 list_t functions; 85 } rootvirt_t; 86 87 /* Function soft state */ 88 typedef struct { 89 ddf_fun_t *fun; 90 link_t dev_link; 91 } rootvirt_fun_t; 92 93 static int instances = 0; 94 95 75 96 /** Add function to the virtual device. 76 97 * … … 79 100 * @return EOK on success or negative error code. 80 101 */ 81 static int rootvirt_add_fun(ddf_dev_t *vdev, virtual_function_t *vfun) 82 { 102 static int rootvirt_add_fun(rootvirt_t *rootvirt, virtual_function_t *vfun) 103 { 104 ddf_dev_t *vdev = rootvirt->dev; 83 105 ddf_fun_t *fun; 106 rootvirt_fun_t *rvfun; 84 107 int rc; 85 108 … … 93 116 } 94 117 118 rvfun = ddf_fun_data_alloc(fun, sizeof(rootvirt_fun_t)); 119 if (rvfun == NULL) { 120 ddf_msg(LVL_ERROR, "Failed allocating soft state for %s.", 121 vfun->name); 122 ddf_fun_destroy(fun); 123 return ENOMEM; 124 } 125 126 rvfun->fun = fun; 127 95 128 rc = ddf_fun_add_match_id(fun, vfun->match_id, 10); 96 129 if (rc != EOK) { … … 109 142 } 110 143 144 list_append(&rvfun->dev_link, &rootvirt->functions); 145 111 146 ddf_msg(LVL_NOTE, "Registered child device `%s'", vfun->name); 112 147 return EOK; 113 148 } 114 149 150 static int rootvirt_fun_remove(rootvirt_fun_t *rvfun) 151 { 152 int rc; 153 const char *name = rvfun->fun->name; 154 155 ddf_msg(LVL_DEBUG, "rootvirt_fun_remove('%s')", name); 156 rc = ddf_fun_offline(rvfun->fun); 157 if (rc != EOK) { 158 ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name); 159 return rc; 160 } 161 162 rc = ddf_fun_unbind(rvfun->fun); 163 if (rc != EOK) { 164 ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name); 165 return rc; 166 } 167 168 list_remove(&rvfun->dev_link); 169 ddf_fun_destroy(rvfun->fun); 170 return EOK; 171 } 172 173 115 174 static int rootvirt_add_device(ddf_dev_t *dev) 116 175 { 117 static int instances = 0;176 rootvirt_t *rootvirt; 118 177 119 178 /* 120 179 * Allow only single instance of root virtual device. 121 180 */ 122 instances++; 123 if (instances > 1) { 181 if (++instances > 1) { 124 182 return ELIMIT; 125 183 } 126 184 127 185 ddf_msg(LVL_DEBUG, "add_device(handle=%d)", (int)dev->handle); 186 187 rootvirt = ddf_dev_data_alloc(dev, sizeof(rootvirt_t)); 188 if (rootvirt == NULL) 189 return ENOMEM; 190 191 rootvirt->dev = dev; 192 list_initialize(&rootvirt->functions); 128 193 129 194 /* … … 133 198 virtual_function_t *vfun = virtual_functions; 134 199 while (vfun->name != NULL) { 135 (void) rootvirt_add_fun( dev, vfun);200 (void) rootvirt_add_fun(rootvirt, vfun); 136 201 vfun++; 137 202 } 138 203 139 204 return EOK; 205 } 206 207 static int rootvirt_dev_remove(ddf_dev_t *dev) 208 { 209 rootvirt_t *rootvirt = (rootvirt_t *)dev->driver_data; 210 int rc; 211 212 while (!list_empty(&rootvirt->functions)) { 213 rootvirt_fun_t *rvfun = list_get_instance( 214 list_first(&rootvirt->functions), rootvirt_fun_t, 215 dev_link); 216 217 rc = rootvirt_fun_remove(rvfun); 218 if (rc != EOK) 219 return rc; 220 } 221 222 --instances; 223 return EOK; 224 } 225 226 static int rootvirt_fun_online(ddf_fun_t *fun) 227 { 228 ddf_msg(LVL_DEBUG, "rootvirt_fun_online()"); 229 return ddf_fun_online(fun); 230 } 231 232 static int rootvirt_fun_offline(ddf_fun_t *fun) 233 { 234 ddf_msg(LVL_DEBUG, "rootvirt_fun_offline()"); 235 return ddf_fun_offline(fun); 140 236 } 141 237 -
uspace/drv/nic/ne2k/dp8390.c
r2bdf8313 rb0f00a9 2 2 * Copyright (c) 2009 Lukas Mejdrech 3 3 * Copyright (c) 2011 Martin Decky 4 * Copyright (c) 2011 Radim Vansa 4 5 * All rights reserved. 5 6 * … … 38 39 */ 39 40 40 /** @addtogroup ne2000 41 * @{ 42 */ 43 44 /** @file 41 /** 42 * @addtogroup drv_ne2k 43 * @{ 44 */ 45 46 /** 47 * @file 48 * @brief NE2000 driver core 45 49 * 46 50 * NE2000 (based on DP8390) network interface core implementation. … … 65 69 #define SQ_PAGES 6 66 70 67 /* NE2000 implementation. */68 69 /** NE2000 Data Register */70 #define NE2K_DATA 0x001071 72 /** NE2000 Reset register */73 #define NE2K_RESET 0x001f74 75 /** NE2000 data start */76 #define NE2K_START 0x400077 78 /** NE2000 data size */79 #define NE2K_SIZE 0x400080 81 /** NE2000 retry count */82 #define NE2K_RETRY 0x100083 84 /** NE2000 error messages rate limiting */85 #define NE2K_ERL 1086 87 /** Minimum Ethernet packet size in bytes */88 #define ETH_MIN_PACK_SIZE 6089 90 /** Maximum Ethernet packet size in bytes */91 #define ETH_MAX_PACK_SIZE_TAGGED 151892 93 71 /** Type definition of the receive header 94 72 * … … 216 194 * 217 195 */ 218 int ne2k_probe(ne2k_t *ne2k , void *port, int irq)196 int ne2k_probe(ne2k_t *ne2k) 219 197 { 220 198 unsigned int i; 221 222 /* General initialization */223 ne2k->port = port;224 ne2k->data_port = ne2k->port + NE2K_DATA;225 ne2k->irq = irq;226 ne2k->probed = false;227 ne2k->up = false;228 199 229 200 ne2k_init(ne2k); … … 247 218 248 219 for (i = 0; i < ETH_ADDR; i++) 249 ne2k->mac[i] = pio_read_16(ne2k->data_port); 250 251 ne2k->probed = true; 220 ne2k->mac.address[i] = pio_read_16(ne2k->data_port); 221 252 222 return EOK; 223 } 224 225 void ne2k_set_physical_address(ne2k_t *ne2k, const nic_address_t *address) 226 { 227 memcpy(&ne2k->mac, address, sizeof(nic_address_t)); 228 229 pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_DM_ABORT | CR_STP); 230 231 pio_write_8(ne2k->port + DP_RBCR0, ETH_ADDR << 1); 232 pio_write_8(ne2k->port + DP_RBCR1, 0); 233 pio_write_8(ne2k->port + DP_RSAR0, 0); 234 pio_write_8(ne2k->port + DP_RSAR1, 0); 235 pio_write_8(ne2k->port + DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 236 237 size_t i; 238 for (i = 0; i < ETH_ADDR; i++) 239 pio_write_16(ne2k->data_port, ne2k->mac.address[i]); 240 241 //pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_DM_ABORT | CR_STA); 253 242 } 254 243 … … 304 293 305 294 /* Step 4: */ 306 pio_write_8(ne2k->port + DP_RCR, RCR_AB);295 pio_write_8(ne2k->port + DP_RCR, ne2k->receive_configuration); 307 296 308 297 /* Step 5: */ … … 324 313 pio_write_8(ne2k->port + DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP); 325 314 326 pio_write_8(ne2k->port + DP_PAR0, ne2k->mac [0]);327 pio_write_8(ne2k->port + DP_PAR1, ne2k->mac [1]);328 pio_write_8(ne2k->port + DP_PAR2, ne2k->mac [2]);329 pio_write_8(ne2k->port + DP_PAR3, ne2k->mac [3]);330 pio_write_8(ne2k->port + DP_PAR4, ne2k->mac [4]);331 pio_write_8(ne2k->port + DP_PAR5, ne2k->mac [5]);332 333 pio_write_8(ne2k->port + DP_MAR0, 0 xff);334 pio_write_8(ne2k->port + DP_MAR1, 0 xff);335 pio_write_8(ne2k->port + DP_MAR2, 0 xff);336 pio_write_8(ne2k->port + DP_MAR3, 0 xff);337 pio_write_8(ne2k->port + DP_MAR4, 0 xff);338 pio_write_8(ne2k->port + DP_MAR5, 0 xff);339 pio_write_8(ne2k->port + DP_MAR6, 0 xff);340 pio_write_8(ne2k->port + DP_MAR7, 0 xff);315 pio_write_8(ne2k->port + DP_PAR0, ne2k->mac.address[0]); 316 pio_write_8(ne2k->port + DP_PAR1, ne2k->mac.address[1]); 317 pio_write_8(ne2k->port + DP_PAR2, ne2k->mac.address[2]); 318 pio_write_8(ne2k->port + DP_PAR3, ne2k->mac.address[3]); 319 pio_write_8(ne2k->port + DP_PAR4, ne2k->mac.address[4]); 320 pio_write_8(ne2k->port + DP_PAR5, ne2k->mac.address[5]); 321 322 pio_write_8(ne2k->port + DP_MAR0, 0); 323 pio_write_8(ne2k->port + DP_MAR1, 0); 324 pio_write_8(ne2k->port + DP_MAR2, 0); 325 pio_write_8(ne2k->port + DP_MAR3, 0); 326 pio_write_8(ne2k->port + DP_MAR4, 0); 327 pio_write_8(ne2k->port + DP_MAR5, 0); 328 pio_write_8(ne2k->port + DP_MAR6, 0); 329 pio_write_8(ne2k->port + DP_MAR7, 0); 341 330 342 331 pio_write_8(ne2k->port + DP_CURR, ne2k->start_page + 1); … … 372 361 } 373 362 363 static void ne2k_reset(ne2k_t *ne2k) 364 { 365 unsigned int i; 366 367 fibril_mutex_lock(&ne2k->sq_mutex); 368 369 /* Stop the chip */ 370 pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT); 371 pio_write_8(ne2k->port + DP_RBCR0, 0); 372 pio_write_8(ne2k->port + DP_RBCR1, 0); 373 374 for (i = 0; i < NE2K_RETRY; i++) { 375 if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RST) != 0) 376 break; 377 } 378 379 pio_write_8(ne2k->port + DP_TCR, TCR_1EXTERNAL | TCR_OFST); 380 pio_write_8(ne2k->port + DP_CR, CR_STA | CR_DM_ABORT); 381 pio_write_8(ne2k->port + DP_TCR, TCR_NORMAL); 382 383 /* Acknowledge the ISR_RDC (remote DMA) interrupt */ 384 for (i = 0; i < NE2K_RETRY; i++) { 385 if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RDC) != 0) 386 break; 387 } 388 389 uint8_t val = pio_read_8(ne2k->port + DP_ISR); 390 pio_write_8(ne2k->port + DP_ISR, val & ~ISR_RDC); 391 392 /* 393 * Reset the transmit ring. If we were transmitting a frame, 394 * we pretend that the packet is processed. Higher layers will 395 * retransmit if the packet wasn't actually sent. 396 */ 397 ne2k->sq.dirty = false; 398 399 fibril_mutex_unlock(&ne2k->sq_mutex); 400 } 401 374 402 /** Send a frame. 375 403 * … … 378 406 * 379 407 */ 380 void ne2k_send(ne2k_t *ne2k, packet_t *packet) 381 { 408 void ne2k_send(nic_t *nic_data, packet_t *packet) 409 { 410 ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data); 411 382 412 assert(ne2k->probed); 383 413 assert(ne2k->up); 384 414 385 415 fibril_mutex_lock(&ne2k->sq_mutex); 386 416 387 while (ne2k->sq.dirty) 417 while (ne2k->sq.dirty) { 388 418 fibril_condvar_wait(&ne2k->sq_cv, &ne2k->sq_mutex); 389 419 } 390 420 void *buf = packet_get_data(packet); 391 421 size_t size = packet_get_data_length(packet); … … 393 423 if ((size < ETH_MIN_PACK_SIZE) || (size > ETH_MAX_PACK_SIZE_TAGGED)) { 394 424 fibril_mutex_unlock(&ne2k->sq_mutex); 395 fprintf(stderr, "%s: Frame dropped (invalid size %zu bytes)\n",396 NAME, size);397 425 return; 398 426 } 399 427 400 428 /* Upload the frame to the ethernet card */ 401 429 ne2k_upload(ne2k, buf, ne2k->sq.page * DP_PAGE, size); 402 430 ne2k->sq.dirty = true; 403 431 ne2k->sq.size = size; 404 432 405 433 /* Initialize the transfer */ 406 434 pio_write_8(ne2k->port + DP_TPSR, ne2k->sq.page); … … 408 436 pio_write_8(ne2k->port + DP_TBCR1, (size >> 8) & 0xff); 409 437 pio_write_8(ne2k->port + DP_CR, CR_TXP | CR_STA); 410 411 438 fibril_mutex_unlock(&ne2k->sq_mutex); 412 } 413 414 static void ne2k_reset(ne2k_t *ne2k) 415 { 416 unsigned int i; 417 418 /* Stop the chip */ 419 pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT); 420 pio_write_8(ne2k->port + DP_RBCR0, 0); 421 pio_write_8(ne2k->port + DP_RBCR1, 0); 422 423 for (i = 0; i < NE2K_RETRY; i++) { 424 if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RST) != 0) 425 break; 426 } 427 428 pio_write_8(ne2k->port + DP_TCR, TCR_1EXTERNAL | TCR_OFST); 429 pio_write_8(ne2k->port + DP_CR, CR_STA | CR_DM_ABORT); 430 pio_write_8(ne2k->port + DP_TCR, TCR_NORMAL); 431 432 /* Acknowledge the ISR_RDC (remote DMA) interrupt */ 433 for (i = 0; i < NE2K_RETRY; i++) { 434 if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RDC) != 0) 435 break; 436 } 437 438 uint8_t val = pio_read_8(ne2k->port + DP_ISR); 439 pio_write_8(ne2k->port + DP_ISR, val & ~ISR_RDC); 440 441 /* 442 * Reset the transmit ring. If we were transmitting a frame, 443 * we pretend that the packet is processed. Higher layers will 444 * retransmit if the packet wasn't actually sent. 445 */ 446 fibril_mutex_lock(&ne2k->sq_mutex); 447 ne2k->sq.dirty = false; 448 fibril_mutex_unlock(&ne2k->sq_mutex); 449 } 450 451 static frame_t *ne2k_receive_frame(ne2k_t *ne2k, uint8_t page, size_t length) 452 { 453 frame_t *frame = (frame_t *) malloc(sizeof(frame_t)); 439 440 /* Relase packet */ 441 nic_release_packet(nic_data, packet); 442 } 443 444 static nic_frame_t *ne2k_receive_frame(nic_t *nic_data, uint8_t page, 445 size_t length) 446 { 447 ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data); 448 449 nic_frame_t *frame = nic_alloc_frame(nic_data, length); 454 450 if (frame == NULL) 455 451 return NULL; 456 457 link_initialize(&frame->link);458 459 frame->packet = netif_packet_get_1(length);460 if (frame->packet == NULL) {461 free(frame);462 return NULL;463 }464 452 465 453 void *buf = packet_suffix(frame->packet, length); … … 470 458 size_t left = (ne2k->stop_page - page) * DP_PAGE 471 459 - sizeof(recv_header_t); 472 473 460 ne2k_download(ne2k, buf, page * DP_PAGE + sizeof(recv_header_t), 474 461 left); 475 462 ne2k_download(ne2k, buf + left, ne2k->start_page * DP_PAGE, 476 463 length - left); 477 } else 464 } else { 478 465 ne2k_download(ne2k, buf, page * DP_PAGE + sizeof(recv_header_t), 479 466 length); 480 481 ne2k->stats.receive_packets++; 467 } 482 468 return frame; 483 469 } 484 470 485 static link_t *ne2k_receive(ne2k_t *ne2k) 486 { 471 static void ne2k_receive(nic_t *nic_data) 472 { 473 ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data); 487 474 /* 488 475 * Allocate memory for the list of received frames. … … 490 477 * frames from the network, but they will be lost. 491 478 */ 492 link_t *frames = (link_t *) malloc(sizeof(link_t)); 493 if (frames != NULL) 494 list_initialize(frames); 495 496 while (true) { 479 nic_frame_list_t *frames = nic_alloc_frame_list(); 480 size_t frames_count = 0; 481 482 /* We may block sending in this loop - after so many received frames there 483 * must be some interrupt pending (for the frames not yet downloaded) and 484 * we will continue in its handler. */ 485 while (frames_count < 16) { 486 //TODO: isn't some locking necessary here? 497 487 uint8_t boundary = pio_read_8(ne2k->port + DP_BNRY) + 1; 498 488 … … 503 493 uint8_t current = pio_read_8(ne2k->port + DP_CURR); 504 494 pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_STA); 505 506 495 if (current == boundary) 507 496 /* No more frames to process */ … … 520 509 521 510 pio_read_buf_16(ne2k->data_port, (void *) &header, size); 522 511 523 512 size_t length = 524 513 (((size_t) header.rbcl) | (((size_t) header.rbch) << 8)) - size; … … 527 516 if ((length < ETH_MIN_PACK_SIZE) 528 517 || (length > ETH_MAX_PACK_SIZE_TAGGED)) { 529 fprintf(stderr, "%s: Rant frame (%zu bytes)\n", NAME, length);530 518 next = current; 531 519 } else if ((header.next < ne2k->start_page) 532 520 || (header.next > ne2k->stop_page)) { 533 fprintf(stderr, "%s: Malformed next frame %u\n", NAME,534 header.next);535 521 next = current; 536 522 } else if (header.status & RSR_FO) { … … 539 525 * reset the buffers. 540 526 */ 541 fprintf(stderr, "%s: FIFO overrun\n", NAME);542 527 ne2k->overruns++; 543 528 next = current; 544 529 } else if ((header.status & RSR_PRX) && (ne2k->up)) { 545 530 if (frames != NULL) { 546 frame_t *frame = ne2k_receive_frame(ne2k, boundary, length); 547 if (frame != NULL) 548 list_append(&frame->link, frames); 549 } 531 nic_frame_t *frame = 532 ne2k_receive_frame(nic_data, boundary, length); 533 if (frame != NULL) { 534 nic_frame_list_append(frames, frame); 535 frames_count++; 536 } else { 537 break; 538 } 539 } else 540 break; 550 541 } 551 542 … … 560 551 else 561 552 next--; 562 563 553 pio_write_8(ne2k->port + DP_BNRY, next); 564 554 } 565 566 return frames; 567 } 568 569 link_t *ne2k_interrupt(ne2k_t *ne2k, uint8_t isr, uint8_t tsr) 570 { 571 /* List of received frames */ 572 link_t *frames = NULL; 573 555 nic_received_frame_list(nic_data, frames); 556 } 557 558 void ne2k_interrupt(nic_t *nic_data, uint8_t isr, uint8_t tsr) 559 { 560 ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data); 561 574 562 if (isr & (ISR_PTX | ISR_TXE)) { 575 if (isr & ISR_TXE) 576 ne2k->stats.send_errors++; 577 else { 578 if (tsr & TSR_PTX) 579 ne2k->stats.send_packets++; 580 581 if (tsr & TSR_COL) 582 ne2k->stats.collisions++; 583 584 if (tsr & TSR_ABT) 585 ne2k->stats.send_aborted_errors++; 586 587 if (tsr & TSR_CRS) 588 ne2k->stats.send_carrier_errors++; 589 590 if (tsr & TSR_FU) { 591 ne2k->underruns++; 592 if (ne2k->underruns < NE2K_ERL) 593 fprintf(stderr, "%s: FIFO underrun\n", NAME); 594 } 595 596 if (tsr & TSR_CDH) { 597 ne2k->stats.send_heartbeat_errors++; 598 if (ne2k->stats.send_heartbeat_errors < NE2K_ERL) 599 fprintf(stderr, "%s: CD heartbeat failure\n", NAME); 600 } 601 602 if (tsr & TSR_OWC) 603 ne2k->stats.send_window_errors++; 563 if (tsr & TSR_COL) { 564 nic_report_collisions(nic_data, 565 pio_read_8(ne2k->port + DP_NCR) & 15); 604 566 } 605 567 568 if (tsr & TSR_PTX) { 569 // TODO: fix number of sent bytes (but how?) 570 nic_report_send_ok(nic_data, 1, 0); 571 } else if (tsr & TSR_ABT) { 572 nic_report_send_error(nic_data, NIC_SEC_ABORTED, 1); 573 } else if (tsr & TSR_CRS) { 574 nic_report_send_error(nic_data, NIC_SEC_CARRIER_LOST, 1); 575 } else if (tsr & TSR_FU) { 576 ne2k->underruns++; 577 // if (ne2k->underruns < NE2K_ERL) { 578 // } 579 } else if (tsr & TSR_CDH) { 580 nic_report_send_error(nic_data, NIC_SEC_HEARTBEAT, 1); 581 // if (nic_data->stats.send_heartbeat_errors < NE2K_ERL) { 582 // } 583 } else if (tsr & TSR_OWC) { 584 nic_report_send_error(nic_data, NIC_SEC_WINDOW_ERROR, 1); 585 } 586 606 587 fibril_mutex_lock(&ne2k->sq_mutex); 607 608 588 if (ne2k->sq.dirty) { 609 589 /* Prepare the buffer for next packet */ … … 615 595 } else { 616 596 ne2k->misses++; 617 if (ne2k->misses < NE2K_ERL)618 fprintf(stderr, "%s: Spurious PTX interrupt\n", NAME);597 // if (ne2k->misses < NE2K_ERL) { 598 // } 619 599 } 620 621 600 fibril_mutex_unlock(&ne2k->sq_mutex); 622 601 } 623 624 if (isr & ISR_RXE) 625 ne2k->stats.receive_errors++; 626 602 627 603 if (isr & ISR_CNT) { 628 ne2k->stats.receive_crc_errors +=629 pio_read_8(ne2k->port + DP_CNTR0);630 ne2k->stats.receive_frame_errors +=631 pio_read_8(ne2k->port + DP_CNTR1);632 ne2k->stats.receive_missed_errors +=633 pio_read_8(ne2k->port + DP_CNTR2);634 }635 636 if (isr & ISR_PRX) 637 frames = ne2k_receive(ne2k);638 604 unsigned int errors; 605 for (errors = pio_read_8(ne2k->port + DP_CNTR0); errors > 0; --errors) 606 nic_report_receive_error(nic_data, NIC_REC_CRC, 1); 607 for (errors = pio_read_8(ne2k->port + DP_CNTR1); errors > 0; --errors) 608 nic_report_receive_error(nic_data, NIC_REC_FRAME_ALIGNMENT, 1); 609 for (errors = pio_read_8(ne2k->port + DP_CNTR2); errors > 0; --errors) 610 nic_report_receive_error(nic_data, NIC_REC_MISSED, 1); 611 } 612 if (isr & ISR_PRX) { 613 ne2k_receive(nic_data); 614 } 639 615 if (isr & ISR_RST) { 640 616 /* … … 648 624 pio_write_8(ne2k->port + DP_IMR, 649 625 IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | IMR_OVWE | IMR_CNTE); 650 651 return frames; 626 } 627 628 void ne2k_set_accept_bcast(ne2k_t *ne2k, int accept) 629 { 630 if (accept) 631 ne2k->receive_configuration |= RCR_AB; 632 else 633 ne2k->receive_configuration &= ~RCR_AB; 634 635 pio_write_8(ne2k->port + DP_RCR, ne2k->receive_configuration); 636 } 637 638 void ne2k_set_accept_mcast(ne2k_t *ne2k, int accept) 639 { 640 if (accept) 641 ne2k->receive_configuration |= RCR_AM; 642 else 643 ne2k->receive_configuration &= ~RCR_AM; 644 645 pio_write_8(ne2k->port + DP_RCR, ne2k->receive_configuration); 646 } 647 648 void ne2k_set_promisc_phys(ne2k_t *ne2k, int promisc) 649 { 650 if (promisc) 651 ne2k->receive_configuration |= RCR_PRO; 652 else 653 ne2k->receive_configuration &= ~RCR_PRO; 654 655 pio_write_8(ne2k->port + DP_RCR, ne2k->receive_configuration); 656 } 657 658 void ne2k_set_mcast_hash(ne2k_t *ne2k, uint64_t hash) 659 { 660 /* Select Page 1 and stop all transfers */ 661 pio_write_8(ne2k->port + DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP); 662 663 pio_write_8(ne2k->port + DP_MAR0, (uint8_t) hash); 664 pio_write_8(ne2k->port + DP_MAR1, (uint8_t) (hash >> 8)); 665 pio_write_8(ne2k->port + DP_MAR2, (uint8_t) (hash >> 16)); 666 pio_write_8(ne2k->port + DP_MAR3, (uint8_t) (hash >> 24)); 667 pio_write_8(ne2k->port + DP_MAR4, (uint8_t) (hash >> 32)); 668 pio_write_8(ne2k->port + DP_MAR5, (uint8_t) (hash >> 40)); 669 pio_write_8(ne2k->port + DP_MAR6, (uint8_t) (hash >> 48)); 670 pio_write_8(ne2k->port + DP_MAR7, (uint8_t) (hash >> 56)); 671 672 /* Select Page 0 and resume transfers */ 673 pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_DM_ABORT | CR_STA); 652 674 } 653 675 -
uspace/drv/nic/ne2k/dp8390.h
r2bdf8313 rb0f00a9 2 2 * Copyright (c) 2009 Lukas Mejdrech 3 3 * Copyright (c) 2011 Martin Decky 4 * Copyright (c) 2011 Radim Vansa 4 5 * All rights reserved. 5 6 * … … 38 39 */ 39 40 40 /** @addtogroup ne200041 /** @addtogroup drv_ne2k 41 42 * @{ 42 43 */ … … 50 51 51 52 #include <fibril_synch.h> 52 #include <adt/list.h> 53 #include <net/packet.h> 54 #include <netif_skel.h> 55 56 /** Module name */ 57 #define NAME "ne2000" 53 #include <nic.h> 54 #include <ddf/interrupt.h> 58 55 59 56 /** Input/output size */ 60 57 #define NE2K_IO_SIZE 0x0020 61 58 62 /** Ethernet address length */ 63 #define ETH_ADDR 6 59 /* NE2000 implementation. */ 60 61 /** NE2000 Data Register */ 62 #define NE2K_DATA 0x0010 63 64 /** NE2000 Reset register */ 65 #define NE2K_RESET 0x001f 66 67 /** NE2000 data start */ 68 #define NE2K_START 0x4000 69 70 /** NE2000 data size */ 71 #define NE2K_SIZE 0x4000 72 73 /** NE2000 retry count */ 74 #define NE2K_RETRY 0x1000 75 76 /** NE2000 error messages rate limiting */ 77 #define NE2K_ERL 10 78 79 /** Minimum Ethernet packet size in bytes */ 80 #define ETH_MIN_PACK_SIZE 60 81 82 /** Maximum Ethernet packet size in bytes */ 83 #define ETH_MAX_PACK_SIZE_TAGGED 1518 64 84 65 85 /* National Semiconductor DP8390 Network Interface Controller. */ … … 204 224 typedef struct { 205 225 /* Device configuration */ 226 void *base_port; /**< Port assigned from ISA configuration **/ 206 227 void *port; 207 228 void *data_port; 208 229 int irq; 209 uint8_t mac[ETH_ADDR];230 nic_address_t mac; 210 231 211 232 uint8_t start_page; /**< Ring buffer start page */ … … 224 245 bool probed; 225 246 bool up; 226 247 248 /* Irq code with assigned addresses for this device */ 249 irq_code_t code; 250 251 /* Copy of the receive configuration register */ 252 uint8_t receive_configuration; 253 227 254 /* Device statistics */ 228 device_stats_t stats;255 // TODO: shouldn't be these directly in device.h - nic_device_stats? 229 256 uint64_t misses; /**< Receive frame misses */ 230 257 uint64_t underruns; /**< FIFO underruns */ … … 232 259 } ne2k_t; 233 260 234 typedef struct { 235 link_t link; 236 packet_t *packet; 237 } frame_t; 238 239 extern int ne2k_probe(ne2k_t *, void *, int); 261 extern int ne2k_probe(ne2k_t *); 240 262 extern int ne2k_up(ne2k_t *); 241 263 extern void ne2k_down(ne2k_t *); 242 extern void ne2k_send(ne2k_t *, packet_t *); 243 extern link_t *ne2k_interrupt(ne2k_t *, uint8_t, uint8_t); 264 extern void ne2k_send(nic_t *, packet_t *); 265 extern void ne2k_interrupt(nic_t *, uint8_t, uint8_t); 266 extern packet_t *ne2k_alloc_packet(nic_t *, size_t); 267 268 extern void ne2k_set_accept_mcast(ne2k_t *, int); 269 extern void ne2k_set_accept_bcast(ne2k_t *, int); 270 extern void ne2k_set_promisc_phys(ne2k_t *, int); 271 extern void ne2k_set_mcast_hash(ne2k_t *, uint64_t); 272 extern void ne2k_set_physical_address(ne2k_t *, const nic_address_t *address); 244 273 245 274 #endif -
uspace/drv/test/test1/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -
uspace/drv/test/test1/test1.c
r2bdf8313 rb0f00a9 1 1 /* 2 2 * Copyright (c) 2010 Vojtech Horky 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 40 41 41 42 static int test1_add_device(ddf_dev_t *dev); 43 static int test1_dev_remove(ddf_dev_t *dev); 44 static int test1_dev_gone(ddf_dev_t *dev); 45 static int test1_fun_online(ddf_fun_t *fun); 46 static int test1_fun_offline(ddf_fun_t *fun); 42 47 43 48 static driver_ops_t driver_ops = { 44 .add_device = &test1_add_device 49 .add_device = &test1_add_device, 50 .dev_remove = &test1_dev_remove, 51 .dev_gone = &test1_dev_gone, 52 .fun_online = &test1_fun_online, 53 .fun_offline = &test1_fun_offline 45 54 }; 46 55 … … 49 58 .driver_ops = &driver_ops 50 59 }; 60 61 typedef struct { 62 ddf_fun_t *fun_a; 63 ddf_fun_t *clone; 64 ddf_fun_t *child; 65 } test1_t; 51 66 52 67 /** Register child and inform user about it. … … 60 75 static int register_fun_verbose(ddf_dev_t *parent, const char *message, 61 76 const char *name, const char *match_id, int match_score, 62 int expected_rc )77 int expected_rc, ddf_fun_t **pfun) 63 78 { 64 79 ddf_fun_t *fun = NULL; … … 74 89 } 75 90 76 rc = ddf_fun_add_match_id(fun, str_dup(match_id), match_score);91 rc = ddf_fun_add_match_id(fun, match_id, match_score); 77 92 if (rc != EOK) { 78 93 ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s", … … 103 118 } 104 119 120 if (pfun != NULL) 121 *pfun = fun; 122 105 123 return rc; 106 124 } … … 126 144 { 127 145 ddf_fun_t *fun_a; 146 test1_t *test1; 128 147 int rc; 129 148 130 149 ddf_msg(LVL_DEBUG, "add_device(name=\"%s\", handle=%d)", 131 150 dev->name, (int) dev->handle); 151 152 test1 = ddf_dev_data_alloc(dev, sizeof(test1_t)); 153 if (test1 == NULL) { 154 ddf_msg(LVL_ERROR, "Failed allocating soft state.\n"); 155 return ENOMEM; 156 } 132 157 133 158 fun_a = ddf_fun_create(dev, fun_exposed, "a"); … … 137 162 } 138 163 164 test1->fun_a = fun_a; 165 139 166 rc = ddf_fun_bind(fun_a); 140 167 if (rc != EOK) { 141 168 ddf_msg(LVL_ERROR, "Failed binding function 'a'."); 169 ddf_fun_destroy(fun_a); 142 170 return rc; 143 171 } 144 172 145 ddf_fun_add_to_c lass(fun_a, "virtual");173 ddf_fun_add_to_category(fun_a, "virtual"); 146 174 147 175 if (str_cmp(dev->name, "null") == 0) { 148 176 fun_a->ops = &char_device_ops; 149 ddf_fun_add_to_c lass(fun_a, "virt-null");177 ddf_fun_add_to_category(fun_a, "virt-null"); 150 178 } else if (str_cmp(dev->name, "test1") == 0) { 151 179 (void) register_fun_verbose(dev, 152 180 "cloning myself ;-)", "clone", 153 "virtual&test1", 10, EOK );181 "virtual&test1", 10, EOK, &test1->clone); 154 182 (void) register_fun_verbose(dev, 155 183 "cloning myself twice ;-)", "clone", 156 "virtual&test1", 10, EEXISTS );184 "virtual&test1", 10, EEXISTS, NULL); 157 185 } else if (str_cmp(dev->name, "clone") == 0) { 158 186 (void) register_fun_verbose(dev, 159 187 "run by the same task", "child", 160 "virtual&test1&child", 10, EOK );188 "virtual&test1&child", 10, EOK, &test1->child); 161 189 } 162 190 … … 164 192 165 193 return EOK; 194 } 195 196 static int fun_remove(ddf_fun_t *fun, const char *name) 197 { 198 int rc; 199 200 ddf_msg(LVL_DEBUG, "fun_remove(%p, '%s')", fun, name); 201 rc = ddf_fun_offline(fun); 202 if (rc != EOK) { 203 ddf_msg(LVL_ERROR, "Error offlining function '%s'.", name); 204 return rc; 205 } 206 207 rc = ddf_fun_unbind(fun); 208 if (rc != EOK) { 209 ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name); 210 return rc; 211 } 212 213 ddf_fun_destroy(fun); 214 return EOK; 215 } 216 217 static int fun_unbind(ddf_fun_t *fun, const char *name) 218 { 219 int rc; 220 221 ddf_msg(LVL_DEBUG, "fun_unbind(%p, '%s')", fun, name); 222 rc = ddf_fun_unbind(fun); 223 if (rc != EOK) { 224 ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name); 225 return rc; 226 } 227 228 ddf_fun_destroy(fun); 229 return EOK; 230 } 231 232 static int test1_dev_remove(ddf_dev_t *dev) 233 { 234 test1_t *test1 = (test1_t *)dev->driver_data; 235 int rc; 236 237 ddf_msg(LVL_DEBUG, "test1_dev_remove(%p)", dev); 238 239 if (test1->fun_a != NULL) { 240 rc = fun_remove(test1->fun_a, "a"); 241 if (rc != EOK) 242 return rc; 243 } 244 245 if (test1->clone != NULL) { 246 rc = fun_remove(test1->clone, "clone"); 247 if (rc != EOK) 248 return rc; 249 } 250 251 if (test1->child != NULL) { 252 rc = fun_remove(test1->child, "child"); 253 if (rc != EOK) 254 return rc; 255 } 256 257 return EOK; 258 } 259 260 static int test1_dev_gone(ddf_dev_t *dev) 261 { 262 test1_t *test1 = (test1_t *)dev->driver_data; 263 int rc; 264 265 ddf_msg(LVL_DEBUG, "test1_dev_remove(%p)", dev); 266 267 if (test1->fun_a != NULL) { 268 rc = fun_unbind(test1->fun_a, "a"); 269 if (rc != EOK) 270 return rc; 271 } 272 273 if (test1->clone != NULL) { 274 rc = fun_unbind(test1->clone, "clone"); 275 if (rc != EOK) 276 return rc; 277 } 278 279 if (test1->child != NULL) { 280 rc = fun_unbind(test1->child, "child"); 281 if (rc != EOK) 282 return rc; 283 } 284 285 return EOK; 286 } 287 288 static int test1_fun_online(ddf_fun_t *fun) 289 { 290 ddf_msg(LVL_DEBUG, "test1_fun_online()"); 291 return ddf_fun_online(fun); 292 } 293 294 static int test1_fun_offline(ddf_fun_t *fun) 295 { 296 ddf_msg(LVL_DEBUG, "test1_fun_offline()"); 297 return ddf_fun_offline(fun); 166 298 } 167 299 -
uspace/drv/test/test2/Makefile
r2bdf8313 rb0f00a9 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../.. 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
Note:
See TracChangeset
for help on using the changeset viewer.
