Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 786bd56 in mainline


Ignore:
Timestamp:
2012-01-24T09:26:36Z (8 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
master
Children:
cd1cc4e6
Parents:
304faab (diff), 2df6f6fe (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 with mainline

Files:
14 edited

Legend:

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

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

    r304faab r786bd56  
    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);
    228216#endif
    229217       
    230218        if (irqs_info != NULL)
    231219                sysinfo_set_item_val(irqs_info, NULL, true);
    232        
    233         sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
    234220}
    235221
  • kernel/arch/ia32/include/interrupt.h

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

    r304faab r786bd56  
    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);
    182170#endif
    183171       
    184172        if (irqs_info != NULL)
    185173                sysinfo_set_item_val(irqs_info, NULL, true);
    186        
    187         sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
    188174}
    189175
  • kernel/arch/ia64/include/interrupt.h

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

    r304faab r786bd56  
    188188       
    189189#ifdef CONFIG_I8042
    190         i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
     190        i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE,
     191            IRQ_KBD);
    191192        if (i8042_instance) {
    192193                kbrd_instance_t *kbrd_instance = kbrd_init();
     
    197198                }
    198199        }
    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 
     200#endif
     201       
    211202        sysinfo_set_item_val("ia64_iospace", NULL, true);
    212203        sysinfo_set_item_val("ia64_iospace.address", NULL, true);
  • uspace/drv/bus/isa/isa.dev

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

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

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

    r304faab r786bd56  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
     28
    2829/**
    2930 * @addtogroup kbd
    3031 * @{
    3132 */
     33
    3234/** @file
    3335 * @brief Cyclic buffer structure.
     
    4648 * Attempt to insert byte into the full buffer will block until it can succeed.
    4749 * Attempt to read from empty buffer will block until it can succeed.
     50 *
    4851 */
    4952typedef struct {
    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. */
     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. */
    5659} buffer_t;
    5760
    5861/** Initialize cyclic buffer using provided memory space.
     62 *
    5963 * @param buffer Cyclic buffer structure to initialize.
    60  * @param data Memory space to use.
    61  * @param size Size of the memory place.
     64 * @param data   Memory space to use.
     65 * @param size   Size of the memory place.
     66 *
    6267 */
    6368static inline void buffer_init(buffer_t *buffer, uint8_t *data, size_t size)
    6469{
    6570        assert(buffer);
     71       
    6672        fibril_mutex_initialize(&buffer->guard);
    6773        fibril_condvar_initialize(&buffer->change);
     
    7480
    7581/** Write byte to cyclic buffer.
     82 *
    7683 * @param buffer Cyclic buffer to write to.
    77  * @param data Data to write.
     84 * @param data   Data to write.
     85 *
    7886 */
    7987static inline void buffer_write(buffer_t *buffer, uint8_t data)
    8088{
    8189        fibril_mutex_lock(&buffer->guard);
    82 
     90       
    8391        /* Next position. */
    8492        uint8_t *new_head = buffer->write_head + 1;
    8593        if (new_head == buffer->buffer_end)
    8694                new_head = buffer->buffer;
    87 
     95       
    8896        /* Buffer full. */
    8997        while (new_head == buffer->read_head)
    9098                fibril_condvar_wait(&buffer->change, &buffer->guard);
    91 
     99       
    92100        /* Write data. */
    93101        *buffer->write_head = data;
    94 
     102       
    95103        /* Buffer was empty. */
    96104        if (buffer->write_head == buffer->read_head)
    97105                fibril_condvar_broadcast(&buffer->change);
    98 
     106       
    99107        /* Move head */
    100108        buffer->write_head = new_head;
     
    103111
    104112/** Read byte from cyclic buffer.
     113 *
    105114 * @param buffer Cyclic buffer to read from.
     115 *
    106116 * @return Byte read.
     117 *
    107118 */
    108119static inline uint8_t buffer_read(buffer_t *buffer)
    109120{
    110121        fibril_mutex_lock(&buffer->guard);
     122       
    111123        /* Buffer is empty. */
    112124        while (buffer->write_head == buffer->read_head)
    113125                fibril_condvar_wait(&buffer->change, &buffer->guard);
    114 
     126       
    115127        /* Next position. */
    116128        uint8_t *new_head = buffer->read_head + 1;
    117129        if (new_head == buffer->buffer_end)
    118130                new_head = buffer->buffer;
    119 
     131       
    120132        /* Read data. */
    121133        const uint8_t data = *buffer->read_head;
    122 
     134       
    123135        /* Buffer was full. */
    124136        uint8_t *new_write_head = buffer->write_head + 1;
     
    127139        if (new_write_head == buffer->read_head)
    128140                fibril_condvar_broadcast(&buffer->change);
    129 
     141       
    130142        /* Move head */
    131143        buffer->read_head = new_head;
    132 
     144       
    133145        fibril_mutex_unlock(&buffer->guard);
    134146        return data;
    135147}
     148
    136149#endif
     150
    137151/**
    138152 * @}
  • uspace/drv/char/i8042/i8042.c

    r304faab r786bd56  
    2929 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    3030 */
     31
    3132/** @addtogroup kbd_port
    3233 * @ingroup kbd
    3334 * @{
    3435 */
     36
    3537/** @file
    3638 * @brief i8042 PS/2 port driver.
     
    4446#include <str_error.h>
    4547#include <inttypes.h>
    46 
    4748#include <ddf/log.h>
    4849#include <ddf/interrupt.h>
    49 
    5050#include "i8042.h"
    5151
    52 #define NAME       "i8042"
     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)
    5399
    54100void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     
    59105};
    60106
    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 
    77107/** i8042 Interrupt pseudo-code. */
    78108static const irq_cmd_t i8042_cmds[] = {
    79109        {
    80110                .cmd = CMD_PIO_READ_8,
    81                 .addr = NULL,   /* will be patched in run-time */
     111                .addr = NULL,  /* will be patched in run-time */
    82112                .dstarg = 1
    83113        },
     
    95125        {
    96126                .cmd = CMD_PIO_READ_8,
    97                 .addr = NULL,   /* will be patched in run-time */
     127                .addr = NULL,  /* will be patched in run-time */
    98128                .dstarg = 2
    99129        },
     
    111141
    112142/** Interrupt handler routine.
    113  * Writes new data to the corresponding buffer.
    114  * @param dev Device that caued the interrupt.
    115  * @param iid Call id.
     143 *
     144 * Write new data to the corresponding buffer.
     145 *
     146 * @param dev  Device that caued the interrupt.
     147 * @param iid  Call id.
    116148 * @param call pointerr to call data.
    117  */
    118 static void i8042_irq_handler(
    119     ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    120 {
    121         if (!dev || !dev->driver_data)
     149 *
     150 */
     151static void i8042_irq_handler(ddf_dev_t *dev, ipc_callid_t iid,
     152    ipc_call_t *call)
     153{
     154        if ((!dev) || (!dev->driver_data))
    122155                return;
     156       
    123157        i8042_t *controller = dev->driver_data;
    124 
     158       
    125159        const uint8_t status = IPC_GET_ARG1(*call);
    126160        const uint8_t data = IPC_GET_ARG2(*call);
     161       
    127162        buffer_t *buffer = (status & i8042_AUX_DATA) ?
    128163            &controller->aux_buffer : &controller->kbd_buffer;
     164       
    129165        buffer_write(buffer, data);
    130166}
    131167
    132168/** Initialize i8042 driver structure.
    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.
     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.
    137174 * @param irq_mouse IRQ for aux port.
    138  * @param ddf_dev DDF device structure of the device.
     175 * @param ddf_dev   DDF device structure of the device.
     176 *
    139177 * @return Error code.
     178 *
    140179 */
    141180int i8042_init(i8042_t *dev, void *regs, size_t reg_size, int irq_kbd,
     
    144183        assert(ddf_dev);
    145184        assert(dev);
    146 
     185       
    147186        if (reg_size < sizeof(i8042_regs_t))
    148187                return EINVAL;
    149 
    150         if (pio_enable(regs, sizeof(i8042_regs_t), (void**)&dev->regs) != 0)
     188       
     189        if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0)
    151190                return -1;
    152 
     191       
    153192        dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    154193        if (!dev->kbd_fun)
    155194                return ENOMEM;
     195       
    156196        int ret = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
    157197        if (ret != EOK) {
     
    159199                return ret;
    160200        }
    161 
     201       
    162202        dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    163203        if (!dev->aux_fun) {
     
    165205                return ENOMEM;
    166206        }
    167 
     207       
    168208        ret = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
    169209        if (ret != EOK) {
     
    172212                return ret;
    173213        }
    174 
     214       
    175215        dev->kbd_fun->ops = &ops;
    176216        dev->aux_fun->ops = &ops;
    177217        dev->kbd_fun->driver_data = dev;
    178218        dev->aux_fun->driver_data = dev;
    179 
     219       
    180220        buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
    181221        buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE);
    182222        fibril_mutex_initialize(&dev->write_guard);
    183 
    184 #define CHECK_RET_DESTROY(ret, msg...) \
    185 if  (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 
     223       
    197224        ret = ddf_fun_bind(dev->kbd_fun);
    198         CHECK_RET_DESTROY(ret,
    199             "Failed to bind keyboard function: %s.", str_error(ret));
    200 
     225        CHECK_RET_DESTROY(ret, "Failed to bind keyboard function: %s.",
     226            str_error(ret));
     227       
    201228        ret = ddf_fun_bind(dev->aux_fun);
    202         CHECK_RET_DESTROY(ret,
    203             "Failed to bind mouse function: %s.", str_error(ret));
    204 
     229        CHECK_RET_DESTROY(ret, "Failed to bind mouse function: %s.",
     230            str_error(ret));
     231       
    205232        /* Disable kbd and aux */
    206233        wait_ready(dev);
     
    208235        wait_ready(dev);
    209236        pio_write_8(&dev->regs->data, i8042_KBD_DISABLE | i8042_AUX_DISABLE);
    210 
     237       
    211238        /* Flush all current IO */
    212239        while (pio_read_8(&dev->regs->status) & i8042_OUTPUT_FULL)
    213240                (void) pio_read_8(&dev->regs->data);
    214 
    215 #define CHECK_RET_UNBIND_DESTROY(ret, msg...) \
    216 if  (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 
     241       
    230242        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    231243        irq_cmd_t cmds[cmd_count];
     
    233245        cmds[0].addr = (void *) &dev->regs->status;
    234246        cmds[3].addr = (void *) &dev->regs->data;
    235 
    236         irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = cmds };
     247       
     248        irq_code_t irq_code = {
     249                .cmdcount = cmd_count,
     250                .cmds = cmds
     251        };
     252       
    237253        ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
    238254            &irq_code);
    239         CHECK_RET_UNBIND_DESTROY(ret,
    240             "Failed set handler for kbd: %s.", str_error(ret));
    241 
     255        CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for kbd: %s.",
     256            str_error(ret));
     257       
    242258        ret = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
    243259            &irq_code);
    244         CHECK_RET_UNBIND_DESTROY(ret,
    245             "Failed set handler for mouse: %s.", str_error(ret));
    246 
     260        CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for mouse: %s.",
     261            str_error(ret));
     262       
    247263        /* Enable interrupts */
    248264        async_sess_t *parent_sess =
     
    251267        ret = parent_sess ? EOK : ENOMEM;
    252268        CHECK_RET_UNBIND_DESTROY(ret, "Failed to create parent connection.");
    253 
     269       
    254270        const bool enabled = hw_res_enable_interrupt(parent_sess);
    255271        async_hangup(parent_sess);
    256272        ret = enabled ? EOK : EIO;
    257273        CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s.");
    258 
     274       
    259275        /* Enable port interrupts. */
    260276        wait_ready(dev);
     
    263279        pio_write_8(&dev->regs->data, i8042_KBD_IE | i8042_KBD_TRANSLATE |
    264280            i8042_AUX_IE);
    265 
     281       
    266282        return EOK;
    267283}
    268284
    269 // TODO use shared instead this
     285// FIXME TODO use shared instead this
    270286enum {
    271287        IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
     
    274290
    275291/** Write data to i8042 port.
    276  * @param fun DDF function.
     292 *
     293 * @param fun    DDF function.
    277294 * @param buffer Data source.
    278  * @param size Data size.
     295 * @param size   Data size.
     296 *
    279297 * @return Bytes written.
     298 *
    280299 */
    281300static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size)
     
    283302        assert(fun);
    284303        assert(fun->driver_data);
     304       
    285305        i8042_t *controller = fun->driver_data;
    286306        fibril_mutex_lock(&controller->write_guard);
     307       
    287308        for (size_t i = 0; i < size; ++i) {
    288309                wait_ready(controller);
     310               
    289311                if (controller->aux_fun == fun)
    290                         pio_write_8(
    291                             &controller->regs->status, i8042_CMD_WRITE_AUX);
     312                        pio_write_8(&controller->regs->status,
     313                            i8042_CMD_WRITE_AUX);
     314               
    292315                pio_write_8(&controller->regs->data, buffer[i]);
    293316        }
     317       
    294318        fibril_mutex_unlock(&controller->write_guard);
    295319        return size;
     
    297321
    298322/** Read data from i8042 port.
    299  * @param fun DDF function.
     323 *
     324 * @param fun    DDF function.
    300325 * @param buffer Data place.
    301  * @param size Data place size.
     326 * @param size   Data place size.
     327 *
    302328 * @return Bytes read.
     329 *
    303330 */
    304331static int i8042_read(ddf_fun_t *fun, char *data, size_t size)
     
    306333        assert(fun);
    307334        assert(fun->driver_data);
    308 
     335       
    309336        i8042_t *controller = fun->driver_data;
    310337        buffer_t *buffer = (fun == controller->aux_fun) ?
    311338            &controller->aux_buffer : &controller->kbd_buffer;
    312         for (size_t i = 0; i < size; ++i) {
     339       
     340        for (size_t i = 0; i < size; ++i)
    313341                *data++ = buffer_read(buffer);
    314         }
     342       
    315343        return size;
    316344}
    317345
    318346/** Handle data requests.
    319  * @param fun ddf_fun_t function.
    320  * @param id callid
     347 *
     348 * @param fun  ddf_fun_t function.
     349 * @param id   callid
    321350 * @param call IPC request.
     351 *
    322352 */
    323353void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
     
    325355        const sysarg_t method = IPC_GET_IMETHOD(*call);
    326356        const size_t size = IPC_GET_ARG1(*call);
     357       
    327358        switch (method) {
    328359        case IPC_CHAR_READ:
    329360                if (size <= 4 * sizeof(sysarg_t)) {
    330361                        sysarg_t message[4] = {};
    331                         i8042_read(fun, (char*)message, size);
     362                       
     363                        i8042_read(fun, (char *) message, size);
    332364                        async_answer_4(id, size, message[0], message[1],
    333365                            message[2], message[3]);
    334                 } else {
     366                } else
    335367                        async_answer_0(id, ELIMIT);
    336                 }
    337368                break;
    338 
     369       
    339370        case IPC_CHAR_WRITE:
    340371                if (size <= 3 * sizeof(sysarg_t)) {
    341372                        const sysarg_t message[3] = {
    342                                 IPC_GET_ARG2(*call), IPC_GET_ARG3(*call),
    343                                 IPC_GET_ARG4(*call) };
    344                         i8042_write(fun, (char*)message, size);
     373                                IPC_GET_ARG2(*call),
     374                                IPC_GET_ARG3(*call),
     375                                IPC_GET_ARG4(*call)
     376                        };
     377                       
     378                        i8042_write(fun, (char *) message, size);
    345379                        async_answer_0(id, size);
    346                 } else {
     380                } else
    347381                        async_answer_0(id, ELIMIT);
    348                 }
    349 
     382       
    350383        default:
    351384                async_answer_0(id, EINVAL);
    352385        }
    353386}
     387
    354388/**
    355389 * @}
  • uspace/drv/char/i8042/i8042.h

    r304faab r786bd56  
    2727 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828 */
     29
    2930/** @addtogroup kbd_port
    3031 * @ingroup  kbd
    3132 * @{
    3233 */
     34
    3335/** @file
    3436 * @brief i8042 port driver.
     
    4143#include <fibril_synch.h>
    4244#include <ddf/driver.h>
    43 
    4445#include "buffer.h"
    4546
    46 #define BUFFER_SIZE 12
     47#define NAME  "i8042"
     48
     49#define BUFFER_SIZE  12
    4750
    4851/** i8042 HW I/O interface */
     
    5558/** i8042 driver structure. */
    5659typedef struct i8042 {
    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. */
     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. */
    6265        uint8_t aux_data[BUFFER_SIZE];  /**< Primary port buffer space. */
    6366        uint8_t kbd_data[BUFFER_SIZE];  /**< Aux. port buffer space. */
     
    6669
    6770int i8042_init(i8042_t *, void *, size_t, int, int, ddf_dev_t *);
     71
    6872#endif
     73
    6974/**
    7075 * @}
  • uspace/drv/char/i8042/main.c

    r304faab r786bd56  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
     28
    2829/** @addtogroup drvi8042
    2930 * @{
    3031 */
     32
    3133/** @file
    3234 * @brief i8042 driver DDF bits.
     
    4143#include <ddf/log.h>
    4244#include <stdio.h>
    43 
    4445#include "i8042.h"
    4546
    46 #define NAME "i8042"
     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)
    4754
    48 static int get_my_registers(const ddf_dev_t *dev,
    49     uintptr_t *io_reg_address, size_t *io_reg_size, int *kbd, int *mouse);
    50 static int i8042_dev_add(ddf_dev_t *device);
     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 */
     66static 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 */
     113static 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}
    51141
    52142/** DDF driver operations. */
     
    61151};
    62152
    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  */
    71153int main(int argc, char *argv[])
    72154{
    73         printf(NAME ": HelenOS ps/2 driver.\n");
     155        printf("%s: HelenOS PS/2 driver.\n", NAME);
    74156        ddf_log_init(NAME, LVL_NOTE);
    75157        return ddf_driver_main(&i8042_driver);
    76158}
    77159
    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  */
    83 static int i8042_dev_add(ddf_dev_t *device)
    84 {
    85         if (!device)
    86                 return EINVAL;
    87 
    88 #define CHECK_RET_RETURN(ret, message...) \
    89 if (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  */
    127 int 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 }
    166160/**
    167161 * @}
  • uspace/lib/c/generic/loc.c

    r304faab r786bd56  
    4747static FIBRIL_MUTEX_INITIALIZE(loc_callback_mutex);
    4848static bool loc_callback_created = false;
     49static loc_cat_change_cb_t cat_change_cb = NULL;
    4950
    5051static async_sess_t *loc_supp_block_sess = NULL;
     
    5455static async_sess_t *loc_consumer_sess = NULL;
    5556
    56 static loc_cat_change_cb_t cat_change_cb = NULL;
    57 
    5857static void loc_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    5958{
    60         loc_cat_change_cb_t cb_fun;
    61        
    6259        while (true) {
    6360                ipc_call_t call;
     
    6966                }
    7067               
    71                 int retval;
    72                
    7368                switch (IPC_GET_IMETHOD(call)) {
    7469                case LOC_EVENT_CAT_CHANGE:
    7570                        fibril_mutex_lock(&loc_callback_mutex);
    76                         cb_fun = cat_change_cb;
    77                         if (cb_fun != NULL) {
     71                        loc_cat_change_cb_t cb_fun = cat_change_cb;
     72                        fibril_mutex_unlock(&loc_callback_mutex);
     73                       
     74                        async_answer_0(callid, EOK);
     75                       
     76                        if (cb_fun != NULL)
    7877                                (*cb_fun)();
    79                         }
    80                         fibril_mutex_unlock(&loc_callback_mutex);
    81                         retval = 0;
     78                       
    8279                        break;
    8380                default:
    84                         retval = ENOTSUP;
     81                        async_answer_0(callid, ENOTSUP);
    8582                }
    86                
    87                 async_answer_0(callid, retval);
    8883        }
    8984}
     
    10196}
    10297
     98/** Create callback
     99 *
     100 * Must be called with loc_callback_mutex locked.
     101 *
     102 * @return EOK on success.
     103 *
     104 */
    103105static int loc_callback_create(void)
    104106{
    105         async_exch_t *exch;
    106         sysarg_t retval;
    107         int rc = EOK;
    108 
    109         fibril_mutex_lock(&loc_callback_mutex);
    110        
    111107        if (!loc_callback_created) {
    112                 exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
     108                async_exch_t *exch =
     109                    loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
    113110               
    114111                ipc_call_t answer;
    115112                aid_t req = async_send_0(exch, LOC_CALLBACK_CREATE, &answer);
    116                 async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);
     113                int rc = async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);
    117114                loc_exchange_end(exch);
    118115               
     116                if (rc != EOK)
     117                        return rc;
     118               
     119                sysarg_t retval;
    119120                async_wait_for(req, &retval);
    120                 if (rc != EOK)
    121                         goto done;
    122                
    123                 if (retval != EOK) {
    124                         rc = retval;
    125                         goto done;
    126                 }
     121                if (retval != EOK)
     122                        return retval;
    127123               
    128124                loc_callback_created = true;
    129125        }
    130126       
    131         rc = EOK;
    132 done:
    133         fibril_mutex_unlock(&loc_callback_mutex);
    134         return rc;
     127        return EOK;
    135128}
    136129
     
    795788    sysarg_t **data, size_t *count)
    796789{
    797         service_id_t *ids;
    798         size_t act_size;
    799         size_t alloc_size;
    800         int rc;
    801 
    802790        *data = NULL;
    803         act_size = 0;   /* silence warning */
    804 
    805         rc = loc_category_get_ids_once(method, arg1, NULL, 0,
     791        *count = 0;
     792       
     793        size_t act_size = 0;
     794        int rc = loc_category_get_ids_once(method, arg1, NULL, 0,
    806795            &act_size);
    807796        if (rc != EOK)
    808797                return rc;
    809 
    810         alloc_size = act_size;
    811         ids = malloc(alloc_size);
     798       
     799        size_t alloc_size = act_size;
     800        service_id_t *ids = malloc(alloc_size);
    812801        if (ids == NULL)
    813802                return ENOMEM;
    814 
     803       
    815804        while (true) {
    816805                rc = loc_category_get_ids_once(method, arg1, ids, alloc_size,
     
    818807                if (rc != EOK)
    819808                        return rc;
    820 
     809               
    821810                if (act_size <= alloc_size)
    822811                        break;
    823 
    824                 alloc_size *= 2;
    825                 free(ids);
    826 
    827                 ids = malloc(alloc_size);
     812               
     813                alloc_size = act_size;
     814                ids = realloc(ids, alloc_size);
    828815                if (ids == NULL)
    829816                        return ENOMEM;
    830817        }
    831 
     818       
    832819        *count = act_size / sizeof(category_id_t);
    833820        *data = ids;
     
    867854int loc_register_cat_change_cb(loc_cat_change_cb_t cb_fun)
    868855{
    869         if (loc_callback_create() != EOK)
     856        fibril_mutex_lock(&loc_callback_mutex);
     857        if (loc_callback_create() != EOK) {
     858                fibril_mutex_unlock(&loc_callback_mutex);
    870859                return EIO;
    871 
     860        }
     861       
    872862        cat_change_cb = cb_fun;
     863        fibril_mutex_unlock(&loc_callback_mutex);
     864       
    873865        return EOK;
    874866}
Note: See TracChangeset for help on using the changeset viewer.