Changeset 68414f4a in mainline for uspace/drv/pciintel/pci.c


Ignore:
Timestamp:
2011-02-13T20:03:45Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bab6388
Parents:
8b1e15ac
Message:

Refactor drivers

  • Rename soft-state structures to have the simplest names
  • Use soft-state structures as a starting point instead of DDF device or function nodes
  • Convert to standard naming scheme
File:
1 edited

Legend:

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

    r8b1e15ac r68414f4a  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    6162        ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
    6263
    63 static hw_resource_list_t *pciintel_get_child_resources(function_t *fun)
    64 {
    65         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    66        
    67         if (fun_data == NULL)
     64/** Obtain PCI function soft-state from DDF function node */
     65#define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
     66
     67/** Obtain PCI bus soft-state from DDF device node */
     68#define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
     69
     70/** Obtain PCI bus soft-state from function soft-state */
     71#define PCI_BUS_FROM_FUN(fun) (PCI_BUS(fun->fnode->dev))
     72
     73static hw_resource_list_t *pciintel_get_resources(function_t *fnode)
     74{
     75        pci_fun_t *fun = PCI_FUN(fnode);
     76       
     77        if (fun == NULL)
    6878                return NULL;
    69         return &fun_data->hw_resources;
    70 }
    71 
    72 static bool pciintel_enable_child_interrupt(function_t *fun)
     79        return &fun->hw_resources;
     80}
     81
     82static bool pciintel_enable_interrupt(function_t *fnode)
    7383{
    7484        /* TODO */
     
    7787}
    7888
    79 static hw_res_ops_t pciintel_child_hw_res_ops = {
    80         &pciintel_get_child_resources,
    81         &pciintel_enable_child_interrupt
     89static hw_res_ops_t pciintel_hw_res_ops = {
     90        &pciintel_get_resources,
     91        &pciintel_enable_interrupt
    8292};
    8393
    84 static device_ops_t pci_child_ops;
     94static device_ops_t pci_fun_ops;
    8595
    8696static int pci_add_device(device_t *);
    8797
    88 /** The pci bus driver's standard operations. */
     98/** PCI bus driver standard operations */
    8999static driver_ops_t pci_ops = {
    90100        .add_device = &pci_add_device
    91101};
    92102
    93 /** The pci bus driver structure. */
     103/** PCI bus driver structure */
    94104static driver_t pci_driver = {
    95105        .name = NAME,
     
    97107};
    98108
    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(function_t *fun, int reg, uint8_t *buf, size_t len)
    125 {
    126         assert(fun->dev != NULL);
    127        
    128         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    129         pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data;
    130        
    131         fibril_mutex_lock(&bus_data->conf_mutex);
     109static pci_bus_t *pci_bus_new(void)
     110{
     111        pci_bus_t *bus;
     112       
     113        bus = (pci_bus_t *) malloc(sizeof(pci_bus_t));
     114        if (bus != NULL) {
     115                memset(bus, 0, sizeof(pci_bus_t));
     116                fibril_mutex_initialize(&bus->conf_mutex);
     117        }
     118
     119        return bus;
     120}
     121
     122static void pci_bus_delete(pci_bus_t *bus)
     123{
     124        free(bus);
     125}
     126
     127static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     128{
     129        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     130       
     131        fibril_mutex_lock(&bus->conf_mutex);
    132132       
    133133        uint32_t conf_addr;
    134         conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_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);
     134        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     135        void *addr = bus->conf_data_port + (reg & 3);
     136       
     137        pio_write_32(bus->conf_addr_port, conf_addr);
    138138       
    139139        switch (len) {
     
    149149        }
    150150       
    151         fibril_mutex_unlock(&bus_data->conf_mutex);
    152 }
    153 
    154 static void pci_conf_write(function_t *fun, int reg, uint8_t *buf, size_t len)
    155 {
    156         assert(fun->dev != NULL);
    157        
    158         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    159         pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data;
    160        
    161         fibril_mutex_lock(&bus_data->conf_mutex);
     151        fibril_mutex_unlock(&bus->conf_mutex);
     152}
     153
     154static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
     155{
     156        pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
     157       
     158        fibril_mutex_lock(&bus->conf_mutex);
    162159       
    163160        uint32_t conf_addr;
    164         conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_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);
     161        conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
     162        void *addr = bus->conf_data_port + (reg & 3);
     163       
     164        pio_write_32(bus->conf_addr_port, conf_addr);
    168165       
    169166        switch (len) {
     
    179176        }
    180177       
    181         fibril_mutex_unlock(&bus_data->conf_mutex);
    182 }
    183 
    184 uint8_t pci_conf_read_8(function_t *fun, int reg)
     178        fibril_mutex_unlock(&bus->conf_mutex);
     179}
     180
     181uint8_t pci_conf_read_8(pci_fun_t *fun, int reg)
    185182{
    186183        uint8_t res;
     
    189186}
    190187
    191 uint16_t pci_conf_read_16(function_t *fun, int reg)
     188uint16_t pci_conf_read_16(pci_fun_t *fun, int reg)
    192189{
    193190        uint16_t res;
     
    196193}
    197194
    198 uint32_t pci_conf_read_32(function_t *fun, int reg)
     195uint32_t pci_conf_read_32(pci_fun_t *fun, int reg)
    199196{
    200197        uint32_t res;
     
    203200}
    204201
    205 void pci_conf_write_8(function_t *fun, int reg, uint8_t val)
     202void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val)
    206203{
    207204        pci_conf_write(fun, reg, (uint8_t *) &val, 1);
    208205}
    209206
    210 void pci_conf_write_16(function_t *fun, int reg, uint16_t val)
     207void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val)
    211208{
    212209        pci_conf_write(fun, reg, (uint8_t *) &val, 2);
    213210}
    214211
    215 void pci_conf_write_32(function_t *fun, int reg, uint32_t val)
     212void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val)
    216213{
    217214        pci_conf_write(fun, reg, (uint8_t *) &val, 4);
    218215}
    219216
    220 void create_pci_match_ids(function_t *fun)
    221 {
    222         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     217void pci_fun_create_match_ids(pci_fun_t *fun)
     218{
    223219        match_id_t *match_id = NULL;
    224220        char *match_id_str;
     
    227223        if (match_id != NULL) {
    228224                asprintf(&match_id_str, "pci/ven=%04x&dev=%04x",
    229                     fun_data->vendor_id, fun_data->device_id);
     225                    fun->vendor_id, fun->device_id);
    230226                match_id->id = match_id_str;
    231227                match_id->score = 90;
    232                 add_match_id(&fun->match_ids, match_id);
     228                add_match_id(&fun->fnode->match_ids, match_id);
    233229        }
    234230
     
    236232}
    237233
    238 void
    239 pci_add_range(function_t *fun, uint64_t range_addr, size_t range_size, bool io)
    240 {
    241         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    242         hw_resource_list_t *hw_res_list = &fun_data->hw_resources;
     234void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size,
     235    bool io)
     236{
     237        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    243238        hw_resource_t *hw_resources =  hw_res_list->resources;
    244239        size_t count = hw_res_list->count;
     
    265260 * address add it to the devices hw resource list.
    266261 *
    267  * @param dev   The pci device.
     262 * @param fun   PCI function
    268263 * @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.
     264 *              the device
     265 * @return      The addr the address of the BAR which should be read next
    271266 */
    272 int pci_read_bar(function_t *fun, int addr)
     267int pci_read_bar(pci_fun_t *fun, int addr)
    273268{       
    274269        /* Value of the BAR */
     
    322317       
    323318        if (range_addr != 0) {
    324                 printf(NAME ": function %s : ", fun->name);
     319                printf(NAME ": function %s : ", fun->fnode->name);
    325320                printf("address = %" PRIx64, range_addr);
    326321                printf(", size = %x\n", (unsigned int) range_size);
     
    335330}
    336331
    337 void pci_add_interrupt(function_t *fun, int irq)
    338 {
    339         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    340         hw_resource_list_t *hw_res_list = &fun_data->hw_resources;
     332void pci_add_interrupt(pci_fun_t *fun, int irq)
     333{
     334        hw_resource_list_t *hw_res_list = &fun->hw_resources;
    341335        hw_resource_t *hw_resources = hw_res_list->resources;
    342336        size_t count = hw_res_list->count;
     
    350344        hw_res_list->count++;
    351345       
    352         printf(NAME ": function %s uses irq %x.\n", fun->name, irq);
    353 }
    354 
    355 void pci_read_interrupt(function_t *fun)
     346        printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq);
     347}
     348
     349void pci_read_interrupt(pci_fun_t *fun)
    356350{
    357351        uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
     
    362356/** Enumerate (recursively) and register the devices connected to a pci bus.
    363357 *
    364  * @param dev           The host-to-pci bridge device.
    365  * @param bus_num       The bus number.
     358 * @param bus           Host-to-PCI bridge
     359 * @param bus_num       Bus number
    366360 */
    367 void pci_bus_scan(device_t *dev, int bus_num)
    368 {
    369         function_t *fun = create_function();
    370         pci_fun_data_t *fun_data = create_pci_fun_data();
    371         fun->driver_data = fun_data;
     361void pci_bus_scan(pci_bus_t *bus, int bus_num)
     362{
     363        function_t *fnode = create_function();
     364        pci_fun_t *fun = pci_fun_new();
     365        fnode->driver_data = fun;
    372366       
    373367        int child_bus = 0;
     
    377371
    378372        /* We need this early, before registering. */
    379         fun->dev = dev;
     373        fun->fnode = fnode;
     374        fnode->dev = bus->dnode;
     375        fnode->driver_data = fun;
    380376       
    381377        for (dnum = 0; dnum < 32; dnum++) {
    382378                multi = true;
    383379                for (fnum = 0; multi && fnum < 8; fnum++) {
    384                         init_pci_fun_data(fun_data, bus_num, dnum, fnum);
    385                         fun_data->vendor_id = pci_conf_read_16(fun,
     380                        pci_fun_init(fun, bus_num, dnum, fnum);
     381                        fun->vendor_id = pci_conf_read_16(fun,
    386382                            PCI_VENDOR_ID);
    387                         fun_data->device_id = pci_conf_read_16(fun,
     383                        fun->device_id = pci_conf_read_16(fun,
    388384                            PCI_DEVICE_ID);
    389                         if (fun_data->vendor_id == 0xffff) {
     385                        if (fun->vendor_id == 0xffff) {
    390386                                /*
    391387                                 * The device is not present, go on scanning the
     
    406402                        header_type = header_type & 0x7F;
    407403                       
    408                         create_pci_fun_name(fun);
     404                        pci_fun_create_name(fun);
    409405                       
    410406                        pci_alloc_resource_list(fun);
     
    412408                        pci_read_interrupt(fun);
    413409                       
    414                         fun->ftype = fun_inner;
    415                         fun->ops = &pci_child_ops;
     410                        fnode->ftype = fun_inner;
     411                        fnode->ops = &pci_fun_ops;
    416412                       
    417413                        printf(NAME ": adding new function %s.\n",
    418                             fun->name);
    419                        
    420                         create_pci_match_ids(fun);
    421                        
    422                         if (register_function(fun, dev) != EOK) {
     414                            fnode->name);
     415                       
     416                        pci_fun_create_match_ids(fun);
     417                       
     418                        if (register_function(fnode, bus->dnode) != EOK) {
    423419                                pci_clean_resource_list(fun);
    424                                 clean_match_ids(&fun->match_ids);
    425                                 free((char *) fun->name);
    426                                 fun->name = NULL;
     420                                clean_match_ids(&fnode->match_ids);
     421                                free((char *) fnode->name);
     422                                fnode->name = NULL;
    427423                                continue;
    428424                        }
     
    435431                                    "secondary bus number = %d.\n", bus_num);
    436432                                if (child_bus > bus_num)
    437                                         pci_bus_scan(dev, child_bus);
     433                                        pci_bus_scan(bus, child_bus);
    438434                        }
    439435                       
    440436                        /* Alloc new aux. fun. structure. */
    441                         fun = create_function();
     437                        fnode = create_function();
    442438
    443439                        /* We need this early, before registering. */
    444                         fun->dev = dev;
    445 
    446                         fun_data = create_pci_fun_data();
    447                         fun->driver_data = fun_data;
     440                        fnode->dev = bus->dnode;
     441
     442                        fun = pci_fun_new();
     443                        fun->fnode = fnode;
     444                        fnode->driver_data = fun;
    448445                }
    449446        }
    450447       
    451         if (fun_data->vendor_id == 0xffff) {
    452                 delete_function(fun);
     448        if (fun->vendor_id == 0xffff) {
     449                delete_function(fnode);
    453450                /* Free the auxiliary function structure. */
    454                 delete_pci_fun_data(fun_data);
    455         }
    456 }
    457 
    458 static int pci_add_device(device_t *dev)
     451                pci_fun_delete(fun);
     452        }
     453}
     454
     455static int pci_add_device(device_t *dnode)
    459456{
    460457        int rc;
    461 
     458       
    462459        printf(NAME ": pci_add_device\n");
    463460       
    464         pci_bus_data_t *bus_data = create_pci_bus_data();
    465         if (bus_data == NULL) {
     461        pci_bus_t *bus = pci_bus_new();
     462        if (bus == NULL) {
    466463                printf(NAME ": pci_add_device allocation failed.\n");
    467464                return ENOMEM;
    468465        }
    469        
    470         dev->parent_phone = devman_parent_device_connect(dev->handle,
     466        bus->dnode = dnode;
     467        dnode->driver_data = bus;
     468       
     469        dnode->parent_phone = devman_parent_device_connect(dnode->handle,
    471470            IPC_FLAG_BLOCKING);
    472         if (dev->parent_phone < 0) {
     471        if (dnode->parent_phone < 0) {
    473472                printf(NAME ": pci_add_device failed to connect to the "
    474473                    "parent's driver.\n");
    475                 delete_pci_bus_data(bus_data);
    476                 return dev->parent_phone;
     474                pci_bus_delete(bus);
     475                return dnode->parent_phone;
    477476        }
    478477       
    479478        hw_resource_list_t hw_resources;
    480479       
    481         rc = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
     480        rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
    482481        if (rc != EOK) {
    483482                printf(NAME ": pci_add_device failed to get hw resources for "
    484483                    "the device.\n");
    485                 delete_pci_bus_data(bus_data);
    486                 async_hangup(dev->parent_phone);
     484                pci_bus_delete(bus);
     485                async_hangup(dnode->parent_phone);
    487486                return rc;
    488487        }       
     
    495494        assert(hw_resources.resources[0].res.io_range.size == 8);
    496495       
    497         bus_data->conf_io_addr =
     496        bus->conf_io_addr =
    498497            (uint32_t) hw_resources.resources[0].res.io_range.address;
    499498       
    500         if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8,
    501             &bus_data->conf_addr_port)) {
     499        if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
     500            &bus->conf_addr_port)) {
    502501                printf(NAME ": failed to enable configuration ports.\n");
    503                 delete_pci_bus_data(bus_data);
    504                 async_hangup(dev->parent_phone);
     502                pci_bus_delete(bus);
     503                async_hangup(dnode->parent_phone);
    505504                hw_res_clean_resource_list(&hw_resources);
    506505                return EADDRNOTAVAIL;
    507506        }
    508         bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4;
    509        
    510         dev->driver_data = bus_data;
    511        
    512         /* Make the bus device more visible. Does not do anything. */
     507        bus->conf_data_port = (char *) bus->conf_addr_port + 4;
     508       
     509        /* Make the bus device more visible. It has no use yet. */
    513510        printf(NAME ": adding a 'ctl' function\n");
    514 
     511       
    515512        function_t *ctl = create_function();
    516513        ctl->ftype = fun_exposed;
    517514        ctl->name = "ctl";
    518         register_function(ctl, dev);
    519        
    520         /* Enumerate child devices. */
     515        register_function(ctl, dnode);
     516       
     517        /* Enumerate functions. */
    521518        printf(NAME ": scanning the bus\n");
    522         pci_bus_scan(dev, 0);
     519        pci_bus_scan(bus, 0);
    523520       
    524521        hw_res_clean_resource_list(&hw_resources);
     
    529526static void pciintel_init(void)
    530527{
    531         pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops;
    532 }
    533 
    534 pci_fun_data_t *create_pci_fun_data(void)
    535 {
    536         pci_fun_data_t *res = (pci_fun_data_t *) malloc(sizeof(pci_fun_data_t));
     528        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     529}
     530
     531pci_fun_t *pci_fun_new(void)
     532{
     533        pci_fun_t *res = (pci_fun_t *) malloc(sizeof(pci_fun_t));
    537534       
    538535        if (res != NULL)
    539                 memset(res, 0, sizeof(pci_fun_data_t));
     536                memset(res, 0, sizeof(pci_fun_t));
    540537        return res;
    541538}
    542539
    543 void init_pci_fun_data(pci_fun_data_t *fun_data, int bus, int dev, int fn)
    544 {
    545         fun_data->bus = bus;
    546         fun_data->dev = dev;
    547         fun_data->fn = fn;
    548 }
    549 
    550 void delete_pci_fun_data(pci_fun_data_t *fun_data)
    551 {
    552         if (fun_data != NULL) {
    553                 hw_res_clean_resource_list(&fun_data->hw_resources);
    554                 free(fun_data);
    555         }
    556 }
    557 
    558 void create_pci_fun_name(function_t *fun)
    559 {
    560         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
     540void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn)
     541{
     542        fun->bus = bus;
     543        fun->dev = dev;
     544        fun->fn = fn;
     545}
     546
     547void pci_fun_delete(pci_fun_t *fun)
     548{
     549        if (fun != NULL) {
     550                hw_res_clean_resource_list(&fun->hw_resources);
     551                free(fun);
     552        }
     553}
     554
     555void pci_fun_create_name(pci_fun_t *fun)
     556{
    561557        char *name = NULL;
    562558       
    563         asprintf(&name, "%02x:%02x.%01x", fun_data->bus, fun_data->dev,
    564             fun_data->fn);
    565         fun->name = name;
    566 }
    567 
    568 bool pci_alloc_resource_list(function_t *fun)
    569 {
    570         pci_fun_data_t *fun_data = (pci_fun_data_t *)fun->driver_data;
    571        
    572         fun_data->hw_resources.resources =
     559        asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev,
     560            fun->fn);
     561        fun->fnode->name = name;
     562}
     563
     564bool pci_alloc_resource_list(pci_fun_t *fun)
     565{
     566        fun->hw_resources.resources =
    573567            (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t));
    574         return fun_data->hw_resources.resources != NULL;
    575 }
    576 
    577 void pci_clean_resource_list(function_t *fun)
    578 {
    579         pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data;
    580        
    581         if (fun_data->hw_resources.resources != NULL) {
    582                 free(fun_data->hw_resources.resources);
    583                 fun_data->hw_resources.resources = NULL;
    584         }
    585 }
    586 
    587 /** Read the base address registers (BARs) of the device and adds the addresses
    588  * to its hw resource list.
     568        return fun->hw_resources.resources != NULL;
     569}
     570
     571void pci_clean_resource_list(pci_fun_t *fun)
     572{
     573        if (fun->hw_resources.resources != NULL) {
     574                free(fun->hw_resources.resources);
     575                fun->hw_resources.resources = NULL;
     576        }
     577}
     578
     579/** Read the base address registers (BARs) of the function and add the addresses
     580 * to its HW resource list.
    589581 *
    590  * @param dev the pci device.
     582 * @param fun   PCI function
    591583 */
    592 void pci_read_bars(function_t *fun)
     584void pci_read_bars(pci_fun_t *fun)
    593585{
    594586        /*
Note: See TracChangeset for help on using the changeset viewer.