Changeset b0f00a9 in mainline for uspace/drv


Ignore:
Timestamp:
2011-11-06T22:21:05Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
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.
Message:

Merge mainline changes.

Location:
uspace/drv
Files:
135 added
1 deleted
35 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/isa/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
  • uspace/drv/bus/isa/isa.c

    r2bdf8313 rb0f00a9  
    3737 */
    3838
     39#include <adt/list.h>
    3940#include <assert.h>
    4041#include <stdio.h>
     
    6364#define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
    6465
    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))
    6771
    6872#define ISA_MAX_HW_RES 4
    6973
     74typedef 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
    7081typedef struct isa_fun {
     82        fibril_mutex_t mutex;
    7183        ddf_fun_t *fnode;
    7284        hw_resource_list_t hw_resources;
     85        link_t bus_link;
    7386} isa_fun_t;
    7487
     
    96109
    97110static int isa_add_device(ddf_dev_t *dev);
     111static int isa_dev_remove(ddf_dev_t *dev);
     112static int isa_fun_online(ddf_fun_t *fun);
     113static int isa_fun_offline(ddf_fun_t *fun);
    98114
    99115/** The isa device driver's standard operations */
    100116static 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
    102121};
    103122
     
    108127};
    109128
    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));
     129static 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));
    113136        if (fun == NULL)
    114137                return NULL;
    115138
    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);
    122140        fun->fnode = fnode;
    123         fnode->driver_data = fun;
    124141        return fun;
    125142}
     
    352369                    str_error(rc));
    353370        }
     371
     372        free(id);
    354373}
    355374
     
    386405static void fun_hw_res_alloc(isa_fun_t *fun)
    387406{
    388         fun->hw_resources.resources = 
     407        fun->hw_resources.resources =
    389408            (hw_resource_t *)malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    390409}
    391410
    392 static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev)
     411static void fun_hw_res_free(isa_fun_t *fun)
     412{
     413        free(fun->hw_resources.resources);
     414        fun->hw_resources.resources = NULL;
     415}
     416
     417static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa)
    393418{
    394419        char *line;
     
    413438                return NULL;
    414439
    415         isa_fun_t *fun = isa_fun_create(dev, fun_name);
     440        isa_fun_t *fun = isa_fun_create(isa, fun_name);
    416441        if (fun == NULL) {
    417442                free(fun_name);
     
    446471        (void) ddf_fun_bind(fun->fnode);
    447472
     473        list_append(&fun->bus_link, &isa->functions);
     474
    448475        return fun_conf;
    449476}
    450477
    451 static void fun_conf_parse(char *conf, ddf_dev_t *dev)
     478static void fun_conf_parse(char *conf, isa_bus_t *isa)
    452479{
    453480        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
     485static void isa_functions_add(isa_bus_t *isa)
    459486{
    460487        char *fun_conf;
     
    462489        fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
    463490        if (fun_conf != NULL) {
    464                 fun_conf_parse(fun_conf, dev);
     491                fun_conf_parse(fun_conf, isa);
    465492                free(fun_conf);
    466493        }
     
    469496static int isa_add_device(ddf_dev_t *dev)
    470497{
     498        isa_bus_t *isa;
     499
    471500        ddf_msg(LVL_DEBUG, "isa_add_device, device handle = %d",
    472501            (int) dev->handle);
    473502
     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
    474511        /* Make the bus device more visible. Does not do anything. */
    475512        ddf_msg(LVL_DEBUG, "Adding a 'ctl' function");
    476513
    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) {
    479518                ddf_msg(LVL_ERROR, "Failed creating control function.");
    480519                return EXDEV;
    481520        }
    482521
    483         if (ddf_fun_bind(ctl) != EOK) {
     522        if (ddf_fun_bind(isa->fctl) != EOK) {
     523                ddf_fun_destroy(isa->fctl);
    484524                ddf_msg(LVL_ERROR, "Failed binding control function.");
    485525                return EXDEV;
     
    487527
    488528        /* Add functions as specified in the configuration file. */
    489         isa_functions_add(dev);
     529        isa_functions_add(isa);
    490530        ddf_msg(LVL_NOTE, "Finished enumerating legacy functions");
    491531
     532        fibril_mutex_unlock(&isa->mutex);
     533
    492534        return EOK;
    493535}
     536
     537static 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
     579static 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
     585static 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
    494591
    495592static void isa_init()
  • uspace/drv/bus/pci/pciintel/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
  • uspace/drv/bus/pci/pciintel/pci.c

    r2bdf8313 rb0f00a9  
    5252#include <ipc/devman.h>
    5353#include <ipc/dev_iface.h>
     54#include <ipc/irc.h>
     55#include <ns.h>
     56#include <ipc/services.h>
     57#include <sysinfo.h>
    5458#include <ops/hw_res.h>
    5559#include <device/hw_res.h>
    5660#include <ddi.h>
    5761#include <libarch/ddi.h>
     62#include <pci_dev_iface.h>
    5863
    5964#include "pci.h"
     
    7277/** Obtain PCI bus soft-state from function soft-state */
    7378#define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
     79
     80/** Max is 47, align to something nice. */
     81#define ID_MAX_STR_LEN 50
    7482
    7583static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
     
    8492static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
    8593{
    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
     134static 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
     143static 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
     152static 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
     161static 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
     170static 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
     179static 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;
    89186}
    90187
     
    94191};
    95192
    96 static ddf_dev_ops_t pci_fun_ops;
     193static 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
     202static 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};
    97206
    98207static int pci_add_device(ddf_dev_t *);
     208static int pci_fun_online(ddf_fun_t *);
     209static int pci_fun_offline(ddf_fun_t *);
    99210
    100211/** PCI bus driver standard operations */
    101212static 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,
    103216};
    104217
     
    109222};
    110223
    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 
    129224static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    130225{
     
    133228        fibril_mutex_lock(&bus->conf_mutex);
    134229       
    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);
    137231        void *addr = bus->conf_data_port + (reg & 3);
    138232       
     
    219313void pci_fun_create_match_ids(pci_fun_t *fun)
    220314{
    221         char *match_id_str;
    222315        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",
    225320            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));
    230324        }
    231325
    232326        rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90);
    233327        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",
    235337                    str_error(rc));
    236338        }
    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 */
    239387}
    240388
     
    288436        /* Get the value of the BAR. */
    289437        val = pci_conf_read_32(fun, addr);
     438
     439#define IO_MASK  (~0x3)
     440#define MEM_MASK (~0xf)
    290441       
    291442        io = (bool) (val & 1);
    292443        if (io) {
    293444                addrw64 = false;
     445                mask = IO_MASK;
    294446        } else {
     447                mask = MEM_MASK;
    295448                switch ((val >> 1) & 3) {
    296449                case 0:
     
    308461        /* Get the address mask. */
    309462        pci_conf_write_32(fun, addr, 0xffffffff);
    310         mask = pci_conf_read_32(fun, addr);
     463        mask &= pci_conf_read_32(fun, addr);
    311464       
    312465        /* Restore the original value. */
     
    382535                for (fnum = 0; multi && fnum < 8; fnum++) {
    383536                        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);
    388537                        if (fun->vendor_id == 0xffff) {
    389538                                /*
     
    412561                       
    413562                        fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
     563                        free(fun_name);
    414564                        if (fnode == NULL) {
    415565                                ddf_msg(LVL_ERROR, "Failed creating function.");
     
    417567                        }
    418568                       
    419                         free(fun_name);
    420569                        fun->fnode = fnode;
    421570                       
     
    469618       
    470619        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));
    474623        if (bus == NULL) {
    475624                ddf_msg(LVL_ERROR, "pci_add_device allocation failed.");
     
    477626                goto fail;
    478627        }
     628        fibril_mutex_initialize(&bus->conf_mutex);
     629
    479630        bus->dnode = dnode;
    480631        dnode->driver_data = bus;
    481632       
    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) {
    485636                ddf_msg(LVL_ERROR, "pci_add_device failed to connect to the "
    486                     "parent's driver.");
    487                 rc = dnode->parent_phone;
     637                    "parent driver.");
     638                rc = ENOENT;
    488639                goto fail;
    489640        }
     
    491642        hw_resource_list_t hw_resources;
    492643       
    493         rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
     644        rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources);
    494645        if (rc != EOK) {
    495646                ddf_msg(LVL_ERROR, "pci_add_device failed to get hw resources "
     
    542693       
    543694fail:
    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       
    548698        if (got_res)
    549699                hw_res_clean_resource_list(&hw_resources);
     700       
    550701        if (ctl != NULL)
    551702                ddf_fun_destroy(ctl);
    552 
     703       
    553704        return rc;
     705}
     706
     707static 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
     713static int pci_fun_offline(ddf_fun_t *fun)
     714{
     715        ddf_msg(LVL_DEBUG, "pci_fun_offline()");
     716        return ddf_fun_offline(fun);
    554717}
    555718
     
    558721        ddf_log_init(NAME, LVL_ERROR);
    559722        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     723        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    560724}
    561725
     
    577741        fun->dev = dev;
    578742        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);
    579749}
    580750
     
    597767bool pci_alloc_resource_list(pci_fun_t *fun)
    598768{
    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;
    602771}
    603772
    604773void pci_clean_resource_list(pci_fun_t *fun)
    605774{
    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;
    610776}
    611777
     
    629795size_t pci_bar_mask_to_size(uint32_t mask)
    630796{
    631         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     797        size_t size = mask & ~(mask - 1);
     798        return size;
    632799}
    633800
  • uspace/drv/bus/pci/pciintel/pci.h

    r2bdf8313 rb0f00a9  
    6060        int vendor_id;
    6161        int device_id;
     62        uint8_t class_code;
     63        uint8_t subclass_code;
     64        uint8_t prog_if;
     65        uint8_t revision;
    6266        hw_resource_list_t hw_resources;
     67        hw_resource_t resources[PCI_MAX_HW_RES];
    6368} pci_fun_t;
    6469
  • uspace/drv/bus/usb/ehci/ehci.h

    r2bdf8313 rb0f00a9  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup mouse
    30  * @brief
     29/** @addtogroup drvusbehci
    3130 * @{
    3231 */
    3332/** @file
     33 * Common EHCI definitions.
    3434 */
     35#ifndef DRV_EHCI_EHCI_H
     36#define DRV_EHCI_EHCI_H
    3537
    36 #ifndef LIBC_IPC_MOUSE_H_
    37 #define LIBC_IPC_MOUSE_H_
     38#include <usbhc_iface.h>
    3839
    39 #include <ipc/common.h>
     40#define NAME "ehci"
    4041
    41 typedef enum {
    42         MEVENT_BUTTON = IPC_FIRST_USER_METHOD,
    43         MEVENT_MOVE
    44 } mouse_notif_t;
     42extern usbhc_iface_t ehci_hc_iface;
    4543
    4644#endif
    47 
    4845/**
    4946 * @}
    5047 */
     48
  • uspace/drv/bus/usb/uhci/uhci.h

    r2bdf8313 rb0f00a9  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2011 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup mouse
    30  * @brief
     29/** @addtogroup drvusbuhci
    3130 * @{
    3231 */
    3332/** @file
     33 * @brief UHCI driver main structure for both host controller and root-hub.
    3434 */
     35#ifndef DRV_UHCI_UHCI_H
     36#define DRV_UHCI_UHCI_H
     37#include <ddf/driver.h>
    3538
    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 
     39int device_setup_uhci(ddf_dev_t *device);
    4340#endif
    44 
    4541/**
    4642 * @}
  • uspace/drv/bus/usb/usbmast/Makefile

    r2bdf8313 rb0f00a9  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2011 Vojtech Horky
    43# All rights reserved.
    54#
     
    2928
    3029USPACE_PREFIX = ../../../..
    31 ROOT_PATH = $(USPACE_PREFIX)/..
    32 LIBS = $(LIBNET_PREFIX)/libnet.a
    33 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
    3430
    35 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
    36 CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
     31LIBS = \
     32        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a \
     35        $(LIBSCSI_PREFIX)/libscsi.a
    3736
    38 -include $(COMMON_MAKEFILE)
    39 -include $(CONFIG_MAKEFILE)
     37EXTRA_CFLAGS += \
     38        -I$(LIBUSB_PREFIX)/include \
     39        -I$(LIBUSBDEV_PREFIX)/include \
     40        -I$(LIBDRV_PREFIX)/include \
     41        -I$(LIBSCSI_PREFIX)/include
    4042
    41 BINARY = ne2000
     43BINARY = usbmast
    4244
    4345SOURCES = \
    44         dp8390.c \
    45         ne2000.c
     46        bo_trans.c \
     47        cmdw.c \
     48        main.c \
     49        scsi_ms.c
    4650
    4751include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/char/ns8250/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
  • uspace/drv/char/ns8250/ns8250.c

    r2bdf8313 rb0f00a9  
    5959
    6060#include <devman.h>
     61#include <ns.h>
    6162#include <ipc/devman.h>
     63#include <ipc/services.h>
     64#include <ipc/irc.h>
    6265#include <device/hw_res.h>
    6366#include <ipc/serial_ctl.h>
     
    111114        /** The fibril mutex for synchronizing the access to the device. */
    112115        fibril_mutex_t mutex;
     116        /** True if device is removed. */
     117        bool removed;
    113118} 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 }
    140119
    141120/** Find out if there is some incomming data available on the serial port.
     
    245224
    246225static int ns8250_add_device(ddf_dev_t *dev);
     226static int ns8250_dev_remove(ddf_dev_t *dev);
    247227
    248228/** The serial port device driver's standard operations. */
    249229static driver_ops_t ns8250_ops = {
    250         .add_device = &ns8250_add_device
     230        .add_device = &ns8250_add_device,
     231        .dev_remove = &ns8250_dev_remove
    251232};
    252233
     
    263244static void ns8250_dev_cleanup(ns8250_t *ns)
    264245{
    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;
    268249        }
    269250}
     
    337318       
    338319        /* 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) {
    342323                ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
    343324                    "device %s.", ns->dev->name);
    344                 ret = ns->dev->parent_phone;
     325                ret = ENOENT;
    345326                goto failed;
    346327        }
    347328       
    348329        /* 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);
    350331        if (ret != EOK) {
    351332                ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
     
    431412static int ns8250_interrupt_enable(ns8250_t *ns)
    432413{
     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
    433432        /* Enable interrupt on the serial port. */
    434433        ns8250_port_interrupts_enable(ns->port);
     
    636635         */
    637636        pio_write_8(port + 4, 0x0B);
     637}
     638
     639/** Deinitialize the serial port device.
     640 *
     641 * @param ns            Serial port device
     642 */
     643static 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);
    638651}
    639652
     
    721734       
    722735        /* Allocate soft-state for the device */
    723         ns = ns8250_new();
     736        ns = ddf_dev_data_alloc(dev, sizeof(ns8250_t));
    724737        if (ns == NULL) {
    725738                rc = ENOMEM;
     
    727740        }
    728741       
     742        fibril_mutex_initialize(&ns->mutex);
    729743        ns->dev = dev;
    730         dev->driver_data = ns;
    731744       
    732745        rc = ns8250_dev_initialize(ns);
     
    781794        ns->fun = fun;
    782795       
    783         ddf_fun_add_to_class(fun, "serial");
     796        ddf_fun_add_to_category(fun, "serial");
    784797       
    785798        ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
     
    792805        if (need_cleanup)
    793806                ns8250_dev_cleanup(ns);
    794         if (ns != NULL)
    795                 ns8250_delete(ns);
    796807        return rc;
     808}
     809
     810static 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;
    797835}
    798836
     
    806844static int ns8250_open(ddf_fun_t *fun)
    807845{
    808         ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
     846        ns8250_t *ns = NS8250(fun);
    809847        int res;
    810848       
    811         fibril_mutex_lock(&data->mutex);
    812         if (data->client_connected) {
     849        fibril_mutex_lock(&ns->mutex);
     850        if (ns->client_connected) {
    813851                res = ELIMIT;
     852        } else if (ns->removed) {
     853                res = ENXIO;
    814854        } else {
    815855                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);
    819859       
    820860        return res;
  • uspace/drv/infrastructure/root/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
  • uspace/drv/infrastructure/root/root.c

    r2bdf8313 rb0f00a9  
    6767
    6868static int root_add_device(ddf_dev_t *dev);
     69static int root_fun_online(ddf_fun_t *fun);
     70static int root_fun_offline(ddf_fun_t *fun);
    6971
    7072/** The root device driver's standard operations. */
    7173static 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
    7377};
    7478
     
    175179                return rc;
    176180        }
     181
     182        free(match_id);
    177183
    178184        rc = ddf_fun_bind(fun);
     
    212218}
    213219
     220static 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
     226static 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
    214232int main(int argc, char *argv[])
    215233{
  • uspace/drv/infrastructure/rootpc/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
  • uspace/drv/infrastructure/rootvirt/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
  • uspace/drv/infrastructure/rootvirt/devices.def

    r2bdf8313 rb0f00a9  
    44 * Unless the list is empty, the last item shall be followed by a comma.
    55 */
     6
     7/* Loopback network interface */
     8{
     9    .name = "lo",
     10    .match_id = "virtual&loopback"
     11},
     12
    613#ifdef CONFIG_TEST_DRIVERS
     14
    715{
    816        .name = "test1",
     
    2129        .match_id = "virtual&test1"
    2230},
     31{
     32        .name = "test3",
     33        .match_id = "virtual&test3"
     34},
     35
    2336#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  
    6363
    6464static int rootvirt_add_device(ddf_dev_t *dev);
     65static int rootvirt_dev_remove(ddf_dev_t *dev);
     66static int rootvirt_fun_online(ddf_fun_t *fun);
     67static int rootvirt_fun_offline(ddf_fun_t *fun);
    6568
    6669static 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
    6874};
    6975
     
    7379};
    7480
     81/* Device soft state */
     82typedef struct {
     83        ddf_dev_t *dev;
     84        list_t functions;
     85} rootvirt_t;
     86
     87/* Function soft state */
     88typedef struct {
     89        ddf_fun_t *fun;
     90        link_t dev_link;
     91} rootvirt_fun_t;
     92
     93static int instances = 0;
     94
     95
    7596/** Add function to the virtual device.
    7697 *
     
    79100 * @return              EOK on success or negative error code.
    80101 */
    81 static int rootvirt_add_fun(ddf_dev_t *vdev, virtual_function_t *vfun)
    82 {
     102static int rootvirt_add_fun(rootvirt_t *rootvirt, virtual_function_t *vfun)
     103{
     104        ddf_dev_t *vdev = rootvirt->dev;
    83105        ddf_fun_t *fun;
     106        rootvirt_fun_t *rvfun;
    84107        int rc;
    85108
     
    93116        }
    94117
     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
    95128        rc = ddf_fun_add_match_id(fun, vfun->match_id, 10);
    96129        if (rc != EOK) {
     
    109142        }
    110143
     144        list_append(&rvfun->dev_link, &rootvirt->functions);
     145
    111146        ddf_msg(LVL_NOTE, "Registered child device `%s'", vfun->name);
    112147        return EOK;
    113148}
    114149
     150static 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
    115174static int rootvirt_add_device(ddf_dev_t *dev)
    116175{
    117         static int instances = 0;
     176        rootvirt_t *rootvirt;
    118177
    119178        /*
    120179         * Allow only single instance of root virtual device.
    121180         */
    122         instances++;
    123         if (instances > 1) {
     181        if (++instances > 1) {
    124182                return ELIMIT;
    125183        }
    126184
    127185        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);
    128193
    129194        /*
     
    133198        virtual_function_t *vfun = virtual_functions;
    134199        while (vfun->name != NULL) {
    135                 (void) rootvirt_add_fun(dev, vfun);
     200                (void) rootvirt_add_fun(rootvirt, vfun);
    136201                vfun++;
    137202        }
    138203
    139204        return EOK;
     205}
     206
     207static 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
     226static 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
     232static int rootvirt_fun_offline(ddf_fun_t *fun)
     233{
     234        ddf_msg(LVL_DEBUG, "rootvirt_fun_offline()");
     235        return ddf_fun_offline(fun);
    140236}
    141237
  • uspace/drv/nic/ne2k/dp8390.c

    r2bdf8313 rb0f00a9  
    22 * Copyright (c) 2009 Lukas Mejdrech
    33 * Copyright (c) 2011 Martin Decky
     4 * Copyright (c) 2011 Radim Vansa
    45 * All rights reserved.
    56 *
     
    3839 */
    3940
    40 /** @addtogroup ne2000
    41  *  @{
    42  */
    43 
    44 /** @file
     41/**
     42 * @addtogroup drv_ne2k
     43 * @{
     44 */
     45
     46/**
     47 * @file
     48 * @brief NE2000 driver core
    4549 *
    4650 * NE2000 (based on DP8390) network interface core implementation.
     
    6569#define SQ_PAGES  6
    6670
    67 /* NE2000 implementation. */
    68 
    69 /** NE2000 Data Register */
    70 #define NE2K_DATA  0x0010
    71 
    72 /** NE2000 Reset register */
    73 #define NE2K_RESET  0x001f
    74 
    75 /** NE2000 data start */
    76 #define NE2K_START  0x4000
    77 
    78 /** NE2000 data size */
    79 #define NE2K_SIZE  0x4000
    80 
    81 /** NE2000 retry count */
    82 #define NE2K_RETRY  0x1000
    83 
    84 /** NE2000 error messages rate limiting */
    85 #define NE2K_ERL  10
    86 
    87 /** Minimum Ethernet packet size in bytes */
    88 #define ETH_MIN_PACK_SIZE  60
    89 
    90 /** Maximum Ethernet packet size in bytes */
    91 #define ETH_MAX_PACK_SIZE_TAGGED  1518
    92 
    9371/** Type definition of the receive header
    9472 *
     
    216194 *
    217195 */
    218 int ne2k_probe(ne2k_t *ne2k, void *port, int irq)
     196int ne2k_probe(ne2k_t *ne2k)
    219197{
    220198        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;
    228199       
    229200        ne2k_init(ne2k);
     
    247218       
    248219        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       
    252222        return EOK;
     223}
     224
     225void 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);
    253242}
    254243
     
    304293       
    305294        /* Step 4: */
    306         pio_write_8(ne2k->port + DP_RCR, RCR_AB);
     295        pio_write_8(ne2k->port + DP_RCR, ne2k->receive_configuration);
    307296       
    308297        /* Step 5: */
     
    324313        pio_write_8(ne2k->port + DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
    325314       
    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, 0xff);
    334         pio_write_8(ne2k->port + DP_MAR1, 0xff);
    335         pio_write_8(ne2k->port + DP_MAR2, 0xff);
    336         pio_write_8(ne2k->port + DP_MAR3, 0xff);
    337         pio_write_8(ne2k->port + DP_MAR4, 0xff);
    338         pio_write_8(ne2k->port + DP_MAR5, 0xff);
    339         pio_write_8(ne2k->port + DP_MAR6, 0xff);
    340         pio_write_8(ne2k->port + DP_MAR7, 0xff);
     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);
    341330       
    342331        pio_write_8(ne2k->port + DP_CURR, ne2k->start_page + 1);
     
    372361}
    373362
     363static 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
    374402/** Send a frame.
    375403 *
     
    378406 *
    379407 */
    380 void ne2k_send(ne2k_t *ne2k, packet_t *packet)
    381 {
     408void ne2k_send(nic_t *nic_data, packet_t *packet)
     409{
     410        ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data);
     411
    382412        assert(ne2k->probed);
    383413        assert(ne2k->up);
    384        
     414
    385415        fibril_mutex_lock(&ne2k->sq_mutex);
    386416       
    387         while (ne2k->sq.dirty)
     417        while (ne2k->sq.dirty) {
    388418                fibril_condvar_wait(&ne2k->sq_cv, &ne2k->sq_mutex);
    389        
     419        }
    390420        void *buf = packet_get_data(packet);
    391421        size_t size = packet_get_data_length(packet);
     
    393423        if ((size < ETH_MIN_PACK_SIZE) || (size > ETH_MAX_PACK_SIZE_TAGGED)) {
    394424                fibril_mutex_unlock(&ne2k->sq_mutex);
    395                 fprintf(stderr, "%s: Frame dropped (invalid size %zu bytes)\n",
    396                     NAME, size);
    397425                return;
    398426        }
    399        
     427
    400428        /* Upload the frame to the ethernet card */
    401429        ne2k_upload(ne2k, buf, ne2k->sq.page * DP_PAGE, size);
    402430        ne2k->sq.dirty = true;
    403431        ne2k->sq.size = size;
    404        
     432
    405433        /* Initialize the transfer */
    406434        pio_write_8(ne2k->port + DP_TPSR, ne2k->sq.page);
     
    408436        pio_write_8(ne2k->port + DP_TBCR1, (size >> 8) & 0xff);
    409437        pio_write_8(ne2k->port + DP_CR, CR_TXP | CR_STA);
    410        
    411438        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
     444static 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);
    454450        if (frame == NULL)
    455451                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         }
    464452       
    465453        void *buf = packet_suffix(frame->packet, length);
     
    470458                size_t left = (ne2k->stop_page - page) * DP_PAGE
    471459                    - sizeof(recv_header_t);
    472                
    473460                ne2k_download(ne2k, buf, page * DP_PAGE + sizeof(recv_header_t),
    474461                    left);
    475462                ne2k_download(ne2k, buf + left, ne2k->start_page * DP_PAGE,
    476463                    length - left);
    477         } else
     464        } else {
    478465                ne2k_download(ne2k, buf, page * DP_PAGE + sizeof(recv_header_t),
    479466                    length);
    480        
    481         ne2k->stats.receive_packets++;
     467        }
    482468        return frame;
    483469}
    484470
    485 static link_t *ne2k_receive(ne2k_t *ne2k)
    486 {
     471static void ne2k_receive(nic_t *nic_data)
     472{
     473        ne2k_t *ne2k = (ne2k_t *) nic_get_specific(nic_data);
    487474        /*
    488475         * Allocate memory for the list of received frames.
     
    490477         * frames from the network, but they will be lost.
    491478         */
    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?
    497487                uint8_t boundary = pio_read_8(ne2k->port + DP_BNRY) + 1;
    498488               
     
    503493                uint8_t current = pio_read_8(ne2k->port + DP_CURR);
    504494                pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_STA);
    505                
    506495                if (current == boundary)
    507496                        /* No more frames to process */
     
    520509               
    521510                pio_read_buf_16(ne2k->data_port, (void *) &header, size);
    522                
     511
    523512                size_t length =
    524513                    (((size_t) header.rbcl) | (((size_t) header.rbch) << 8)) - size;
     
    527516                if ((length < ETH_MIN_PACK_SIZE)
    528517                    || (length > ETH_MAX_PACK_SIZE_TAGGED)) {
    529                         fprintf(stderr, "%s: Rant frame (%zu bytes)\n", NAME, length);
    530518                        next = current;
    531519                } else if ((header.next < ne2k->start_page)
    532520                    || (header.next > ne2k->stop_page)) {
    533                         fprintf(stderr, "%s: Malformed next frame %u\n", NAME,
    534                             header.next);
    535521                        next = current;
    536522                } else if (header.status & RSR_FO) {
     
    539525                         * reset the buffers.
    540526                         */
    541                         fprintf(stderr, "%s: FIFO overrun\n", NAME);
    542527                        ne2k->overruns++;
    543528                        next = current;
    544529                } else if ((header.status & RSR_PRX) && (ne2k->up)) {
    545530                        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;
    550541                }
    551542               
     
    560551                else
    561552                        next--;
    562                
    563553                pio_write_8(ne2k->port + DP_BNRY, next);
    564554        }
    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
     558void 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
    574562        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);
    604566                }
    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
    606587                fibril_mutex_lock(&ne2k->sq_mutex);
    607                
    608588                if (ne2k->sq.dirty) {
    609589                        /* Prepare the buffer for next packet */
     
    615595                } else {
    616596                        ne2k->misses++;
    617                         if (ne2k->misses < NE2K_ERL)
    618                                 fprintf(stderr, "%s: Spurious PTX interrupt\n", NAME);
     597                        // if (ne2k->misses < NE2K_ERL) {
     598                        // }
    619599                }
    620                
    621600                fibril_mutex_unlock(&ne2k->sq_mutex);
    622601        }
    623        
    624         if (isr & ISR_RXE)
    625                 ne2k->stats.receive_errors++;
    626        
     602
    627603        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        }
    639615        if (isr & ISR_RST) {
    640616                /*
     
    648624        pio_write_8(ne2k->port + DP_IMR,
    649625            IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | IMR_OVWE | IMR_CNTE);
    650        
    651         return frames;
     626}
     627
     628void 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
     638void 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
     648void 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
     658void 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);
    652674}
    653675
  • uspace/drv/nic/ne2k/dp8390.h

    r2bdf8313 rb0f00a9  
    22 * Copyright (c) 2009 Lukas Mejdrech
    33 * Copyright (c) 2011 Martin Decky
     4 * Copyright (c) 2011 Radim Vansa
    45 * All rights reserved.
    56 *
     
    3839 */
    3940
    40 /** @addtogroup ne2000
     41/** @addtogroup drv_ne2k
    4142 *  @{
    4243 */
     
    5051
    5152#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>
    5855
    5956/** Input/output size */
    6057#define NE2K_IO_SIZE  0x0020
    6158
    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
    6484
    6585/* National Semiconductor DP8390 Network Interface Controller. */
     
    204224typedef struct {
    205225        /* Device configuration */
     226        void *base_port; /**< Port assigned from ISA configuration **/
    206227        void *port;
    207228        void *data_port;
    208229        int irq;
    209         uint8_t mac[ETH_ADDR];
     230        nic_address_t mac;
    210231       
    211232        uint8_t start_page;  /**< Ring buffer start page */
     
    224245        bool probed;
    225246        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
    227254        /* Device statistics */
    228         device_stats_t stats;
     255        // TODO: shouldn't be these directly in device.h - nic_device_stats?
    229256        uint64_t misses;     /**< Receive frame misses */
    230257        uint64_t underruns;  /**< FIFO underruns */
     
    232259} ne2k_t;
    233260
    234 typedef struct {
    235         link_t link;
    236         packet_t *packet;
    237 } frame_t;
    238 
    239 extern int ne2k_probe(ne2k_t *, void *, int);
     261extern int ne2k_probe(ne2k_t *);
    240262extern int ne2k_up(ne2k_t *);
    241263extern 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);
     264extern void ne2k_send(nic_t *, packet_t *);
     265extern void ne2k_interrupt(nic_t *, uint8_t, uint8_t);
     266extern packet_t *ne2k_alloc_packet(nic_t *, size_t);
     267
     268extern void ne2k_set_accept_mcast(ne2k_t *, int);
     269extern void ne2k_set_accept_bcast(ne2k_t *, int);
     270extern void ne2k_set_promisc_phys(ne2k_t *, int);
     271extern void ne2k_set_mcast_hash(ne2k_t *, uint64_t);
     272extern void ne2k_set_physical_address(ne2k_t *, const nic_address_t *address);
    244273
    245274#endif
  • uspace/drv/test/test1/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
  • uspace/drv/test/test1/test1.c

    r2bdf8313 rb0f00a9  
    11/*
    22 * Copyright (c) 2010 Vojtech Horky
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4041
    4142static int test1_add_device(ddf_dev_t *dev);
     43static int test1_dev_remove(ddf_dev_t *dev);
     44static int test1_dev_gone(ddf_dev_t *dev);
     45static int test1_fun_online(ddf_fun_t *fun);
     46static int test1_fun_offline(ddf_fun_t *fun);
    4247
    4348static 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
    4554};
    4655
     
    4958        .driver_ops = &driver_ops
    5059};
     60
     61typedef struct {
     62        ddf_fun_t *fun_a;
     63        ddf_fun_t *clone;
     64        ddf_fun_t *child;
     65} test1_t;
    5166
    5267/** Register child and inform user about it.
     
    6075static int register_fun_verbose(ddf_dev_t *parent, const char *message,
    6176    const char *name, const char *match_id, int match_score,
    62     int expected_rc)
     77    int expected_rc, ddf_fun_t **pfun)
    6378{
    6479        ddf_fun_t *fun = NULL;
     
    7489        }
    7590
    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);
    7792        if (rc != EOK) {
    7893                ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s",
     
    103118        }
    104119
     120        if (pfun != NULL)
     121                *pfun = fun;
     122
    105123        return rc;
    106124}
     
    126144{
    127145        ddf_fun_t *fun_a;
     146        test1_t *test1;
    128147        int rc;
    129148
    130149        ddf_msg(LVL_DEBUG, "add_device(name=\"%s\", handle=%d)",
    131150            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        }
    132157
    133158        fun_a = ddf_fun_create(dev, fun_exposed, "a");
     
    137162        }
    138163
     164        test1->fun_a = fun_a;
     165
    139166        rc = ddf_fun_bind(fun_a);
    140167        if (rc != EOK) {
    141168                ddf_msg(LVL_ERROR, "Failed binding function 'a'.");
     169                ddf_fun_destroy(fun_a);
    142170                return rc;
    143171        }
    144172
    145         ddf_fun_add_to_class(fun_a, "virtual");
     173        ddf_fun_add_to_category(fun_a, "virtual");
    146174
    147175        if (str_cmp(dev->name, "null") == 0) {
    148176                fun_a->ops = &char_device_ops;
    149                 ddf_fun_add_to_class(fun_a, "virt-null");
     177                ddf_fun_add_to_category(fun_a, "virt-null");
    150178        } else if (str_cmp(dev->name, "test1") == 0) {
    151179                (void) register_fun_verbose(dev,
    152180                    "cloning myself ;-)", "clone",
    153                     "virtual&test1", 10, EOK);
     181                    "virtual&test1", 10, EOK, &test1->clone);
    154182                (void) register_fun_verbose(dev,
    155183                    "cloning myself twice ;-)", "clone",
    156                     "virtual&test1", 10, EEXISTS);
     184                    "virtual&test1", 10, EEXISTS, NULL);
    157185        } else if (str_cmp(dev->name, "clone") == 0) {
    158186                (void) register_fun_verbose(dev,
    159187                    "run by the same task", "child",
    160                     "virtual&test1&child", 10, EOK);
     188                    "virtual&test1&child", 10, EOK, &test1->child);
    161189        }
    162190
     
    164192
    165193        return EOK;
     194}
     195
     196static 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
     217static 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
     232static 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
     260static 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
     288static 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
     294static int test1_fun_offline(ddf_fun_t *fun)
     295{
     296        ddf_msg(LVL_DEBUG, "test1_fun_offline()");
     297        return ddf_fun_offline(fun);
    166298}
    167299
  • uspace/drv/test/test2/Makefile

    r2bdf8313 rb0f00a9  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
Note: See TracChangeset for help on using the changeset viewer.