Changeset 3a0a4d8 in mainline for uspace/drv/bus


Ignore:
Timestamp:
2013-09-12T07:54:05Z (12 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
95027b5
Parents:
47f5a77 (diff), 64f3d3b (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/bus
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/isa/i8237.c

    r47f5a77 r3a0a4d8  
    3838#include <stdbool.h>
    3939#include <errno.h>
     40#include <ddi.h>
     41#include <ddf/log.h>
    4042#include <fibril_synch.h>
    4143#include <ddi.h>
     
    198200        .channels = {
    199201                /* The first chip 8-bit */
    200                 {
    201                         (uint8_t *) 0x00,
    202                         (uint8_t *) 0x01,
    203                         (uint8_t *) 0x87,
    204                         (uint8_t *) 0x0a,
    205                         (uint8_t *) 0x0b,
    206                         (uint8_t *) 0x0c,
    207                 },
    208                 {
    209                         (uint8_t *) 0x02,
    210                         (uint8_t *) 0x03,
    211                         (uint8_t *) 0x83,
    212                         (uint8_t *) 0x0a,
    213                         (uint8_t *) 0x0b,
    214                         (uint8_t *) 0x0c,
    215                 },
    216                 {
    217                         (uint8_t *) 0x04,
    218                         (uint8_t *) 0x05,
    219                         (uint8_t *) 0x81,
    220                         (uint8_t *) 0x0a,
    221                         (uint8_t *) 0x0b,
    222                         (uint8_t *) 0x0c,
    223                 },
    224                 {
    225                         (uint8_t *) 0x06,
    226                         (uint8_t *) 0x07,
    227                         (uint8_t *) 0x82,
    228                         (uint8_t *) 0x0a,
    229                         (uint8_t *) 0x0b,
    230                         (uint8_t *) 0x0c,
     202                { /* Channel 0 - Unusable*/
     203                        .offset_reg_address = (uint8_t *) 0x00,
     204                        .size_reg_address = (uint8_t *) 0x01,
     205                        .page_reg_address = (uint8_t *) 0x87,
     206                        .single_mask_address = (uint8_t *) 0x0a,
     207                        .mode_address = (uint8_t *) 0x0b,
     208                        .flip_flop_address = (uint8_t *) 0x0c,
     209                },
     210                { /* Channel 1 */
     211                        .offset_reg_address = (uint8_t *) 0x02,
     212                        .size_reg_address = (uint8_t *) 0x03,
     213                        .page_reg_address = (uint8_t *) 0x83,
     214                        .single_mask_address = (uint8_t *) 0x0a,
     215                        .mode_address = (uint8_t *) 0x0b,
     216                        .flip_flop_address = (uint8_t *) 0x0c,
     217                },
     218                { /* Channel 2 */
     219                        .offset_reg_address = (uint8_t *) 0x04,
     220                        .size_reg_address = (uint8_t *) 0x05,
     221                        .page_reg_address = (uint8_t *) 0x81,
     222                        .single_mask_address = (uint8_t *) 0x0a,
     223                        .mode_address = (uint8_t *) 0x0b,
     224                        .flip_flop_address = (uint8_t *) 0x0c,
     225                },
     226                { /* Channel 3 */
     227                        .offset_reg_address = (uint8_t *) 0x06,
     228                        .size_reg_address = (uint8_t *) 0x07,
     229                        .page_reg_address = (uint8_t *) 0x82,
     230                        .single_mask_address = (uint8_t *) 0x0a,
     231                        .mode_address = (uint8_t *) 0x0b,
     232                        .flip_flop_address = (uint8_t *) 0x0c,
    231233                },
    232234               
    233235                /* The second chip 16-bit */
    234                 {
    235                         (uint8_t *) 0xc0,
    236                         (uint8_t *) 0xc2,
    237                         (uint8_t *) 0x8f,
    238                         (uint8_t *) 0xd4,
    239                         (uint8_t *) 0xd6,
    240                         (uint8_t *) 0xd8,
    241                 },
    242                 {
    243                         (uint8_t *) 0xc4,
    244                         (uint8_t *) 0xc6,
    245                         (uint8_t *) 0x8b,
    246                         (uint8_t *) 0xd4,
    247                         (uint8_t *) 0xd6,
    248                         (uint8_t *) 0xd8,
    249                 },
    250                 {
    251                         (uint8_t *) 0xc8,
    252                         (uint8_t *) 0xca,
    253                         (uint8_t *) 0x89,
    254                         (uint8_t *) 0xd4,
    255                         (uint8_t *) 0xd6,
    256                         (uint8_t *) 0xd8,
    257                 },
    258                 {
    259                         (uint8_t *) 0xcc,
    260                         (uint8_t *) 0xce,
    261                         (uint8_t *) 0x8a,
    262                         (uint8_t *) 0xd4,
    263                         (uint8_t *) 0xd6,
    264                         (uint8_t *) 0xd8,
     236                { /* Channel 4 - Unusable */
     237                        .offset_reg_address = (uint8_t *) 0xc0,
     238                        .size_reg_address = (uint8_t *) 0xc2,
     239                        .page_reg_address = (uint8_t *) 0x8f,
     240                        .single_mask_address = (uint8_t *) 0xd4,
     241                        .mode_address = (uint8_t *) 0xd6,
     242                        .flip_flop_address = (uint8_t *) 0xd8,
     243                },
     244                { /* Channel 5 */
     245                        .offset_reg_address = (uint8_t *) 0xc4,
     246                        .size_reg_address = (uint8_t *) 0xc6,
     247                        .page_reg_address = (uint8_t *) 0x8b,
     248                        .single_mask_address = (uint8_t *) 0xd4,
     249                        .mode_address = (uint8_t *) 0xd6,
     250                        .flip_flop_address = (uint8_t *) 0xd8,
     251                },
     252                { /* Channel 6 */
     253                        .offset_reg_address = (uint8_t *) 0xc8,
     254                        .size_reg_address = (uint8_t *) 0xca,
     255                        .page_reg_address = (uint8_t *) 0x89,
     256                        .single_mask_address = (uint8_t *) 0xd4,
     257                        .mode_address = (uint8_t *) 0xd6,
     258                        .flip_flop_address = (uint8_t *) 0xd8,
     259                },
     260                { /* Channel 7 */
     261                        .offset_reg_address = (uint8_t *) 0xcc,
     262                        .size_reg_address = (uint8_t *) 0xce,
     263                        .page_reg_address = (uint8_t *) 0x8a,
     264                        .single_mask_address = (uint8_t *) 0xd4,
     265                        .mode_address = (uint8_t *) 0xd6,
     266                        .flip_flop_address = (uint8_t *) 0xd8,
    265267                },
    266268        },
     
    272274};
    273275
    274 /* Initialize I/O access to DMA controller I/O ports.
     276/** Initialize I/O access to DMA controller I/O ports.
    275277 *
    276278 * @param controller DMA Controller structure to initialize.
     
    304306       
    305307        return EOK;
     308}
     309
     310/** Helper function. Channels 4,5,6, and 7 are 8 bit DMA.
     311 * @pram channel DMA channel.
     312 * @reutrn True, if channel is 4,5,6, or 7, false otherwise.
     313 */
     314static inline bool is_dma16(unsigned channel)
     315{
     316        return (channel >= 4) && (channel < 8);
     317}
     318
     319/** Helper function. Channels 0,1,2, and 3 are 8 bit DMA.
     320 * @pram channel DMA channel.
     321 * @reutrn True, if channel is 0,1,2, or 3, false otherwise.
     322 */
     323static inline bool is_dma8(unsigned channel)
     324{
     325        return (channel < 4);
    306326}
    307327
     
    320340 *
    321341 * @return Error code.
    322  *
    323  */
    324 int dma_setup_channel(unsigned int channel, uint32_t pa, uint16_t size,
     342 */
     343int dma_channel_setup(unsigned int channel, uint32_t pa, uint32_t size,
    325344    uint8_t mode)
    326345{
     346        if (!is_dma8(channel) && !is_dma16(channel))
     347                return ENOENT;
     348
    327349        if ((channel == 0) || (channel == 4))
    328350                return ENOTSUP;
    329        
    330         if (channel > 7)
    331                 return ENOENT;
    332351       
    333352        /* DMA is limited to 24bit addresses. */
     
    336355       
    337356        /* 8 bit channels use only 4 bits from the page register. */
    338         if ((channel > 0) && (channel < 4) && (pa >= (1 << 20)))
     357        if (is_dma8(channel) && (pa >= (1 << 20)))
     358                return EINVAL;
     359
     360        /* Buffers cannot cross 64K page boundaries */
     361        if ((pa & 0xffff0000) != ((pa + size - 1) & 0xffff0000))
    339362                return EINVAL;
    340363       
     
    352375        ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu16 ")",
    353376            pa, size);
    354         if (channel > 4) {
     377        if (is_dma16(channel)) {
    355378                /* Size must be aligned to 16 bits */
    356379                if ((size & 1) != 0) {
     
    358381                        return EINVAL;
    359382                }
    360                
     383                /* Size is in 2byte words */
    361384                size >>= 1;
    362                
    363385                /* Address is fun: lower 16 bits need to be shifted by 1 */
    364386                pa = ((pa & 0xffff) >> 1) | (pa & 0xff0000);
     
    426448}
    427449
     450/** Query remaining buffer size.
     451 *
     452 * @param channel DMA Channel 1, 2, 3 for 8 bit transfers,
     453 *                    5, 6, 7 for 16 bit.
     454 * @param size    Place to store number of bytes pending in the assigned buffer.
     455 *
     456 * @return Error code.
     457 */
     458int dma_channel_remain(unsigned channel, size_t *size)
     459{
     460        assert(size);
     461        if (!is_dma8(channel) && !is_dma16(channel))
     462                return ENOENT;
     463       
     464        if ((channel == 0) || (channel == 4))
     465                return ENOTSUP;
     466       
     467        fibril_mutex_lock(&guard);
     468        if (!controller_8237.initialized) {
     469                fibril_mutex_unlock(&guard);
     470                return EIO;
     471        }
     472
     473        const dma_channel_t dma_channel = controller_8237.channels[channel];
     474        /* Get size - reset flip-flop */
     475        pio_write_8(dma_channel.flip_flop_address, 0);
     476       
     477        /* Low byte */
     478        const uint8_t value_low = pio_read_8(dma_channel.size_reg_address);
     479        ddf_msg(LVL_DEBUG2, "Read size low byte: %p:%x.",
     480            dma_channel.size_reg_address, value_low);
     481       
     482        /* High byte */
     483        const uint8_t value_high = pio_read_8(dma_channel.size_reg_address);
     484        ddf_msg(LVL_DEBUG2, "Read size high byte: %p:%x.",
     485            dma_channel.size_reg_address, value_high);
     486        fibril_mutex_unlock(&guard);
     487
     488        uint16_t remain = (value_high << 8 | value_low) ;
     489        /* 16 bit DMA size is in words,
     490         * the upper bits are bogus for 16bit transfers so we need to get
     491         * rid of them. Using limited type works well.*/
     492        if (is_dma16(channel))
     493                remain <<= 1;
     494        *size =  is_dma16(channel) ? remain + 2: remain + 1;
     495        return EOK;
     496}
    428497/**
    429498 * @}
  • uspace/drv/bus/isa/i8237.h

    r47f5a77 r3a0a4d8  
    3838#define DRV_BUS_ISA_I8237_H
    3939
    40 extern int dma_setup_channel(unsigned int, uint32_t, uint16_t, uint8_t);
     40extern int dma_channel_setup(unsigned, uint32_t, uint32_t, uint8_t);
     41extern int dma_channel_remain(unsigned, size_t *);
    4142
    4243#endif
  • uspace/drv/bus/isa/isa.c

    r47f5a77 r3a0a4d8  
    6767
    6868#include <device/hw_res.h>
     69#include <device/pio_window.h>
    6970
    7071#include "i8237.h"
     
    7980        ddf_dev_t *dev;
    8081        ddf_fun_t *fctl;
     82        pio_window_t pio_win;
    8183        list_t functions;
    8284} isa_bus_t;
     
    8587        fibril_mutex_t mutex;
    8688        ddf_fun_t *fnode;
     89        hw_resource_t resources[ISA_MAX_HW_RES];
    8790        hw_resource_list_t hw_resources;
    8891        link_t bus_link;
     
    103106static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
    104107{
    105         isa_fun_t *fun = isa_fun(fnode);
    106         assert(fun != NULL);
    107 
    108         return &fun->hw_resources;
    109 }
    110 
    111 static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
     108        isa_fun_t *isa = isa_fun(fnode);
     109        assert(isa);
     110
     111        return &isa->hw_resources;
     112}
     113
     114static bool isa_fun_enable_interrupt(ddf_fun_t *fnode)
    112115{
    113116        /* This is an old ugly way, copied from pci driver */
    114117        assert(fnode);
    115         isa_fun_t *fun = isa_fun(fnode);
     118        isa_fun_t *isa = isa_fun(fnode);
     119        assert(isa);
    116120
    117121        sysarg_t apic;
     
    129133                return false;
    130134
    131         const hw_resource_list_t *res = &fun->hw_resources;
     135        const hw_resource_list_t *res = &isa->hw_resources;
    132136        assert(res);
    133137        for (size_t i = 0; i < res->count; ++i) {
     
    151155}
    152156
    153 static int isa_dma_channel_fun_setup(ddf_fun_t *fnode,
    154     unsigned int channel, uint32_t pa, uint16_t size, uint8_t mode)
     157static int isa_fun_setup_dma(ddf_fun_t *fnode,
     158    unsigned int channel, uint32_t pa, uint32_t size, uint8_t mode)
    155159{
    156160        assert(fnode);
    157         isa_fun_t *fun = isa_fun(fnode);
    158         const hw_resource_list_t *res = &fun->hw_resources;
     161        isa_fun_t *isa = isa_fun(fnode);
     162        assert(isa);
     163        const hw_resource_list_t *res = &isa->hw_resources;
    159164        assert(res);
    160        
    161         const unsigned int ch = channel;
     165
    162166        for (size_t i = 0; i < res->count; ++i) {
     167                /* Check for assigned channel */
    163168                if (((res->resources[i].type == DMA_CHANNEL_16) &&
    164                     (res->resources[i].res.dma_channel.dma16 == ch)) ||
     169                    (res->resources[i].res.dma_channel.dma16 == channel)) ||
    165170                    ((res->resources[i].type == DMA_CHANNEL_8) &&
    166                     (res->resources[i].res.dma_channel.dma8 == ch))) {
    167                         return dma_setup_channel(channel, pa, size, mode);
    168                 }
    169         }
    170        
     171                    (res->resources[i].res.dma_channel.dma8 == channel))) {
     172                        return dma_channel_setup(channel, pa, size, mode);
     173                }
     174        }
     175
     176        return EINVAL;
     177}
     178
     179static int isa_fun_remain_dma(ddf_fun_t *fnode,
     180    unsigned channel, size_t *size)
     181{
     182        assert(size);
     183        assert(fnode);
     184        isa_fun_t *isa = isa_fun(fnode);
     185        assert(isa);
     186        const hw_resource_list_t *res = &isa->hw_resources;
     187        assert(res);
     188
     189        for (size_t i = 0; i < res->count; ++i) {
     190                /* Check for assigned channel */
     191                if (((res->resources[i].type == DMA_CHANNEL_16) &&
     192                    (res->resources[i].res.dma_channel.dma16 == channel)) ||
     193                    ((res->resources[i].type == DMA_CHANNEL_8) &&
     194                    (res->resources[i].res.dma_channel.dma8 == channel))) {
     195                        return dma_channel_remain(channel, size);
     196                }
     197        }
     198
    171199        return EINVAL;
    172200}
     
    174202static hw_res_ops_t isa_fun_hw_res_ops = {
    175203        .get_resource_list = isa_get_fun_resources,
    176         .enable_interrupt = isa_enable_fun_interrupt,
    177         .dma_channel_setup = isa_dma_channel_fun_setup,
     204        .enable_interrupt = isa_fun_enable_interrupt,
     205        .dma_channel_setup = isa_fun_setup_dma,
     206        .dma_channel_remain = isa_fun_remain_dma,
    178207};
    179208
    180 static ddf_dev_ops_t isa_fun_ops;
     209static ddf_dev_ops_t isa_fun_ops= {
     210        .interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops,
     211};
    181212
    182213static int isa_dev_add(ddf_dev_t *dev);
     
    212243
    213244        fibril_mutex_initialize(&fun->mutex);
     245        fun->hw_resources.resources = fun->resources;
     246
    214247        fun->fnode = fnode;
    215248        return fun;
     
    270303{
    271304        char *line = str;
     305        *next = NULL;
    272306
    273307        if (str == NULL) {
    274                 *next = NULL;
    275308                return NULL;
    276309        }
     
    282315        if (*str != '\0') {
    283316                *next = str + 1;
    284         } else {
    285                 *next = NULL;
    286317        }
    287318
     
    310341        /* Get the name part of the rest of the line. */
    311342        strtok(line, ":");
    312 
    313         /* Allocate output buffer. */
    314         size_t size = str_size(line) + 1;
    315         char *name = malloc(size);
    316 
    317         if (name != NULL) {
    318                 /* Copy the result to the output buffer. */
    319                 str_cpy(name, size, line);
    320         }
    321 
    322         return name;
    323 }
    324 
    325 static inline char *skip_spaces(char *line)
     343        return line;
     344}
     345
     346static inline const char *skip_spaces(const char *line)
    326347{
    327348        /* Skip leading spaces. */
     
    332353}
    333354
    334 static void isa_fun_set_irq(isa_fun_t *fun, int irq)
     355static void isa_fun_add_irq(isa_fun_t *fun, int irq)
    335356{
    336357        size_t count = fun->hw_resources.count;
     
    348369}
    349370
    350 static void isa_fun_set_dma(isa_fun_t *fun, int dma)
     371static void isa_fun_add_dma(isa_fun_t *fun, int dma)
    351372{
    352373        size_t count = fun->hw_resources.count;
     
    381402}
    382403
    383 static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
     404static void isa_fun_add_io_range(isa_fun_t *fun, size_t addr, size_t len)
    384405{
    385406        size_t count = fun->hw_resources.count;
    386407        hw_resource_t *resources = fun->hw_resources.resources;
     408
     409        isa_bus_t *isa = isa_bus(ddf_fun_get_dev(fun->fnode));
    387410
    388411        if (count < ISA_MAX_HW_RES) {
    389412                resources[count].type = IO_RANGE;
    390413                resources[count].res.io_range.address = addr;
     414                resources[count].res.io_range.address += isa->pio_win.io.base;
    391415                resources[count].res.io_range.size = len;
    392416                resources[count].res.io_range.endianness = LITTLE_ENDIAN;
     
    400424}
    401425
    402 static void fun_parse_irq(isa_fun_t *fun, char *val)
     426static void fun_parse_irq(isa_fun_t *fun, const char *val)
    403427{
    404428        int irq = 0;
     
    409433
    410434        if (val != end)
    411                 isa_fun_set_irq(fun, irq);
    412 }
    413 
    414 static void fun_parse_dma(isa_fun_t *fun, char *val)
    415 {
    416         unsigned int dma = 0;
     435                isa_fun_add_irq(fun, irq);
     436}
     437
     438static void fun_parse_dma(isa_fun_t *fun, const char *val)
     439{
    417440        char *end = NULL;
    418441       
    419442        val = skip_spaces(val);
    420         dma = (unsigned int) strtol(val, &end, 10);
     443        const int dma = strtol(val, &end, 10);
    421444       
    422445        if (val != end)
    423                 isa_fun_set_dma(fun, dma);
    424 }
    425 
    426 static void fun_parse_io_range(isa_fun_t *fun, char *val)
     446                isa_fun_add_dma(fun, dma);
     447}
     448
     449static void fun_parse_io_range(isa_fun_t *fun, const char *val)
    427450{
    428451        size_t addr, len;
     
    441464                return;
    442465
    443         isa_fun_set_io_range(fun, addr, len);
    444 }
    445 
    446 static void get_match_id(char **id, char *val)
    447 {
    448         char *end = val;
     466        isa_fun_add_io_range(fun, addr, len);
     467}
     468
     469static void get_match_id(char **id, const char *val)
     470{
     471        const char *end = val;
    449472
    450473        while (!isspace(*end))
     
    456479}
    457480
    458 static void fun_parse_match_id(isa_fun_t *fun, char *val)
     481static void fun_parse_match_id(isa_fun_t *fun, const char *val)
    459482{
    460483        char *id = NULL;
    461         int score = 0;
    462484        char *end = NULL;
    463         int rc;
    464485
    465486        val = skip_spaces(val);
    466487
    467         score = (int)strtol(val, &end, 10);
     488        int score = (int)strtol(val, &end, 10);
    468489        if (val == end) {
    469490                ddf_msg(LVL_ERROR, "Cannot read match score for function "
     
    483504            "function %s", id, score, ddf_fun_get_name(fun->fnode));
    484505
    485         rc = ddf_fun_add_match_id(fun->fnode, id, score);
     506        int rc = ddf_fun_add_match_id(fun->fnode, id, score);
    486507        if (rc != EOK) {
    487508                ddf_msg(LVL_ERROR, "Failed adding match ID: %s",
     
    492513}
    493514
    494 static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
    495     void (*read_fn)(isa_fun_t *, char *))
     515static bool prop_parse(isa_fun_t *fun, const char *line, const char *prop,
     516    void (*read_fn)(isa_fun_t *, const char *))
    496517{
    497518        size_t proplen = str_size(prop);
     
    508529}
    509530
    510 static void fun_prop_parse(isa_fun_t *fun, char *line)
     531static void fun_prop_parse(isa_fun_t *fun, const char *line)
    511532{
    512533        /* Skip leading spaces. */
     
    523544}
    524545
    525 static void fun_hw_res_alloc(isa_fun_t *fun)
    526 {
    527         fun->hw_resources.resources =
    528             (hw_resource_t *) malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
    529 }
    530 
    531 static void fun_hw_res_free(isa_fun_t *fun)
    532 {
    533         free(fun->hw_resources.resources);
    534         fun->hw_resources.resources = NULL;
    535 }
    536 
    537546static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa)
    538547{
    539548        char *line;
    540         char *fun_name = NULL;
    541549
    542550        /* Skip empty lines. */
    543         while (true) {
     551        do {
    544552                line = str_get_line(fun_conf, &fun_conf);
    545553
     
    549557                }
    550558
    551                 if (!line_empty(line))
    552                         break;
    553         }
     559        } while (line_empty(line));
    554560
    555561        /* Get device name. */
    556         fun_name = get_device_name(line);
     562        const char *fun_name = get_device_name(line);
    557563        if (fun_name == NULL)
    558564                return NULL;
    559565
    560566        isa_fun_t *fun = isa_fun_create(isa, fun_name);
    561         free(fun_name);
    562567        if (fun == NULL) {
    563568                return NULL;
    564569        }
    565 
    566         /* Allocate buffer for the list of hardware resources of the device. */
    567         fun_hw_res_alloc(fun);
    568570
    569571        /* Get properties of the device (match ids, irq and io range). */
     
    596598}
    597599
    598 static void fun_conf_parse(char *conf, isa_bus_t *isa)
    599 {
     600static void isa_functions_add(isa_bus_t *isa)
     601{
     602        char *conf = fun_conf_read(CHILD_FUN_CONF_PATH);
    600603        while (conf != NULL && *conf != '\0') {
    601604                conf = isa_fun_read_info(conf, isa);
    602605        }
    603 }
    604 
    605 static void isa_functions_add(isa_bus_t *isa)
    606 {
    607         char *fun_conf;
    608 
    609         fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
    610         if (fun_conf != NULL) {
    611                 fun_conf_parse(fun_conf, isa);
    612                 free(fun_conf);
    613         }
     606        free(conf);
    614607}
    615608
    616609static int isa_dev_add(ddf_dev_t *dev)
    617610{
    618         isa_bus_t *isa;
     611        async_sess_t *sess;
     612        int rc;
    619613
    620614        ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
    621615            (int) ddf_dev_get_handle(dev));
    622616
    623         isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
     617        isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
    624618        if (isa == NULL)
    625619                return ENOMEM;
     
    628622        isa->dev = dev;
    629623        list_initialize(&isa->functions);
     624
     625        sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
     626        if (sess == NULL) {
     627                ddf_msg(LVL_ERROR, "isa_dev_add failed to connect to the "
     628                    "parent driver.");
     629                return ENOENT;
     630        }
     631
     632        rc = pio_window_get(sess, &isa->pio_win);
     633        if (rc != EOK) {
     634                ddf_msg(LVL_ERROR, "isa_dev_add failed to get PIO window "
     635                    "for the device.");
     636                return rc;
     637        }       
    630638
    631639        /* Make the bus device more visible. Does not do anything. */
     
    658666{
    659667        isa_bus_t *isa = isa_bus(dev);
    660         int rc;
    661668
    662669        fibril_mutex_lock(&isa->mutex);
     
    666673                    isa_fun_t, bus_link);
    667674
    668                 rc = ddf_fun_offline(fun->fnode);
     675                int rc = ddf_fun_offline(fun->fnode);
    669676                if (rc != EOK) {
    670677                        fibril_mutex_unlock(&isa->mutex);
     
    682689                list_remove(&fun->bus_link);
    683690
    684                 fun_hw_res_free(fun);
    685691                ddf_fun_destroy(fun->fnode);
    686692        }
     
    709715}
    710716
    711 
    712 static void isa_init()
    713 {
     717int main(int argc, char *argv[])
     718{
     719        printf(NAME ": HelenOS ISA bus driver\n");
    714720        ddf_log_init(NAME);
    715         isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
    716 }
    717 
    718 int main(int argc, char *argv[])
    719 {
    720         printf(NAME ": HelenOS ISA bus driver\n");
    721         isa_init();
    722721        return ddf_driver_main(&isa_driver);
    723722}
  • uspace/drv/bus/pci/pciintel/pci.c

    r47f5a77 r3a0a4d8  
    5757#include <ops/hw_res.h>
    5858#include <device/hw_res.h>
     59#include <ops/pio_window.h>
     60#include <device/pio_window.h>
    5961#include <ddi.h>
    6062#include <pci_dev_iface.h>
     
    141143}
    142144
     145static pio_window_t *pciintel_get_pio_window(ddf_fun_t *fnode)
     146{
     147        pci_fun_t *fun = pci_fun(fnode);
     148       
     149        if (fun == NULL)
     150                return NULL;
     151        return &fun->pio_window;
     152}
     153
     154
    143155static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address,
    144156    uint32_t data)
     
    198210        .get_resource_list = &pciintel_get_resources,
    199211        .enable_interrupt = &pciintel_enable_interrupt,
     212};
     213
     214static pio_window_ops_t pciintel_pio_window_ops = {
     215        .get_pio_window = &pciintel_get_pio_window
    200216};
    201217
     
    211227static ddf_dev_ops_t pci_fun_ops = {
    212228        .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops,
     229        .interfaces[PIO_WINDOW_DEV_IFACE] = &pciintel_pio_window_ops,
    213230        .interfaces[PCI_DEV_IFACE] = &pci_dev_ops
    214231};
     
    233250static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    234251{
     252        const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
    235253        pci_bus_t *bus = pci_bus_from_fun(fun);
     254        uint32_t val;
    236255       
    237256        fibril_mutex_lock(&bus->conf_mutex);
    238        
    239         const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
    240         void *addr = bus->conf_data_port + (reg & 3);
    241        
     257
    242258        pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
    243        
     259
     260        /*
     261         * Always read full 32-bits from the PCI conf_data_port register and
     262         * get the desired portion of it afterwards. Some architectures do not
     263         * support shorter PIO reads offset from this register.
     264         */
     265        val = uint32_t_le2host(pio_read_32(bus->conf_data_port));
     266
    244267        switch (len) {
    245268        case 1:
    246                 /* No endianness change for 1 byte */
    247                 buf[0] = pio_read_8(addr);
     269                *buf = (uint8_t) (val >> ((reg & 3) * 8));
    248270                break;
    249271        case 2:
    250                 ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr));
     272                *((uint16_t *) buf) = (uint16_t) (val >> ((reg & 3)) * 8);
    251273                break;
    252274        case 4:
    253                 ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr));
     275                *((uint32_t *) buf) = (uint32_t) val;
    254276                break;
    255277        }
     
    260282static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
    261283{
     284        const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
    262285        pci_bus_t *bus = pci_bus_from_fun(fun);
     286        uint32_t val;
    263287       
    264288        fibril_mutex_lock(&bus->conf_mutex);
    265        
    266         const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
    267         void *addr = bus->conf_data_port + (reg & 3);
    268        
    269         pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
     289
     290        /*
     291         * Prepare to write full 32-bits to the PCI conf_data_port register.
     292         * Some architectures do not support shorter PIO writes offset from this
     293         * register.
     294         */
     295
     296        if (len < 4) {
     297                /*
     298                 * We have fewer than full 32-bits, so we need to read the
     299                 * missing bits first.
     300                 */
     301                pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
     302                val = uint32_t_le2host(pio_read_32(bus->conf_data_port));
     303        }
    270304       
    271305        switch (len) {
    272306        case 1:
    273                 /* No endianness change for 1 byte */
    274                 pio_write_8(addr, buf[0]);
     307                val &= ~(0xffU << ((reg & 3) * 8));
     308                val |= *buf << ((reg & 3) * 8);
    275309                break;
    276310        case 2:
    277                 pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0]));
     311                val &= ~(0xffffU << ((reg & 3) * 8));
     312                val |= *((uint16_t *) buf) << ((reg & 3) * 8);
    278313                break;
    279314        case 4:
    280                 pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0]));
     315                val = *((uint32_t *) buf);
    281316                break;
    282317        }
     318
     319        pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));
     320        pio_write_32(bus->conf_data_port, host2uint32_t_le(val));
    283321       
    284322        fibril_mutex_unlock(&bus->conf_mutex);
     
    433471{
    434472        /* Value of the BAR */
    435         uint32_t val, mask;
     473        uint32_t val;
     474        uint32_t bar;
     475        uint32_t mask;
     476
    436477        /* IO space address */
    437478        bool io;
     
    471512        /* Get the address mask. */
    472513        pci_conf_write_32(fun, addr, 0xffffffff);
    473         mask &= pci_conf_read_32(fun, addr);
    474        
     514        bar = pci_conf_read_32(fun, addr);
     515
     516        /*
     517         * Unimplemented BARs read back as all 0's.
     518         */
     519        if (!bar)
     520                return addr + (addrw64 ? 8 : 4);
     521
     522        mask &= bar;   
     523
    475524        /* Restore the original value. */
    476525        pci_conf_write_32(fun, addr, val);
     
    520569{
    521570        uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE);
    522         if (irq != 0xff)
     571        uint8_t pin = pci_conf_read_8(fun, PCI_BRIDGE_INT_PIN);
     572
     573        if (pin != 0 && irq != 0xff)
    523574                pci_add_interrupt(fun, irq);
    524575}
     
    583634                        pci_read_bars(fun);
    584635                        pci_read_interrupt(fun);
     636
     637                        /* Propagate the PIO window to the function. */
     638                        fun->pio_window = bus->pio_win;
    585639                       
    586640                        ddf_fun_set_ops(fun->fnode, &pci_fun_ops);
     
    613667static int pci_dev_add(ddf_dev_t *dnode)
    614668{
     669        hw_resource_list_t hw_resources;
    615670        pci_bus_t *bus = NULL;
    616671        ddf_fun_t *ctl = NULL;
     
    638693                goto fail;
    639694        }
    640        
    641         hw_resource_list_t hw_resources;
     695
     696        rc = pio_window_get(sess, &bus->pio_win);
     697        if (rc != EOK) {
     698                ddf_msg(LVL_ERROR, "pci_dev_add failed to get PIO window "
     699                    "for the device.");
     700                goto fail;
     701        }
    642702       
    643703        rc = hw_res_get_resource_list(sess, &hw_resources);
     
    729789{
    730790        ddf_log_init(NAME);
    731         pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
    732         pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    733791}
    734792
  • uspace/drv/bus/pci/pciintel/pci.h

    r47f5a77 r3a0a4d8  
    4040#include "pci_regs.h"
    4141
    42 #define PCI_MAX_HW_RES 8
     42#define PCI_MAX_HW_RES 10
    4343
    4444typedef struct pciintel_bus {
     
    4949        void *conf_data_port;
    5050        void *conf_addr_port;
     51        pio_window_t pio_win;
    5152        fibril_mutex_t conf_mutex;
    5253} pci_bus_t;
     
    6869        hw_resource_list_t hw_resources;
    6970        hw_resource_t resources[PCI_MAX_HW_RES];
     71        pio_window_t pio_window;
    7072} pci_fun_t;
    7173
  • uspace/drv/bus/usb/uhci/utils/malloc32.h

    r47f5a77 r3a0a4d8  
    9292 */
    9393static inline void free32(void *addr)
    94         { free(addr); }
     94{
     95        free(addr);
     96}
    9597
    9698/** Create 4KB page mapping
     
    98100 * @return Address of the mapped page, NULL on failure.
    99101 */
    100 static inline void * get_page(void)
     102static inline void *get_page(void)
    101103{
    102         void *address, *phys;
     104        uintptr_t phys;
     105        void *address;
     106       
    103107        const int ret = dmamem_map_anonymous(UHCI_REQUIRED_PAGE_SIZE,
    104             AS_AREA_READ | AS_AREA_WRITE, 0, &phys, &address);
    105         return ret == EOK ? address : NULL;
     108            DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
     109            &address);
     110       
     111        return ((ret == EOK) ? address : NULL);
    106112}
    107113
  • uspace/drv/bus/usb/usbmid/explore.c

    r47f5a77 r3a0a4d8  
    5656static bool interface_in_list(const list_t *list, int interface_no)
    5757{
    58         list_foreach(*list, l) {
    59                 usbmid_interface_t *iface = usbmid_interface_from_link(l);
     58        list_foreach(*list, link, usbmid_interface_t, iface) {
    6059                if (iface->interface_no == interface_no) {
    6160                        return true;
     
    190189
    191190        /* Start child function for every interface. */
    192         list_foreach(usb_mid->interface_list, link) {
    193                 usbmid_interface_t *iface = usbmid_interface_from_link(link);
    194 
     191        list_foreach(usb_mid->interface_list, link, usbmid_interface_t, iface) {
    195192                usb_log_info("Creating child for interface %d (%s).\n",
    196193                    iface->interface_no,
  • uspace/drv/bus/usb/usbmid/usbmid.c

    r47f5a77 r3a0a4d8  
    135135        }
    136136
    137         list_foreach(match_ids.ids, link) {
    138                 match_id_t *match_id = list_get_instance(link, match_id_t, link);
     137        list_foreach(match_ids.ids, link, match_id_t, match_id) {
    139138                rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
    140139                if (rc != EOK) {
  • uspace/drv/bus/usb/vhc/transfer.c

    r47f5a77 r3a0a4d8  
    9292
    9393        bool target_found = false;
    94         list_foreach(vhc->devices, pos) {
    95                 vhc_virtdev_t *dev = list_get_instance(pos, vhc_virtdev_t, link);
     94        list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
    9695                fibril_mutex_lock(&dev->guard);
    9796                if (dev->address == transfer->address) {
Note: See TracChangeset for help on using the changeset viewer.