Changeset b1f44b4 in mainline


Ignore:
Timestamp:
2011-12-25T19:51:11Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a8f7029
Parents:
5960b48
Message:

i8042: Start turning into standard char devices.

Location:
uspace/drv/char/i8042
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/i8042/i8042.c

    r5960b48 rb1f44b4  
    3838
    3939#include <ddi.h>
     40#include <devman.h>
     41#include <device/hw_res.h>
    4042#include <libarch/ddi.h>
    4143#include <loc.h>
     
    5254
    5355#define NAME       "i8042"
    54 #define NAMESPACE  "char"
    5556
    5657/* Interesting bits for status register */
     
    9798};
    9899
    99 static i8042_t device;
    100 
    101100static void wait_ready(i8042_t *dev)
    102101{
     
    105104}
    106105
    107 static void i8042_irq_handler(ddf_dev_t *dev,
    108     ipc_callid_t iid, ipc_call_t *call);
    109 static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    110 static void i8042_port_write(i8042_t *dev, int devid, uint8_t data);
    111 
     106static void i8042_irq_handler(
     107    ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
     108{
     109
     110        const int status = IPC_GET_ARG1(*call);
     111        const int data = IPC_GET_ARG2(*call);
     112        const int devid = (status & i8042_AUX_DATA) ? DEVID_AUX : DEVID_PRI;
     113        ddf_msg(LVL_WARN, "Unhandled %s data: %x , status: %x.",
     114            (devid == DEVID_AUX) ? "AUX" : "PRIMARY", data, status);
     115#if 0
     116        if (!dev || !dev->driver_data)
     117                return;
     118
     119        if (device.port[devid].client_sess != NULL) {
     120                async_exch_t *exch =
     121                    async_exchange_begin(device.port[devid].client_sess);
     122                if (exch) {
     123                        async_msg_1(exch, IPC_FIRST_USER_METHOD, data);
     124                        async_exchange_end(exch);
     125                }
     126        } else {
     127                ddf_msg(LVL_WARN, "No client session.\n");
     128        }
     129#endif
     130}
     131/*----------------------------------------------------------------------------*/
    112132int i8042_init(i8042_t *dev, void *regs, size_t reg_size, int irq_kbd,
    113133    int irq_mouse, ddf_dev_t *ddf_dev)
     
    177197        } \
    178198} else (void)0
     199
    179200        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    180201        irq_cmd_t cmds[cmd_count];
     
    184205
    185206        irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = cmds };
    186         ddf_msg(LVL_DEBUG,
    187             "Registering interrupt handler for device %s on irq %d.\n",
    188             ddf_dev->name, irq_kbd);
    189207        ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
    190208            &irq_code);
     
    192210            "Failed set handler for kbd: %s.\n", str_error(ret));
    193211
    194         ddf_msg(LVL_DEBUG,
    195             "Registering interrupt handler for device %s on irq %d.\n",
    196             ddf_dev->name, irq_mouse);
    197212        ret = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
    198213            &irq_code);
     
    200215            "Failed set handler for mouse: %s.\n", str_error(ret));
    201216
     217#if 0
    202218        ret = ddf_fun_add_to_category(dev->kbd_fun, "keyboard");
    203219        if (ret != EOK)
     
    206222        if (ret != EOK)
    207223                ddf_msg(LVL_WARN, "Failed to register mouse fun to category.\n");
    208 
    209         // TODO: Don't rely on kernel enabling interrupts do it yourself.
     224#endif
     225        /* Enable interrupts */
     226        async_sess_t *parent_sess =
     227            devman_parent_device_connect(EXCHANGE_SERIALIZE, ddf_dev->handle,
     228            IPC_FLAG_BLOCKING);
     229        ret = parent_sess ? EOK : ENOMEM;
     230        CHECK_RET_UNBIND_DESTROY(ret, "Failed to create parent connection.\n");
     231        const bool enabled = hw_res_enable_interrupt(parent_sess);
     232        async_hangup(parent_sess);
     233        ret = enabled ? EOK : EIO;
     234        CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s.\n");
     235
    210236
    211237        wait_ready(dev);
     
    215241            i8042_AUX_IE);
    216242
    217         // TODO: Plug in connection.
    218 
    219         return ret;
    220         (void)i8042_connection;
     243        return EOK;
    221244}
    222245
    223246/** Character device connection handler */
     247#if 0
    224248static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    225249{
     
    288312        }
    289313}
    290 
    291314void i8042_port_write(i8042_t *dev, int devid, uint8_t data)
    292315{
     
    300323        pio_write_8(&dev->regs->data, data);
    301324}
    302 
    303 void i8042_irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    304 {
    305         ddf_msg(LVL_FATAL, "IRQ!!!.\n");
    306         if (!dev || !dev->driver_data)
    307                 return;
    308 
    309         const int status = IPC_GET_ARG1(*call);
    310         const int data = IPC_GET_ARG2(*call);
    311         const int devid = (status & i8042_AUX_DATA) ? DEVID_AUX : DEVID_PRI;
    312 
    313         if (device.port[devid].client_sess != NULL) {
    314                 async_exch_t *exch =
    315                     async_exchange_begin(device.port[devid].client_sess);
    316                 if (exch) {
    317                         async_msg_1(exch, IPC_FIRST_USER_METHOD, data);
    318                         async_exchange_end(exch);
    319                 }
    320         } else {
    321                 ddf_msg(LVL_WARN, "No client session.\n");
    322         }
    323 }
     325#endif
    324326
    325327/**
  • uspace/drv/char/i8042/i8042.h

    r5960b48 rb1f44b4  
    4242#include <libarch/ddi.h>
    4343#include <async.h>
     44#include <fibril_synch.h>
    4445#include <ddf/driver.h>
    4546
     
    5253
    5354/** Softstate structure, one for each serial port (primary and aux). */
     55/*
    5456typedef struct {
    5557        service_id_t service_id;
    5658        async_sess_t *client_sess;
    5759} i8042_port_t;
     60*/
     61
     62typedef struct i8042 i8042_t;
    5863
    5964enum {
     
    6368};
    6469
    65 typedef struct {
     70struct i8042 {
    6671        i8042_regs_t *regs;
    67         i8042_port_t port[MAX_DEVS];
     72//      i8042_port_t port[MAX_DEVS];
    6873        ddf_fun_t *kbd_fun;
    6974        ddf_fun_t *mouse_fun;
    70 } i8042_t;
     75        fibril_mutex_t guard;
     76        fibril_condvar_t data_avail;
     77};
    7178
    7279int i8042_init(i8042_t *, void *, size_t, int, int, ddf_dev_t *);
     80int i8042_write_kbd(i8042_t *, uint8_t);
     81int i8042_read_kbd(i8042_t *, uint8_t *);
     82int i8042_write_aux(i8042_t *, uint8_t);
     83int i8042_read_aux(i8042_t *, uint8_t *);
    7384
    7485#endif
  • uspace/drv/char/i8042/main.c

    r5960b48 rb1f44b4  
    114114        return EOK;
    115115}
    116 
     116/*----------------------------------------------------------------------------*/
    117117/** Get address of I/O registers.
    118118 *
     
    161161        return EOK;
    162162}
    163 
    164163/**
    165164 * @}
Note: See TracChangeset for help on using the changeset viewer.