Changeset ad7a6c9 in mainline for uspace/drv/pciintel/pci.c


Ignore:
Timestamp:
2011-03-30T13:10:24Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4ae90f9
Parents:
6e50466 (diff), d6b81941 (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/pciintel/pci.c

    r6e50466 rad7a6c9  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    4445#include <ctype.h>
    4546#include <macros.h>
    46 
    47 #include <driver.h>
     47#include <str_error.h>
     48
     49#include <ddf/driver.h>
    4850#include <devman.h>
    4951#include <ipc/devman.h>
    5052#include <ipc/dev_iface.h>
    51 #include <resource.h>
     53#include <ops/hw_res.h>
    5254#include <device/hw_res.h>
    5355#include <ddi.h>
     
    6163        ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
    6264
    63 static hw_resource_list_t *pciintel_get_child_resources(device_t *dev)
    64 {
    65         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    66        
    67         if (dev_data == NULL)
     65/** Obtain PCI function soft-state from DDF function node */
     66#define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
     67
     68/** Obtain PCI bus soft-state from DDF device node */
     69#define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
     70
     71/** Obtain PCI bus soft-state from function soft-state */
     72#define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
     73
     74static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
     75{
     76        pci_fun_t *fun = PCI_FUN(fnode);
     77       
     78        if (fun == NULL)
    6879                return NULL;
    69         return &dev_data->hw_resources;
    70 }
    71 
    72 static bool pciintel_enable_child_interrupt(device_t *dev)
     80        return &fun->hw_resources;
     81}
     82
     83static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
    7384{
    7485        /* TODO */
     
    7788}
    7889
    79 static resource_iface_t pciintel_child_res_iface = {
    80         &pciintel_get_child_resources,
    81         &pciintel_enable_child_interrupt
     90static hw_res_ops_t pciintel_hw_res_ops = {
     91        &pciintel_get_resources,
     92        &pciintel_enable_interrupt
    8293};
    8394
    84 static device_ops_t pci_child_ops;
    85 
    86 static int pci_add_device(device_t *);
    87 
    88 /** The pci bus driver's standard operations. */
     95static ddf_dev_ops_t pci_fun_ops;
     96
     97static int pci_add_device(ddf_dev_t *);
     98
     99/** PCI bus driver standard operations */
    89100static driver_ops_t pci_ops = {
    90101        .add_device = &pci_add_device
    91102};
    92103
    93 /** The pci bus driver structure. */
     104/** PCI bus driver structure */
    94105static driver_t pci_driver = {
    95106        .name = NAME,
     
    97108};
    98109
    99 typedef struct pciintel_bus_data {
    100         uint32_t conf_io_addr;
    101         void *conf_data_port;
    102         void *conf_addr_port;
    103         fibril_mutex_t conf_mutex;
    104 } pci_bus_data_t;
    105 
    106 static pci_bus_data_t *create_pci_bus_data(void)
    107 {
    108         pci_bus_data_t *bus_data;
    109        
    110         bus_data = (pci_bus_data_t *) malloc(sizeof(pci_bus_data_t));
    111         if (bus_data != NULL) {
    112                 memset(bus_data, 0, sizeof(pci_bus_data_t));
    113                 fibril_mutex_initialize(&bus_data->conf_mutex);
    114         }
    115 
    116         return bus_data;
    117 }
    118 
    119 static void delete_pci_bus_data(pci_bus_data_t *bus_data)
    120 {
    121         free(bus_data);
    122 }
    123 
    124 static void pci_conf_read(device_t *dev, int reg, uint8_t *buf, size_t len)
    125 {
    126         assert(dev->parent != NULL);
    127        
    128         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    129         pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;
    130        
    131         fibril_mutex_lock(&bus_data->conf_mutex);
     110static pci_bus_t *pci_bus_new(void)
     111{
     112        pci_bus_t *bus;
     113       
     114        bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t));
     115        if (bus == NULL)
     116                return NULL;
     117       
     118        fibril_mutex_initialize(&bus->conf_mutex);
     119        return bus;
     120}
     121
     122static void pci_bus_delete(pci_bus_t *bus)
     123{
     124        assert(bus != NULL);
     125        free(bus);
     126}
     127
     128static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     129{
     130        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     131       
     132        fibril_mutex_lock(&bus->conf_mutex);
    132133       
    133134        uint32_t conf_addr;
    134         conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg);
    135         void *addr = bus_data->conf_data_port + (reg & 3);
    136        
    137         pio_write_32(bus_data->conf_addr_port, conf_addr);
     135        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     136        void *addr = bus->conf_data_port + (reg & 3);
     137       
     138        pio_write_32(bus->conf_addr_port, conf_addr);
    138139       
    139140        switch (len) {
     
    149150        }
    150151       
    151         fibril_mutex_unlock(&bus_data->conf_mutex);
    152 }
    153 
    154 static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len)
    155 {
    156         assert(dev->parent != NULL);
    157        
    158         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    159         pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;
    160        
    161         fibril_mutex_lock(&bus_data->conf_mutex);
     152        fibril_mutex_unlock(&bus->conf_mutex);
     153}
     154
     155static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     156{
     157        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     158       
     159        fibril_mutex_lock(&bus->conf_mutex);
    162160       
    163161        uint32_t conf_addr;
    164         conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg);
    165         void *addr = bus_data->conf_data_port + (reg & 3);
    166        
    167         pio_write_32(bus_data->conf_addr_port, conf_addr);
     162        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     163        void *addr = bus->conf_data_port + (reg & 3);
     164       
     165        pio_write_32(bus->conf_addr_port, conf_addr);
    168166       
    169167        switch (len) {
     
    179177        }
    180178       
    181         fibril_mutex_unlock(&bus_data->conf_mutex);
    182 }
    183 
    184 uint8_t pci_conf_read_8(device_t *dev, int reg)
     179        fibril_mutex_unlock(&bus->conf_mutex);
     180}
     181
     182uint8_t pci_conf_read_8(pci_fun_t *fun, int reg)
    185183{
    186184        uint8_t res;
    187         pci_conf_read(dev, reg, &res, 1);
     185        pci_conf_read(fun, reg, &res, 1);
    188186        return res;
    189187}
    190188
    191 uint16_t pci_conf_read_16(device_t *dev, int reg)
     189uint16_t pci_conf_read_16(pci_fun_t *fun, int reg)
    192190{
    193191        uint16_t res;
    194         pci_conf_read(dev, reg, (uint8_t *) &res, 2);
     192        pci_conf_read(fun, reg, (uint8_t *) &res, 2);
    195193        return res;
    196194}
    197195
    198 uint32_t pci_conf_read_32(device_t *dev, int reg)
     196uint32_t pci_conf_read_32(pci_fun_t *fun, int reg)
    199197{
    200198        uint32_t res;
    201         pci_conf_read(dev, reg, (uint8_t *) &res, 4);
     199        pci_conf_read(fun, reg, (uint8_t *) &res, 4);
    202200        return res;
    203201}
    204202
    205 void pci_conf_write_8(device_t *dev, int reg, uint8_t val)
    206 {
    207         pci_conf_write(dev, reg, (uint8_t *) &val, 1);
    208 }
    209 
    210 void pci_conf_write_16(device_t *dev, int reg, uint16_t val)
    211 {
    212         pci_conf_write(dev, reg, (uint8_t *) &val, 2);
    213 }
    214 
    215 void pci_conf_write_32(device_t *dev, int reg, uint32_t val)
    216 {
    217         pci_conf_write(dev, reg, (uint8_t *) &val, 4);
    218 }
    219 
    220 void create_pci_match_ids(device_t *dev)
    221 {
    222         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    223         match_id_t *match_id = NULL;
     203void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val)
     204{
     205        pci_conf_write(fun, reg, (uint8_t *) &val, 1);
     206}
     207
     208void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val)
     209{
     210        pci_conf_write(fun, reg, (uint8_t *) &val, 2);
     211}
     212
     213void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val)
     214{
     215        pci_conf_write(fun, reg, (uint8_t *) &val, 4);
     216}
     217
     218void pci_fun_create_match_ids(pci_fun_t *fun)
     219{
    224220        char *match_id_str;
    225        
    226         match_id = create_match_id();
    227         if (match_id != NULL) {
    228                 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x",
    229                     dev_data->vendor_id, dev_data->device_id);
    230                 match_id->id = match_id_str;
    231                 match_id->score = 90;
    232                 add_match_id(&dev->match_ids, match_id);
    233         }
    234 
     221        int rc;
     222       
     223        asprintf(&match_id_str, "pci/ven=%04x&dev=%04x",
     224            fun->vendor_id, fun->device_id);
     225
     226        if (match_id_str == NULL) {
     227                printf(NAME ": out of memory creating match ID.\n");
     228                return;
     229        }
     230
     231        rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90);
     232        if (rc != EOK) {
     233                printf(NAME ": error adding match ID: %s\n",
     234                    str_error(rc));
     235        }
     236       
    235237        /* TODO add more ids (with subsys ids, using class id etc.) */
    236238}
    237239
    238 void
    239 pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io)
    240 {
    241         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    242         hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     240void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size,
     241    bool io)
     242{
     243        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    243244        hw_resource_t *hw_resources =  hw_res_list->resources;
    244245        size_t count = hw_res_list->count;
     
    265266 * address add it to the devices hw resource list.
    266267 *
    267  * @param dev   The pci device.
     268 * @param fun   PCI function
    268269 * @param addr  The address of the BAR in the PCI configuration address space of
    269  *              the device.
    270  * @return      The addr the address of the BAR which should be read next.
     270 *              the device
     271 * @return      The addr the address of the BAR which should be read next
    271272 */
    272 int pci_read_bar(device_t *dev, int addr)
    273 {       
     273int pci_read_bar(pci_fun_t *fun, int addr)
     274{
    274275        /* Value of the BAR */
    275276        uint32_t val, mask;
     
    285286       
    286287        /* Get the value of the BAR. */
    287         val = pci_conf_read_32(dev, addr);
     288        val = pci_conf_read_32(fun, addr);
    288289       
    289290        io = (bool) (val & 1);
     
    305306       
    306307        /* Get the address mask. */
    307         pci_conf_write_32(dev, addr, 0xffffffff);
    308         mask = pci_conf_read_32(dev, addr);
     308        pci_conf_write_32(fun, addr, 0xffffffff);
     309        mask = pci_conf_read_32(fun, addr);
    309310       
    310311        /* Restore the original value. */
    311         pci_conf_write_32(dev, addr, val);
    312         val = pci_conf_read_32(dev, addr);
     312        pci_conf_write_32(fun, addr, val);
     313        val = pci_conf_read_32(fun, addr);
    313314       
    314315        range_size = pci_bar_mask_to_size(mask);
    315316       
    316317        if (addrw64) {
    317                 range_addr = ((uint64_t)pci_conf_read_32(dev, addr + 4) << 32) |
     318                range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) |
    318319                    (val & 0xfffffff0);
    319320        } else {
     
    322323       
    323324        if (range_addr != 0) {
    324                 printf(NAME ": device %s : ", dev->name);
     325                printf(NAME ": function %s : ", fun->fnode->name);
    325326                printf("address = %" PRIx64, range_addr);
    326327                printf(", size = %x\n", (unsigned int) range_size);
    327328        }
    328329       
    329         pci_add_range(dev, range_addr, range_size, io);
     330        pci_add_range(fun, range_addr, range_size, io);
    330331       
    331332        if (addrw64)
     
    335336}
    336337
    337 void pci_add_interrupt(device_t *dev, int irq)
    338 {
    339         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    340         hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     338void pci_add_interrupt(pci_fun_t *fun, int irq)
     339{
     340        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    341341        hw_resource_t *hw_resources = hw_res_list->resources;
    342342        size_t count = hw_res_list->count;
     
    350350        hw_res_list->count++;
    351351       
    352         printf(NAME ": device %s uses irq %x.\n", dev->name, irq);
    353 }
    354 
    355 void pci_read_interrupt(device_t *dev)
    356 {
    357         uint8_t irq = pci_conf_read_8(dev, PCI_BRIDGE_INT_LINE);
     352        printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq);
     353}
     354
     355void pci_read_interrupt(pci_fun_t *fun)
     356{
     357        uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
    358358        if (irq != 0xff)
    359                 pci_add_interrupt(dev, irq);
     359                pci_add_interrupt(fun, irq);
    360360}
    361361
    362362/** Enumerate (recursively) and register the devices connected to a pci bus.
    363363 *
    364  * @param parent        The host-to-pci bridge device.
    365  * @param bus_num       The bus number.
     364 * @param bus           Host-to-PCI bridge
     365 * @param bus_num       Bus number
    366366 */
    367 void pci_bus_scan(device_t *parent, int bus_num)
    368 {
    369         device_t *dev = create_device();
    370         pci_dev_data_t *dev_data = create_pci_dev_data();
    371         dev->driver_data = dev_data;
    372         dev->parent = parent;
     367void pci_bus_scan(pci_bus_t *bus, int bus_num)
     368{
     369        ddf_fun_t *fnode;
     370        pci_fun_t *fun;
    373371       
    374372        int child_bus = 0;
    375373        int dnum, fnum;
    376374        bool multi;
    377         uint8_t header_type;
     375        uint8_t header_type;
     376       
     377        fun = pci_fun_new(bus);
    378378       
    379379        for (dnum = 0; dnum < 32; dnum++) {
    380380                multi = true;
    381381                for (fnum = 0; multi && fnum < 8; fnum++) {
    382                         init_pci_dev_data(dev_data, bus_num, dnum, fnum);
    383                         dev_data->vendor_id = pci_conf_read_16(dev,
     382                        pci_fun_init(fun, bus_num, dnum, fnum);
     383                        fun->vendor_id = pci_conf_read_16(fun,
    384384                            PCI_VENDOR_ID);
    385                         dev_data->device_id = pci_conf_read_16(dev,
     385                        fun->device_id = pci_conf_read_16(fun,
    386386                            PCI_DEVICE_ID);
    387                         if (dev_data->vendor_id == 0xffff) {
     387                        if (fun->vendor_id == 0xffff) {
    388388                                /*
    389389                                 * The device is not present, go on scanning the
     
    396396                        }
    397397                       
    398                         header_type = pci_conf_read_8(dev, PCI_HEADER_TYPE);
     398                        header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE);
    399399                        if (fnum == 0) {
    400400                                /* Is the device multifunction? */
     
    404404                        header_type = header_type & 0x7F;
    405405                       
    406                         create_pci_dev_name(dev);
    407                        
    408                         pci_alloc_resource_list(dev);
    409                         pci_read_bars(dev);
    410                         pci_read_interrupt(dev);
    411                        
    412                         dev->ops = &pci_child_ops;
    413                        
    414                         printf(NAME ": adding new child device %s.\n",
    415                             dev->name);
    416                        
    417                         create_pci_match_ids(dev);
    418                        
    419                         if (child_device_register(dev, parent) != EOK) {
    420                                 pci_clean_resource_list(dev);
    421                                 clean_match_ids(&dev->match_ids);
    422                                 free((char *) dev->name);
    423                                 dev->name = NULL;
     406                        char *fun_name = pci_fun_create_name(fun);
     407                        if (fun_name == NULL) {
     408                                printf(NAME ": out of memory.\n");
     409                                return;
     410                        }
     411                       
     412                        fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
     413                        if (fnode == NULL) {
     414                                printf(NAME ": error creating function.\n");
     415                                return;
     416                        }
     417                       
     418                        free(fun_name);
     419                        fun->fnode = fnode;
     420                       
     421                        pci_alloc_resource_list(fun);
     422                        pci_read_bars(fun);
     423                        pci_read_interrupt(fun);
     424                       
     425                        fnode->ops = &pci_fun_ops;
     426                        fnode->driver_data = fun;
     427                       
     428                        printf(NAME ": adding new function %s.\n",
     429                            fnode->name);
     430                       
     431                        pci_fun_create_match_ids(fun);
     432                       
     433                        if (ddf_fun_bind(fnode) != EOK) {
     434                                pci_clean_resource_list(fun);
     435                                clean_match_ids(&fnode->match_ids);
     436                                free((char *) fnode->name);
     437                                fnode->name = NULL;
    424438                                continue;
    425439                        }
     
    427441                        if (header_type == PCI_HEADER_TYPE_BRIDGE ||
    428442                            header_type == PCI_HEADER_TYPE_CARDBUS) {
    429                                 child_bus = pci_conf_read_8(dev,
     443                                child_bus = pci_conf_read_8(fun,
    430444                                    PCI_BRIDGE_SEC_BUS_NUM);
    431445                                printf(NAME ": device is pci-to-pci bridge, "
    432446                                    "secondary bus number = %d.\n", bus_num);
    433447                                if (child_bus > bus_num)
    434                                         pci_bus_scan(parent, child_bus);
     448                                        pci_bus_scan(bus, child_bus);
    435449                        }
    436450                       
    437                         /* Alloc new aux. dev. structure. */
    438                         dev = create_device();
    439                         dev_data = create_pci_dev_data();
    440                         dev->driver_data = dev_data;
    441                         dev->parent = parent;
     451                        fun = pci_fun_new(bus);
    442452                }
    443453        }
    444454       
    445         if (dev_data->vendor_id == 0xffff) {
    446                 delete_device(dev);
    447                 /* Free the auxiliary device structure. */
    448                 delete_pci_dev_data(dev_data);
    449         }
    450 }
    451 
    452 static int pci_add_device(device_t *dev)
    453 {
     455        if (fun->vendor_id == 0xffff) {
     456                /* Free the auxiliary function structure. */
     457                pci_fun_delete(fun);
     458        }
     459}
     460
     461static int pci_add_device(ddf_dev_t *dnode)
     462{
     463        pci_bus_t *bus = NULL;
     464        ddf_fun_t *ctl = NULL;
     465        bool got_res = false;
     466        int rc;
     467       
    454468        printf(NAME ": pci_add_device\n");
    455        
    456         pci_bus_data_t *bus_data = create_pci_bus_data();
    457         if (bus_data == NULL) {
     469        dnode->parent_phone = -1;
     470       
     471        bus = pci_bus_new();
     472        if (bus == NULL) {
    458473                printf(NAME ": pci_add_device allocation failed.\n");
    459                 return ENOMEM;
    460         }
    461        
    462         dev->parent_phone = devman_parent_device_connect(dev->handle,
     474                rc = ENOMEM;
     475                goto fail;
     476        }
     477        bus->dnode = dnode;
     478        dnode->driver_data = bus;
     479       
     480        dnode->parent_phone = devman_parent_device_connect(dnode->handle,
    463481            IPC_FLAG_BLOCKING);
    464         if (dev->parent_phone < 0) {
     482        if (dnode->parent_phone < 0) {
    465483                printf(NAME ": pci_add_device failed to connect to the "
    466484                    "parent's driver.\n");
    467                 delete_pci_bus_data(bus_data);
    468                 return EPARTY;  /* FIXME: use another EC */
     485                rc = dnode->parent_phone;
     486                goto fail;
    469487        }
    470488       
    471489        hw_resource_list_t hw_resources;
    472490       
    473         if (!get_hw_resources(dev->parent_phone, &hw_resources)) {
     491        rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
     492        if (rc != EOK) {
    474493                printf(NAME ": pci_add_device failed to get hw resources for "
    475494                    "the device.\n");
    476                 delete_pci_bus_data(bus_data);
    477                 ipc_hangup(dev->parent_phone);
    478                 return EPARTY;  /* FIXME: use another EC */
    479         }       
     495                goto fail;
     496        }
     497        got_res = true;
    480498       
    481499        printf(NAME ": conf_addr = %" PRIx64 ".\n",
     
    486504        assert(hw_resources.resources[0].res.io_range.size == 8);
    487505       
    488         bus_data->conf_io_addr =
     506        bus->conf_io_addr =
    489507            (uint32_t) hw_resources.resources[0].res.io_range.address;
    490508       
    491         if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8,
    492             &bus_data->conf_addr_port)) {
     509        if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
     510            &bus->conf_addr_port)) {
    493511                printf(NAME ": failed to enable configuration ports.\n");
    494                 delete_pci_bus_data(bus_data);
    495                 ipc_hangup(dev->parent_phone);
    496                 clean_hw_resource_list(&hw_resources);
    497                 return EADDRNOTAVAIL;
    498         }
    499         bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4;
    500        
    501         dev->driver_data = bus_data;
    502        
    503         /* Enumerate child devices. */
     512                rc = EADDRNOTAVAIL;
     513                goto fail;
     514        }
     515        bus->conf_data_port = (char *) bus->conf_addr_port + 4;
     516       
     517        /* Make the bus device more visible. It has no use yet. */
     518        printf(NAME ": adding a 'ctl' function\n");
     519       
     520        ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl");
     521        if (ctl == NULL) {
     522                printf(NAME ": error creating control function.\n");
     523                rc = ENOMEM;
     524                goto fail;
     525        }
     526       
     527        rc = ddf_fun_bind(ctl);
     528        if (rc != EOK) {
     529                printf(NAME ": error binding control function.\n");
     530                goto fail;
     531        }
     532       
     533        /* Enumerate functions. */
    504534        printf(NAME ": scanning the bus\n");
    505         pci_bus_scan(dev, 0);
    506        
    507         clean_hw_resource_list(&hw_resources);
     535        pci_bus_scan(bus, 0);
     536       
     537        hw_res_clean_resource_list(&hw_resources);
    508538       
    509539        return EOK;
     540       
     541fail:
     542        if (bus != NULL)
     543                pci_bus_delete(bus);
     544        if (dnode->parent_phone >= 0)
     545                async_hangup(dnode->parent_phone);
     546        if (got_res)
     547                hw_res_clean_resource_list(&hw_resources);
     548        if (ctl != NULL)
     549                ddf_fun_destroy(ctl);
     550
     551        return rc;
    510552}
    511553
    512554static void pciintel_init(void)
    513555{
    514         pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_res_iface;
    515 }
    516 
    517 pci_dev_data_t *create_pci_dev_data(void)
    518 {
    519         pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t));
    520        
    521         if (res != NULL)
    522                 memset(res, 0, sizeof(pci_dev_data_t));
    523         return res;
    524 }
    525 
    526 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn)
    527 {
    528         dev_data->bus = bus;
    529         dev_data->dev = dev;
    530         dev_data->fn = fn;
    531 }
    532 
    533 void delete_pci_dev_data(pci_dev_data_t *dev_data)
    534 {
    535         if (dev_data != NULL) {
    536                 clean_hw_resource_list(&dev_data->hw_resources);
    537                 free(dev_data);
    538         }
    539 }
    540 
    541 void create_pci_dev_name(device_t *dev)
    542 {
    543         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
     556        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     557}
     558
     559pci_fun_t *pci_fun_new(pci_bus_t *bus)
     560{
     561        pci_fun_t *fun;
     562       
     563        fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
     564        if (fun == NULL)
     565                return NULL;
     566
     567        fun->busptr = bus;
     568        return fun;
     569}
     570
     571void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn)
     572{
     573        fun->bus = bus;
     574        fun->dev = dev;
     575        fun->fn = fn;
     576}
     577
     578void pci_fun_delete(pci_fun_t *fun)
     579{
     580        assert(fun != NULL);
     581        hw_res_clean_resource_list(&fun->hw_resources);
     582        free(fun);
     583}
     584
     585char *pci_fun_create_name(pci_fun_t *fun)
     586{
    544587        char *name = NULL;
    545588       
    546         asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev,
    547             dev_data->fn);
    548         dev->name = name;
    549 }
    550 
    551 bool pci_alloc_resource_list(device_t *dev)
    552 {
    553         pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
    554        
    555         dev_data->hw_resources.resources =
     589        asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev,
     590            fun->fn);
     591        return name;
     592}
     593
     594bool pci_alloc_resource_list(pci_fun_t *fun)
     595{
     596        fun->hw_resources.resources =
    556597            (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t));
    557         return dev_data->hw_resources.resources != NULL;
    558 }
    559 
    560 void pci_clean_resource_list(device_t *dev)
    561 {
    562         pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
    563        
    564         if (dev_data->hw_resources.resources != NULL) {
    565                 free(dev_data->hw_resources.resources);
    566                 dev_data->hw_resources.resources = NULL;
    567         }
    568 }
    569 
    570 /** Read the base address registers (BARs) of the device and adds the addresses
    571  * to its hw resource list.
     598        return fun->hw_resources.resources != NULL;
     599}
     600
     601void pci_clean_resource_list(pci_fun_t *fun)
     602{
     603        if (fun->hw_resources.resources != NULL) {
     604                free(fun->hw_resources.resources);
     605                fun->hw_resources.resources = NULL;
     606        }
     607}
     608
     609/** Read the base address registers (BARs) of the function and add the addresses
     610 * to its HW resource list.
    572611 *
    573  * @param dev the pci device.
     612 * @param fun   PCI function
    574613 */
    575 void pci_read_bars(device_t *dev)
     614void pci_read_bars(pci_fun_t *fun)
    576615{
    577616        /*
     
    582621       
    583622        while (addr <= PCI_BASE_ADDR_5)
    584                 addr = pci_read_bar(dev, addr);
     623                addr = pci_read_bar(fun, addr);
    585624}
    586625
     
    594633        printf(NAME ": HelenOS pci bus driver (intel method 1).\n");
    595634        pciintel_init();
    596         return driver_main(&pci_driver);
     635        return ddf_driver_main(&pci_driver);
    597636}
    598637
Note: See TracChangeset for help on using the changeset viewer.