Changes in / [786bd56:304faab] in mainline


Ignore:
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/interrupt.h

    r786bd56 r304faab  
    5555#define IRQ_PIC_SPUR  7
    5656#define IRQ_MOUSE     12
     57#define IRQ_NE2000    9
    5758
    5859/* This one must have four least significant bits set to ones */
  • kernel/arch/amd64/src/amd64.c

    r786bd56 r304faab  
    214214                }
    215215        }
     216       
     217        /*
     218         * This is the necessary evil until the userspace driver is entirely
     219         * self-sufficient.
     220         */
     221        sysinfo_set_item_val("i8042", NULL, true);
     222        sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD);
     223        sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE);
     224        sysinfo_set_item_val("i8042.address.physical", NULL,
     225            (uintptr_t) I8042_BASE);
     226        sysinfo_set_item_val("i8042.address.kernel", NULL,
     227            (uintptr_t) I8042_BASE);
    216228#endif
    217229       
    218230        if (irqs_info != NULL)
    219231                sysinfo_set_item_val(irqs_info, NULL, true);
     232       
     233        sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
    220234}
    221235
  • kernel/arch/ia32/include/interrupt.h

    r786bd56 r304faab  
    5555#define IRQ_PIC_SPUR  7
    5656#define IRQ_MOUSE     12
     57#define IRQ_NE2000    5
    5758
    5859/* This one must have four least significant bits set to ones */
  • kernel/arch/ia32/src/ia32.c

    r786bd56 r304faab  
    168168                }
    169169        }
     170       
     171        /*
     172         * This is the necessary evil until the userspace driver is entirely
     173         * self-sufficient.
     174         */
     175        sysinfo_set_item_val("i8042", NULL, true);
     176        sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD);
     177        sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE);
     178        sysinfo_set_item_val("i8042.address.physical", NULL,
     179            (uintptr_t) I8042_BASE);
     180        sysinfo_set_item_val("i8042.address.kernel", NULL,
     181            (uintptr_t) I8042_BASE);
    170182#endif
    171183       
    172184        if (irqs_info != NULL)
    173185                sysinfo_set_item_val(irqs_info, NULL, true);
     186       
     187        sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
    174188}
    175189
  • kernel/arch/ia64/include/interrupt.h

    r786bd56 r304faab  
    6161#define IRQ_KBD    (0x01 + LEGACY_INTERRUPT_BASE)
    6262#define IRQ_MOUSE  (0x0c + LEGACY_INTERRUPT_BASE)
     63#define IRQ_NE2000 (0x09 + LEGACY_INTERRUPT_BASE)
    6364
    6465/** General Exception codes. */
  • kernel/arch/ia64/src/ia64.c

    r786bd56 r304faab  
    188188       
    189189#ifdef CONFIG_I8042
    190         i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE,
    191             IRQ_KBD);
     190        i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
    192191        if (i8042_instance) {
    193192                kbrd_instance_t *kbrd_instance = kbrd_init();
     
    198197                }
    199198        }
    200 #endif
    201        
     199       
     200        sysinfo_set_item_val("i8042", NULL, true);
     201        sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD);
     202        sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE);
     203        sysinfo_set_item_val("i8042.address.physical", NULL,
     204            (uintptr_t) I8042_BASE);
     205        sysinfo_set_item_val("i8042.address.kernel", NULL,
     206            (uintptr_t) I8042_BASE);
     207#endif
     208
     209        sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
     210
    202211        sysinfo_set_item_val("ia64_iospace", NULL, true);
    203212        sysinfo_set_item_val("ia64_iospace.address", NULL, true);
  • uspace/drv/bus/isa/isa.dev

    r786bd56 r304faab  
    1414        irq 12
    1515        io_range 060 5
     16       
    1617
    1718ne2k:
  • uspace/drv/bus/isa/isa.ma

    r786bd56 r304faab  
    1 9 pci/class=06&subclass=01
     19 pci/ven=8086&dev=7000
  • uspace/drv/bus/pci/pciintel/pci.c

    r786bd56 r304faab  
    9292static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
    9393{
    94         /* This is an old ugly way */
     94        /* This is an old ugly way, copied from ne2000 driver */
    9595        assert(fnode);
    9696        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
  • uspace/drv/char/i8042/buffer.h

    r786bd56 r304faab  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    2928/**
    3029 * @addtogroup kbd
    3130 * @{
    3231 */
    33 
    3432/** @file
    3533 * @brief Cyclic buffer structure.
     
    4846 * Attempt to insert byte into the full buffer will block until it can succeed.
    4947 * Attempt to read from empty buffer will block until it can succeed.
    50  *
    5148 */
    5249typedef struct {
    53         uint8_t *buffer;          /**< Storage space. */
    54         uint8_t *buffer_end;      /**< End of storage place. */
    55         fibril_mutex_t guard;     /**< Protects buffer structures. */
    56         fibril_condvar_t change;  /**< Indicates change (empty/full). */
    57         uint8_t *read_head;       /**< Place of the next readable element. */
    58         uint8_t *write_head;      /**< Pointer to the next writable place. */
     50        uint8_t *buffer;         /**< Storage space. */
     51        uint8_t *buffer_end;     /**< End of storage place. */
     52        fibril_mutex_t guard;    /**< Protects buffer structures. */
     53        fibril_condvar_t change; /**< Indicates change (empty/full). */
     54        uint8_t *read_head;      /**< Place of the next readable element. */
     55        uint8_t *write_head;     /**< Pointer to the next writable place. */
    5956} buffer_t;
    6057
    6158/** Initialize cyclic buffer using provided memory space.
    62  *
    6359 * @param buffer Cyclic buffer structure to initialize.
    64  * @param data   Memory space to use.
    65  * @param size   Size of the memory place.
    66  *
     60 * @param data Memory space to use.
     61 * @param size Size of the memory place.
    6762 */
    6863static inline void buffer_init(buffer_t *buffer, uint8_t *data, size_t size)
    6964{
    7065        assert(buffer);
    71        
    7266        fibril_mutex_initialize(&buffer->guard);
    7367        fibril_condvar_initialize(&buffer->change);
     
    8074
    8175/** Write byte to cyclic buffer.
    82  *
    8376 * @param buffer Cyclic buffer to write to.
    84  * @param data   Data to write.
    85  *
     77 * @param data Data to write.
    8678 */
    8779static inline void buffer_write(buffer_t *buffer, uint8_t data)
    8880{
    8981        fibril_mutex_lock(&buffer->guard);
    90        
     82
    9183        /* Next position. */
    9284        uint8_t *new_head = buffer->write_head + 1;
    9385        if (new_head == buffer->buffer_end)
    9486                new_head = buffer->buffer;
    95        
     87
    9688        /* Buffer full. */
    9789        while (new_head == buffer->read_head)
    9890                fibril_condvar_wait(&buffer->change, &buffer->guard);
    99        
     91
    10092        /* Write data. */
    10193        *buffer->write_head = data;
    102        
     94
    10395        /* Buffer was empty. */
    10496        if (buffer->write_head == buffer->read_head)
    10597                fibril_condvar_broadcast(&buffer->change);
    106        
     98
    10799        /* Move head */
    108100        buffer->write_head = new_head;
     
    111103
    112104/** Read byte from cyclic buffer.
    113  *
    114105 * @param buffer Cyclic buffer to read from.
    115  *
    116106 * @return Byte read.
    117  *
    118107 */
    119108static inline uint8_t buffer_read(buffer_t *buffer)
    120109{
    121110        fibril_mutex_lock(&buffer->guard);
    122        
    123111        /* Buffer is empty. */
    124112        while (buffer->write_head == buffer->read_head)
    125113                fibril_condvar_wait(&buffer->change, &buffer->guard);
    126        
     114
    127115        /* Next position. */
    128116        uint8_t *new_head = buffer->read_head + 1;
    129117        if (new_head == buffer->buffer_end)
    130118                new_head = buffer->buffer;
    131        
     119
    132120        /* Read data. */
    133121        const uint8_t data = *buffer->read_head;
    134        
     122
    135123        /* Buffer was full. */
    136124        uint8_t *new_write_head = buffer->write_head + 1;
     
    139127        if (new_write_head == buffer->read_head)
    140128                fibril_condvar_broadcast(&buffer->change);
    141        
     129
    142130        /* Move head */
    143131        buffer->read_head = new_head;
    144        
     132
    145133        fibril_mutex_unlock(&buffer->guard);
    146134        return data;
    147135}
    148 
    149136#endif
    150 
    151137/**
    152138 * @}
  • uspace/drv/char/i8042/i8042.c

    r786bd56 r304faab  
    2929 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    3030 */
    31 
    3231/** @addtogroup kbd_port
    3332 * @ingroup kbd
    3433 * @{
    3534 */
    36 
    3735/** @file
    3836 * @brief i8042 PS/2 port driver.
     
    4644#include <str_error.h>
    4745#include <inttypes.h>
     46
    4847#include <ddf/log.h>
    4948#include <ddf/interrupt.h>
     49
    5050#include "i8042.h"
    5151
    52 /* Interesting bits for status register */
    53 #define i8042_OUTPUT_FULL  0x01
    54 #define i8042_INPUT_FULL   0x02
    55 #define i8042_AUX_DATA     0x20
    56 
    57 /* Command constants */
    58 #define i8042_CMD_WRITE_CMDB  0x60  /**< Write command byte */
    59 #define i8042_CMD_WRITE_AUX   0xd4  /**< Write aux device */
    60 
    61 /* Command byte fields */
    62 #define i8042_KBD_IE         0x01
    63 #define i8042_AUX_IE         0x02
    64 #define i8042_KBD_DISABLE    0x10
    65 #define i8042_AUX_DISABLE    0x20
    66 #define i8042_KBD_TRANSLATE  0x40  /* Use this to switch to XT scancodes */
    67 
    68 #define CHECK_RET_DESTROY(ret, msg...) \
    69         do { \
    70                 if (ret != EOK) { \
    71                         ddf_msg(LVL_ERROR, msg); \
    72                         if (dev->kbd_fun) { \
    73                                 dev->kbd_fun->driver_data = NULL; \
    74                                 ddf_fun_destroy(dev->kbd_fun); \
    75                         } \
    76                         if (dev->aux_fun) { \
    77                                 dev->aux_fun->driver_data = NULL; \
    78                                 ddf_fun_destroy(dev->aux_fun); \
    79                         } \
    80                 } \
    81         } while (0)
    82 
    83 #define CHECK_RET_UNBIND_DESTROY(ret, msg...) \
    84         do { \
    85                 if (ret != EOK) { \
    86                         ddf_msg(LVL_ERROR, msg); \
    87                         if (dev->kbd_fun) { \
    88                                 ddf_fun_unbind(dev->kbd_fun); \
    89                                 dev->kbd_fun->driver_data = NULL; \
    90                                 ddf_fun_destroy(dev->kbd_fun); \
    91                         } \
    92                         if (dev->aux_fun) { \
    93                                 ddf_fun_unbind(dev->aux_fun); \
    94                                 dev->aux_fun->driver_data = NULL; \
    95                                 ddf_fun_destroy(dev->aux_fun); \
    96                         } \
    97                 } \
    98         } while (0)
     52#define NAME       "i8042"
    9953
    10054void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     
    10559};
    10660
     61/* Interesting bits for status register */
     62#define i8042_OUTPUT_FULL       0x01
     63#define i8042_INPUT_FULL        0x02
     64#define i8042_AUX_DATA          0x20
     65
     66/* Command constants */
     67#define i8042_CMD_WRITE_CMDB    0x60    /**< write command byte */
     68#define i8042_CMD_WRITE_AUX     0xd4    /**< write aux device */
     69
     70/* Command byte fields */
     71#define i8042_KBD_IE            0x01
     72#define i8042_AUX_IE            0x02
     73#define i8042_KBD_DISABLE       0x10
     74#define i8042_AUX_DISABLE       0x20
     75#define i8042_KBD_TRANSLATE     0x40 /* Use this to switch to XT scancodes */
     76
    10777/** i8042 Interrupt pseudo-code. */
    10878static const irq_cmd_t i8042_cmds[] = {
    10979        {
    11080                .cmd = CMD_PIO_READ_8,
    111                 .addr = NULL,  /* will be patched in run-time */
     81                .addr = NULL,   /* will be patched in run-time */
    11282                .dstarg = 1
    11383        },
     
    12595        {
    12696                .cmd = CMD_PIO_READ_8,
    127                 .addr = NULL,  /* will be patched in run-time */
     97                .addr = NULL,   /* will be patched in run-time */
    12898                .dstarg = 2
    12999        },
     
    141111
    142112/** Interrupt handler routine.
    143  *
    144  * Write new data to the corresponding buffer.
    145  *
    146  * @param dev  Device that caued the interrupt.
    147  * @param iid  Call id.
     113 * Writes new data to the corresponding buffer.
     114 * @param dev Device that caued the interrupt.
     115 * @param iid Call id.
    148116 * @param call pointerr to call data.
    149  *
    150  */
    151 static void i8042_irq_handler(ddf_dev_t *dev, ipc_callid_t iid,
    152     ipc_call_t *call)
    153 {
    154         if ((!dev) || (!dev->driver_data))
     117 */
     118static void i8042_irq_handler(
     119    ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
     120{
     121        if (!dev || !dev->driver_data)
    155122                return;
    156        
    157123        i8042_t *controller = dev->driver_data;
    158        
     124
    159125        const uint8_t status = IPC_GET_ARG1(*call);
    160126        const uint8_t data = IPC_GET_ARG2(*call);
    161        
    162127        buffer_t *buffer = (status & i8042_AUX_DATA) ?
    163128            &controller->aux_buffer : &controller->kbd_buffer;
    164        
    165129        buffer_write(buffer, data);
    166130}
    167131
    168132/** Initialize i8042 driver structure.
    169  *
    170  * @param dev       Driver structure to initialize.
    171  * @param regs      I/O address of registers.
    172  * @param reg_size  size of the reserved I/O address space.
    173  * @param irq_kbd   IRQ for primary port.
     133 * @param dev Driver structure to initialize.
     134 * @param regs I/O address of registers.
     135 * @param reg_size size of the reserved I/O address space.
     136 * @param irq_kbd IRQ for primary port.
    174137 * @param irq_mouse IRQ for aux port.
    175  * @param ddf_dev   DDF device structure of the device.
    176  *
     138 * @param ddf_dev DDF device structure of the device.
    177139 * @return Error code.
    178  *
    179140 */
    180141int i8042_init(i8042_t *dev, void *regs, size_t reg_size, int irq_kbd,
     
    183144        assert(ddf_dev);
    184145        assert(dev);
    185        
     146
    186147        if (reg_size < sizeof(i8042_regs_t))
    187148                return EINVAL;
    188        
    189         if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0)
     149
     150        if (pio_enable(regs, sizeof(i8042_regs_t), (void**)&dev->regs) != 0)
    190151                return -1;
    191        
     152
    192153        dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    193154        if (!dev->kbd_fun)
    194155                return ENOMEM;
    195        
    196156        int ret = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
    197157        if (ret != EOK) {
     
    199159                return ret;
    200160        }
    201        
     161
    202162        dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    203163        if (!dev->aux_fun) {
     
    205165                return ENOMEM;
    206166        }
    207        
     167
    208168        ret = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
    209169        if (ret != EOK) {
     
    212172                return ret;
    213173        }
    214        
     174
    215175        dev->kbd_fun->ops = &ops;
    216176        dev->aux_fun->ops = &ops;
    217177        dev->kbd_fun->driver_data = dev;
    218178        dev->aux_fun->driver_data = dev;
    219        
     179
    220180        buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
    221181        buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE);
    222182        fibril_mutex_initialize(&dev->write_guard);
    223        
     183
     184#define CHECK_RET_DESTROY(ret, msg...) \
     185if  (ret != EOK) { \
     186        ddf_msg(LVL_ERROR, msg); \
     187        if (dev->kbd_fun) { \
     188                dev->kbd_fun->driver_data = NULL; \
     189                ddf_fun_destroy(dev->kbd_fun); \
     190        } \
     191        if (dev->aux_fun) { \
     192                dev->aux_fun->driver_data = NULL; \
     193                ddf_fun_destroy(dev->aux_fun); \
     194        } \
     195} else (void)0
     196
    224197        ret = ddf_fun_bind(dev->kbd_fun);
    225         CHECK_RET_DESTROY(ret, "Failed to bind keyboard function: %s.",
    226             str_error(ret));
    227        
     198        CHECK_RET_DESTROY(ret,
     199            "Failed to bind keyboard function: %s.", str_error(ret));
     200
    228201        ret = ddf_fun_bind(dev->aux_fun);
    229         CHECK_RET_DESTROY(ret, "Failed to bind mouse function: %s.",
    230             str_error(ret));
    231        
     202        CHECK_RET_DESTROY(ret,
     203            "Failed to bind mouse function: %s.", str_error(ret));
     204
    232205        /* Disable kbd and aux */
    233206        wait_ready(dev);
     
    235208        wait_ready(dev);
    236209        pio_write_8(&dev->regs->data, i8042_KBD_DISABLE | i8042_AUX_DISABLE);
    237        
     210
    238211        /* Flush all current IO */
    239212        while (pio_read_8(&dev->regs->status) & i8042_OUTPUT_FULL)
    240213                (void) pio_read_8(&dev->regs->data);
    241        
     214
     215#define CHECK_RET_UNBIND_DESTROY(ret, msg...) \
     216if  (ret != EOK) { \
     217        ddf_msg(LVL_ERROR, msg); \
     218        if (dev->kbd_fun) { \
     219                ddf_fun_unbind(dev->kbd_fun); \
     220                dev->kbd_fun->driver_data = NULL; \
     221                ddf_fun_destroy(dev->kbd_fun); \
     222        } \
     223        if (dev->aux_fun) { \
     224                ddf_fun_unbind(dev->aux_fun); \
     225                dev->aux_fun->driver_data = NULL; \
     226                ddf_fun_destroy(dev->aux_fun); \
     227        } \
     228} else (void)0
     229
    242230        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    243231        irq_cmd_t cmds[cmd_count];
     
    245233        cmds[0].addr = (void *) &dev->regs->status;
    246234        cmds[3].addr = (void *) &dev->regs->data;
    247        
    248         irq_code_t irq_code = {
    249                 .cmdcount = cmd_count,
    250                 .cmds = cmds
    251         };
    252        
     235
     236        irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = cmds };
    253237        ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
    254238            &irq_code);
    255         CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for kbd: %s.",
    256             str_error(ret));
    257        
     239        CHECK_RET_UNBIND_DESTROY(ret,
     240            "Failed set handler for kbd: %s.", str_error(ret));
     241
    258242        ret = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
    259243            &irq_code);
    260         CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for mouse: %s.",
    261             str_error(ret));
    262        
     244        CHECK_RET_UNBIND_DESTROY(ret,
     245            "Failed set handler for mouse: %s.", str_error(ret));
     246
    263247        /* Enable interrupts */
    264248        async_sess_t *parent_sess =
     
    267251        ret = parent_sess ? EOK : ENOMEM;
    268252        CHECK_RET_UNBIND_DESTROY(ret, "Failed to create parent connection.");
    269        
     253
    270254        const bool enabled = hw_res_enable_interrupt(parent_sess);
    271255        async_hangup(parent_sess);
    272256        ret = enabled ? EOK : EIO;
    273257        CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s.");
    274        
     258
    275259        /* Enable port interrupts. */
    276260        wait_ready(dev);
     
    279263        pio_write_8(&dev->regs->data, i8042_KBD_IE | i8042_KBD_TRANSLATE |
    280264            i8042_AUX_IE);
    281        
     265
    282266        return EOK;
    283267}
    284268
    285 // FIXME TODO use shared instead this
     269// TODO use shared instead this
    286270enum {
    287271        IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
     
    290274
    291275/** Write data to i8042 port.
    292  *
    293  * @param fun    DDF function.
     276 * @param fun DDF function.
    294277 * @param buffer Data source.
    295  * @param size   Data size.
    296  *
     278 * @param size Data size.
    297279 * @return Bytes written.
    298  *
    299280 */
    300281static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size)
     
    302283        assert(fun);
    303284        assert(fun->driver_data);
    304        
    305285        i8042_t *controller = fun->driver_data;
    306286        fibril_mutex_lock(&controller->write_guard);
    307        
    308287        for (size_t i = 0; i < size; ++i) {
    309288                wait_ready(controller);
    310                
    311289                if (controller->aux_fun == fun)
    312                         pio_write_8(&controller->regs->status,
    313                             i8042_CMD_WRITE_AUX);
    314                
     290                        pio_write_8(
     291                            &controller->regs->status, i8042_CMD_WRITE_AUX);
    315292                pio_write_8(&controller->regs->data, buffer[i]);
    316293        }
    317        
    318294        fibril_mutex_unlock(&controller->write_guard);
    319295        return size;
     
    321297
    322298/** Read data from i8042 port.
    323  *
    324  * @param fun    DDF function.
     299 * @param fun DDF function.
    325300 * @param buffer Data place.
    326  * @param size   Data place size.
    327  *
     301 * @param size Data place size.
    328302 * @return Bytes read.
    329  *
    330303 */
    331304static int i8042_read(ddf_fun_t *fun, char *data, size_t size)
     
    333306        assert(fun);
    334307        assert(fun->driver_data);
    335        
     308
    336309        i8042_t *controller = fun->driver_data;
    337310        buffer_t *buffer = (fun == controller->aux_fun) ?
    338311            &controller->aux_buffer : &controller->kbd_buffer;
    339        
    340         for (size_t i = 0; i < size; ++i)
     312        for (size_t i = 0; i < size; ++i) {
    341313                *data++ = buffer_read(buffer);
    342        
     314        }
    343315        return size;
    344316}
    345317
    346318/** Handle data requests.
    347  *
    348  * @param fun  ddf_fun_t function.
    349  * @param id   callid
     319 * @param fun ddf_fun_t function.
     320 * @param id callid
    350321 * @param call IPC request.
    351  *
    352322 */
    353323void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
     
    355325        const sysarg_t method = IPC_GET_IMETHOD(*call);
    356326        const size_t size = IPC_GET_ARG1(*call);
    357        
    358327        switch (method) {
    359328        case IPC_CHAR_READ:
    360329                if (size <= 4 * sizeof(sysarg_t)) {
    361330                        sysarg_t message[4] = {};
    362                        
    363                         i8042_read(fun, (char *) message, size);
     331                        i8042_read(fun, (char*)message, size);
    364332                        async_answer_4(id, size, message[0], message[1],
    365333                            message[2], message[3]);
    366                 } else
     334                } else {
    367335                        async_answer_0(id, ELIMIT);
     336                }
    368337                break;
    369        
     338
    370339        case IPC_CHAR_WRITE:
    371340                if (size <= 3 * sizeof(sysarg_t)) {
    372341                        const sysarg_t message[3] = {
    373                                 IPC_GET_ARG2(*call),
    374                                 IPC_GET_ARG3(*call),
    375                                 IPC_GET_ARG4(*call)
    376                         };
    377                        
    378                         i8042_write(fun, (char *) message, size);
     342                                IPC_GET_ARG2(*call), IPC_GET_ARG3(*call),
     343                                IPC_GET_ARG4(*call) };
     344                        i8042_write(fun, (char*)message, size);
    379345                        async_answer_0(id, size);
    380                 } else
     346                } else {
    381347                        async_answer_0(id, ELIMIT);
    382        
     348                }
     349
    383350        default:
    384351                async_answer_0(id, EINVAL);
    385352        }
    386353}
    387 
    388354/**
    389355 * @}
  • uspace/drv/char/i8042/i8042.h

    r786bd56 r304faab  
    2727 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828 */
    29 
    3029/** @addtogroup kbd_port
    3130 * @ingroup  kbd
    3231 * @{
    3332 */
    34 
    3533/** @file
    3634 * @brief i8042 port driver.
     
    4341#include <fibril_synch.h>
    4442#include <ddf/driver.h>
     43
    4544#include "buffer.h"
    4645
    47 #define NAME  "i8042"
    48 
    49 #define BUFFER_SIZE  12
     46#define BUFFER_SIZE 12
    5047
    5148/** i8042 HW I/O interface */
     
    5855/** i8042 driver structure. */
    5956typedef struct i8042 {
    60         i8042_regs_t *regs;             /**< I/O registers. */
    61         ddf_fun_t *kbd_fun;             /**< Pirmary port device function. */
    62         ddf_fun_t *aux_fun;             /**< Auxiliary port device function. */
    63         buffer_t kbd_buffer;            /**< Primary port buffer. */
    64         buffer_t aux_buffer;            /**< Aux. port buffer. */
     57        i8042_regs_t *regs;    /**< I/O registers. */
     58        ddf_fun_t *kbd_fun;    /**< Pirmary port device function. */
     59        ddf_fun_t *aux_fun;  /**< Auxiliary port device function. */
     60        buffer_t kbd_buffer;   /**< Primary port buffer. */
     61        buffer_t aux_buffer;   /**< Aux. port buffer. */
    6562        uint8_t aux_data[BUFFER_SIZE];  /**< Primary port buffer space. */
    6663        uint8_t kbd_data[BUFFER_SIZE];  /**< Aux. port buffer space. */
     
    6966
    7067int i8042_init(i8042_t *, void *, size_t, int, int, ddf_dev_t *);
    71 
    7268#endif
    73 
    7469/**
    7570 * @}
  • uspace/drv/char/i8042/main.c

    r786bd56 r304faab  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    2928/** @addtogroup drvi8042
    3029 * @{
    3130 */
    32 
    3331/** @file
    3432 * @brief i8042 driver DDF bits.
     
    4341#include <ddf/log.h>
    4442#include <stdio.h>
     43
    4544#include "i8042.h"
    4645
    47 #define CHECK_RET_RETURN(ret, message...) \
    48         do { \
    49                 if (ret != EOK) { \
    50                         ddf_msg(LVL_ERROR, message); \
    51                         return ret; \
    52                 } \
    53         } while (0)
     46#define NAME "i8042"
    5447
    55 /** Get address of I/O registers.
    56  *
    57  * @param[in]  dev            Device asking for the addresses.
    58  * @param[out] io_reg_address Base address of the memory range.
    59  * @param[out] io_reg_size    Size of the memory range.
    60  * @param[out] kbd_irq        Primary port IRQ.
    61  * @param[out] mouse_irq      Auxiliary port IRQ.
    62  *
    63  * @return Error code.
    64  *
    65  */
    66 static int get_my_registers(const ddf_dev_t *dev, uintptr_t *io_reg_address,
    67     size_t *io_reg_size, int *kbd_irq, int *mouse_irq)
    68 {
    69         assert(dev);
    70        
    71         async_sess_t *parent_sess =
    72             devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
    73             IPC_FLAG_BLOCKING);
    74         if (!parent_sess)
    75                 return ENOMEM;
    76        
    77         hw_res_list_parsed_t hw_resources;
    78         hw_res_list_parsed_init(&hw_resources);
    79         const int ret = hw_res_get_list_parsed(parent_sess, &hw_resources, 0);
    80         async_hangup(parent_sess);
    81         if (ret != EOK)
    82                 return ret;
    83        
    84         if ((hw_resources.irqs.count != 2) ||
    85             (hw_resources.io_ranges.count != 1)) {
    86                 hw_res_list_parsed_clean(&hw_resources);
    87                 return EINVAL;
    88         }
    89        
    90         if (io_reg_address)
    91                 *io_reg_address = hw_resources.io_ranges.ranges[0].address;
    92        
    93         if (io_reg_size)
    94                 *io_reg_size = hw_resources.io_ranges.ranges[0].size;
    95        
    96         if (kbd_irq)
    97                 *kbd_irq = hw_resources.irqs.irqs[0];
    98        
    99         if (mouse_irq)
    100                 *mouse_irq = hw_resources.irqs.irqs[1];
    101        
    102         hw_res_list_parsed_clean(&hw_resources);
    103         return EOK;
    104 }
    105 
    106 /** Initialize a new ddf driver instance of i8042 driver
    107  *
    108  * @param[in] device DDF instance of the device to initialize.
    109  *
    110  * @return Error code.
    111  *
    112  */
    113 static int i8042_dev_add(ddf_dev_t *device)
    114 {
    115         if (!device)
    116                 return EINVAL;
    117        
    118         uintptr_t io_regs = 0;
    119         size_t io_size = 0;
    120         int kbd = 0;
    121         int mouse = 0;
    122        
    123         int ret = get_my_registers(device, &io_regs, &io_size, &kbd, &mouse);
    124         CHECK_RET_RETURN(ret, "Failed to get registers: %s.",
    125             str_error(ret));
    126         ddf_msg(LVL_DEBUG, "I/O regs at %p (size %zuB), IRQ kbd %d, IRQ mouse %d.",
    127             (void *) io_regs, io_size, kbd, mouse);
    128        
    129         i8042_t *i8042 = ddf_dev_data_alloc(device, sizeof(i8042_t));
    130         ret = (i8042 == NULL) ? ENOMEM : EOK;
    131         CHECK_RET_RETURN(ret, "Failed to allocate i8042 driver instance.");
    132        
    133         ret = i8042_init(i8042, (void *) io_regs, io_size, kbd, mouse, device);
    134         CHECK_RET_RETURN(ret, "Failed to initialize i8042 driver: %s.",
    135             str_error(ret));
    136        
    137         ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
    138             device->name, device->handle);
    139         return EOK;
    140 }
     48static int get_my_registers(const ddf_dev_t *dev,
     49    uintptr_t *io_reg_address, size_t *io_reg_size, int *kbd, int *mouse);
     50static int i8042_dev_add(ddf_dev_t *device);
    14151
    14252/** DDF driver operations. */
     
    15161};
    15262
     63/** Initialize global driver structures (NONE).
     64 *
     65 * @param[in] argc Nmber of arguments in argv vector (ignored).
     66 * @param[in] argv Cmdline argument vector (ignored).
     67 * @return Error code.
     68 *
     69 * Driver debug level is set here.
     70 */
    15371int main(int argc, char *argv[])
    15472{
    155         printf("%s: HelenOS PS/2 driver.\n", NAME);
     73        printf(NAME ": HelenOS ps/2 driver.\n");
    15674        ddf_log_init(NAME, LVL_NOTE);
    15775        return ddf_driver_main(&i8042_driver);
    15876}
    15977
     78/** Initialize a new ddf driver instance of i8042 driver
     79 *
     80 * @param[in] device DDF instance of the device to initialize.
     81 * @return Error code.
     82 */
     83static int i8042_dev_add(ddf_dev_t *device)
     84{
     85        if (!device)
     86                return EINVAL;
     87
     88#define CHECK_RET_RETURN(ret, message...) \
     89if (ret != EOK) { \
     90        ddf_msg(LVL_ERROR, message); \
     91        return ret; \
     92} else (void)0
     93
     94        uintptr_t io_regs = 0;
     95        size_t io_size = 0;
     96        int kbd = 0, mouse = 0;
     97
     98        int ret = get_my_registers(device, &io_regs, &io_size, &kbd, &mouse);
     99        CHECK_RET_RETURN(ret,
     100            "Failed to get registers: %s.", str_error(ret));
     101        ddf_msg(LVL_DEBUG,
     102            "I/O regs at %p (size %zuB), IRQ kbd %d, IRQ mouse %d.",
     103            (void *) io_regs, io_size, kbd, mouse);
     104
     105        i8042_t *i8042 = ddf_dev_data_alloc(device, sizeof(i8042_t));
     106        ret = (i8042 == NULL) ? ENOMEM : EOK;
     107        CHECK_RET_RETURN(ret, "Failed to allocate i8042 driver instance.");
     108
     109        ret = i8042_init(i8042, (void*)io_regs, io_size, kbd, mouse, device);
     110        CHECK_RET_RETURN(ret,
     111            "Failed to initialize i8042 driver: %s.", str_error(ret));
     112
     113        ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
     114            device->name, device->handle);
     115        return EOK;
     116}
     117
     118/** Get address of I/O registers.
     119 *
     120 * @param[in] dev Device asking for the addresses.
     121 * @param[out] io_reg_address Base address of the memory range.
     122 * @param[out] io_reg_size Size of the memory range.
     123 * @param[out] kbd_irq Primary port IRQ.
     124 * @param[out] mouse_irq Auxiliary port IRQ.
     125 * @return Error code.
     126 */
     127int get_my_registers(const ddf_dev_t *dev, uintptr_t *io_reg_address,
     128    size_t *io_reg_size, int *kbd_irq, int *mouse_irq)
     129{
     130        assert(dev);
     131
     132        async_sess_t *parent_sess =
     133            devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
     134            IPC_FLAG_BLOCKING);
     135        if (!parent_sess)
     136                return ENOMEM;
     137
     138        hw_res_list_parsed_t hw_resources;
     139        hw_res_list_parsed_init(&hw_resources);
     140        const int ret = hw_res_get_list_parsed(parent_sess, &hw_resources, 0);
     141        async_hangup(parent_sess);
     142        if (ret != EOK) {
     143                return ret;
     144        }
     145
     146        if (hw_resources.irqs.count != 2 || hw_resources.io_ranges.count != 1) {
     147                hw_res_list_parsed_clean(&hw_resources);
     148                return EINVAL;
     149        }
     150
     151        if (io_reg_address)
     152                *io_reg_address = hw_resources.io_ranges.ranges[0].address;
     153
     154        if (io_reg_size)
     155                *io_reg_size = hw_resources.io_ranges.ranges[0].size;
     156
     157        if (kbd_irq)
     158                *kbd_irq = hw_resources.irqs.irqs[0];
     159
     160        if (mouse_irq)
     161                *mouse_irq = hw_resources.irqs.irqs[1];
     162
     163        hw_res_list_parsed_clean(&hw_resources);
     164        return EOK;
     165}
    160166/**
    161167 * @}
  • uspace/lib/c/generic/loc.c

    r786bd56 r304faab  
    4747static FIBRIL_MUTEX_INITIALIZE(loc_callback_mutex);
    4848static bool loc_callback_created = false;
    49 static loc_cat_change_cb_t cat_change_cb = NULL;
    5049
    5150static async_sess_t *loc_supp_block_sess = NULL;
     
    5554static async_sess_t *loc_consumer_sess = NULL;
    5655
     56static loc_cat_change_cb_t cat_change_cb = NULL;
     57
    5758static void loc_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    5859{
     60        loc_cat_change_cb_t cb_fun;
     61       
    5962        while (true) {
    6063                ipc_call_t call;
     
    6669                }
    6770               
     71                int retval;
     72               
    6873                switch (IPC_GET_IMETHOD(call)) {
    6974                case LOC_EVENT_CAT_CHANGE:
    7075                        fibril_mutex_lock(&loc_callback_mutex);
    71                         loc_cat_change_cb_t cb_fun = cat_change_cb;
     76                        cb_fun = cat_change_cb;
     77                        if (cb_fun != NULL) {
     78                                (*cb_fun)();
     79                        }
    7280                        fibril_mutex_unlock(&loc_callback_mutex);
    73                        
    74                         async_answer_0(callid, EOK);
    75                        
    76                         if (cb_fun != NULL)
    77                                 (*cb_fun)();
    78                        
     81                        retval = 0;
    7982                        break;
    8083                default:
    81                         async_answer_0(callid, ENOTSUP);
     84                        retval = ENOTSUP;
    8285                }
     86               
     87                async_answer_0(callid, retval);
    8388        }
    8489}
     
    96101}
    97102
    98 /** Create callback
    99  *
    100  * Must be called with loc_callback_mutex locked.
    101  *
    102  * @return EOK on success.
    103  *
    104  */
    105103static int loc_callback_create(void)
    106104{
     105        async_exch_t *exch;
     106        sysarg_t retval;
     107        int rc = EOK;
     108
     109        fibril_mutex_lock(&loc_callback_mutex);
     110       
    107111        if (!loc_callback_created) {
    108                 async_exch_t *exch =
    109                     loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
     112                exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
    110113               
    111114                ipc_call_t answer;
    112115                aid_t req = async_send_0(exch, LOC_CALLBACK_CREATE, &answer);
    113                 int rc = async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);
     116                async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);
    114117                loc_exchange_end(exch);
    115118               
     119                async_wait_for(req, &retval);
    116120                if (rc != EOK)
    117                         return rc;
    118                
    119                 sysarg_t retval;
    120                 async_wait_for(req, &retval);
    121                 if (retval != EOK)
    122                         return retval;
     121                        goto done;
     122               
     123                if (retval != EOK) {
     124                        rc = retval;
     125                        goto done;
     126                }
    123127               
    124128                loc_callback_created = true;
    125129        }
    126130       
    127         return EOK;
     131        rc = EOK;
     132done:
     133        fibril_mutex_unlock(&loc_callback_mutex);
     134        return rc;
    128135}
    129136
     
    788795    sysarg_t **data, size_t *count)
    789796{
     797        service_id_t *ids;
     798        size_t act_size;
     799        size_t alloc_size;
     800        int rc;
     801
    790802        *data = NULL;
    791         *count = 0;
    792        
    793         size_t act_size = 0;
    794         int rc = loc_category_get_ids_once(method, arg1, NULL, 0,
     803        act_size = 0;   /* silence warning */
     804
     805        rc = loc_category_get_ids_once(method, arg1, NULL, 0,
    795806            &act_size);
    796807        if (rc != EOK)
    797808                return rc;
    798        
    799         size_t alloc_size = act_size;
    800         service_id_t *ids = malloc(alloc_size);
     809
     810        alloc_size = act_size;
     811        ids = malloc(alloc_size);
    801812        if (ids == NULL)
    802813                return ENOMEM;
    803        
     814
    804815        while (true) {
    805816                rc = loc_category_get_ids_once(method, arg1, ids, alloc_size,
     
    807818                if (rc != EOK)
    808819                        return rc;
    809                
     820
    810821                if (act_size <= alloc_size)
    811822                        break;
    812                
    813                 alloc_size = act_size;
    814                 ids = realloc(ids, alloc_size);
     823
     824                alloc_size *= 2;
     825                free(ids);
     826
     827                ids = malloc(alloc_size);
    815828                if (ids == NULL)
    816829                        return ENOMEM;
    817830        }
    818        
     831
    819832        *count = act_size / sizeof(category_id_t);
    820833        *data = ids;
     
    854867int loc_register_cat_change_cb(loc_cat_change_cb_t cb_fun)
    855868{
    856         fibril_mutex_lock(&loc_callback_mutex);
    857         if (loc_callback_create() != EOK) {
    858                 fibril_mutex_unlock(&loc_callback_mutex);
     869        if (loc_callback_create() != EOK)
    859870                return EIO;
    860         }
    861        
     871
    862872        cat_change_cb = cb_fun;
    863         fibril_mutex_unlock(&loc_callback_mutex);
    864        
    865873        return EOK;
    866874}
Note: See TracChangeset for help on using the changeset viewer.