Changeset cfb79747 in mainline for uspace/drv/char


Ignore:
Timestamp:
2012-02-14T22:06:15Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a31aad1
Parents:
199112e4 (diff), e10d41a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace/drv/char
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/i8042/buffer.h

    r199112e4 rcfb79747  
    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

    r199112e4 rcfb79747  
    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 
    77107static const irq_pio_range_t i8042_ranges[] = {
    78108        {
     
    86116        {
    87117                .cmd = CMD_PIO_READ_8,
    88                 .addr = NULL,   /* will be patched in run-time */
     118                .addr = NULL,  /* will be patched in run-time */
    89119                .dstarg = 1
    90120        },
     
    102132        {
    103133                .cmd = CMD_PIO_READ_8,
    104                 .addr = NULL,   /* will be patched in run-time */
     134                .addr = NULL,  /* will be patched in run-time */
    105135                .dstarg = 2
    106136        },
     
    118148
    119149/** Interrupt handler routine.
    120  * Writes new data to the corresponding buffer.
    121  * @param dev Device that caued the interrupt.
    122  * @param iid Call id.
     150 *
     151 * Write new data to the corresponding buffer.
     152 *
     153 * @param dev  Device that caued the interrupt.
     154 * @param iid  Call id.
    123155 * @param call pointerr to call data.
    124  */
    125 static void i8042_irq_handler(
    126     ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    127 {
    128         if (!dev || !dev->driver_data)
     156 *
     157 */
     158static void i8042_irq_handler(ddf_dev_t *dev, ipc_callid_t iid,
     159    ipc_call_t *call)
     160{
     161        if ((!dev) || (!dev->driver_data))
    129162                return;
     163       
    130164        i8042_t *controller = dev->driver_data;
    131 
     165       
    132166        const uint8_t status = IPC_GET_ARG1(*call);
    133167        const uint8_t data = IPC_GET_ARG2(*call);
     168       
    134169        buffer_t *buffer = (status & i8042_AUX_DATA) ?
    135170            &controller->aux_buffer : &controller->kbd_buffer;
     171       
    136172        buffer_write(buffer, data);
    137173}
    138174
    139175/** Initialize i8042 driver structure.
    140  * @param dev Driver structure to initialize.
    141  * @param regs I/O address of registers.
    142  * @param reg_size size of the reserved I/O address space.
    143  * @param irq_kbd IRQ for primary port.
     176 *
     177 * @param dev       Driver structure to initialize.
     178 * @param regs      I/O address of registers.
     179 * @param reg_size  size of the reserved I/O address space.
     180 * @param irq_kbd   IRQ for primary port.
    144181 * @param irq_mouse IRQ for aux port.
    145  * @param ddf_dev DDF device structure of the device.
     182 * @param ddf_dev   DDF device structure of the device.
     183 *
    146184 * @return Error code.
     185 *
    147186 */
    148187int i8042_init(i8042_t *dev, void *regs, size_t reg_size, int irq_kbd,
     
    151190        assert(ddf_dev);
    152191        assert(dev);
    153 
     192       
    154193        if (reg_size < sizeof(i8042_regs_t))
    155194                return EINVAL;
    156 
    157         if (pio_enable(regs, sizeof(i8042_regs_t), (void**)&dev->regs) != 0)
     195       
     196        if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0)
    158197                return -1;
    159 
     198       
    160199        dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
    161200        if (!dev->kbd_fun)
    162201                return ENOMEM;
     202       
    163203        int ret = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
    164204        if (ret != EOK) {
     
    166206                return ret;
    167207        }
    168 
     208       
    169209        dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
    170210        if (!dev->aux_fun) {
     
    172212                return ENOMEM;
    173213        }
    174 
     214       
    175215        ret = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
    176216        if (ret != EOK) {
     
    179219                return ret;
    180220        }
    181 
     221       
    182222        dev->kbd_fun->ops = &ops;
    183223        dev->aux_fun->ops = &ops;
    184224        dev->kbd_fun->driver_data = dev;
    185225        dev->aux_fun->driver_data = dev;
    186 
     226       
    187227        buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
    188228        buffer_init(&dev->aux_buffer, dev->aux_data, BUFFER_SIZE);
    189229        fibril_mutex_initialize(&dev->write_guard);
    190 
    191 #define CHECK_RET_DESTROY(ret, msg...) \
    192 if  (ret != EOK) { \
    193         ddf_msg(LVL_ERROR, msg); \
    194         if (dev->kbd_fun) { \
    195                 dev->kbd_fun->driver_data = NULL; \
    196                 ddf_fun_destroy(dev->kbd_fun); \
    197         } \
    198         if (dev->aux_fun) { \
    199                 dev->aux_fun->driver_data = NULL; \
    200                 ddf_fun_destroy(dev->aux_fun); \
    201         } \
    202 } else (void)0
    203 
     230       
    204231        ret = ddf_fun_bind(dev->kbd_fun);
    205         CHECK_RET_DESTROY(ret,
    206             "Failed to bind keyboard function: %s.", str_error(ret));
    207 
     232        CHECK_RET_DESTROY(ret, "Failed to bind keyboard function: %s.",
     233            str_error(ret));
     234       
    208235        ret = ddf_fun_bind(dev->aux_fun);
    209         CHECK_RET_DESTROY(ret,
    210             "Failed to bind mouse function: %s.", str_error(ret));
    211 
     236        CHECK_RET_DESTROY(ret, "Failed to bind mouse function: %s.",
     237            str_error(ret));
     238       
    212239        /* Disable kbd and aux */
    213240        wait_ready(dev);
     
    215242        wait_ready(dev);
    216243        pio_write_8(&dev->regs->data, i8042_KBD_DISABLE | i8042_AUX_DISABLE);
    217 
     244       
    218245        /* Flush all current IO */
    219246        while (pio_read_8(&dev->regs->status) & i8042_OUTPUT_FULL)
    220247                (void) pio_read_8(&dev->regs->data);
    221 
    222 #define CHECK_RET_UNBIND_DESTROY(ret, msg...) \
    223 if  (ret != EOK) { \
    224         ddf_msg(LVL_ERROR, msg); \
    225         if (dev->kbd_fun) { \
    226                 ddf_fun_unbind(dev->kbd_fun); \
    227                 dev->kbd_fun->driver_data = NULL; \
    228                 ddf_fun_destroy(dev->kbd_fun); \
    229         } \
    230         if (dev->aux_fun) { \
    231                 ddf_fun_unbind(dev->aux_fun); \
    232                 dev->aux_fun->driver_data = NULL; \
    233                 ddf_fun_destroy(dev->aux_fun); \
    234         } \
    235 } else (void)0
    236248
    237249        const size_t range_count = sizeof(i8042_ranges) /
     
    253265                .cmds = cmds
    254266        };
     267       
    255268        ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
    256269            &irq_code);
    257         CHECK_RET_UNBIND_DESTROY(ret,
    258             "Failed set handler for kbd: %s.", str_error(ret));
    259 
     270        CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for kbd: %s.",
     271            str_error(ret));
     272       
    260273        ret = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
    261274            &irq_code);
    262         CHECK_RET_UNBIND_DESTROY(ret,
    263             "Failed set handler for mouse: %s.", str_error(ret));
    264 
     275        CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for mouse: %s.",
     276            str_error(ret));
     277       
    265278        /* Enable interrupts */
    266279        async_sess_t *parent_sess =
     
    269282        ret = parent_sess ? EOK : ENOMEM;
    270283        CHECK_RET_UNBIND_DESTROY(ret, "Failed to create parent connection.");
    271 
     284       
    272285        const bool enabled = hw_res_enable_interrupt(parent_sess);
    273286        async_hangup(parent_sess);
    274287        ret = enabled ? EOK : EIO;
    275288        CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s.");
    276 
     289       
    277290        /* Enable port interrupts. */
    278291        wait_ready(dev);
     
    281294        pio_write_8(&dev->regs->data, i8042_KBD_IE | i8042_KBD_TRANSLATE |
    282295            i8042_AUX_IE);
    283 
     296       
    284297        return EOK;
    285298}
    286299
    287 // TODO use shared instead this
     300// FIXME TODO use shared instead this
    288301enum {
    289302        IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
     
    292305
    293306/** Write data to i8042 port.
    294  * @param fun DDF function.
     307 *
     308 * @param fun    DDF function.
    295309 * @param buffer Data source.
    296  * @param size Data size.
     310 * @param size   Data size.
     311 *
    297312 * @return Bytes written.
     313 *
    298314 */
    299315static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size)
     
    301317        assert(fun);
    302318        assert(fun->driver_data);
     319       
    303320        i8042_t *controller = fun->driver_data;
    304321        fibril_mutex_lock(&controller->write_guard);
     322       
    305323        for (size_t i = 0; i < size; ++i) {
     324                if (controller->aux_fun == fun) {
     325                        wait_ready(controller);
     326                        pio_write_8(&controller->regs->status,
     327                            i8042_CMD_WRITE_AUX);
     328                }
     329               
    306330                wait_ready(controller);
    307                 if (controller->aux_fun == fun)
    308                         pio_write_8(
    309                             &controller->regs->status, i8042_CMD_WRITE_AUX);
    310331                pio_write_8(&controller->regs->data, buffer[i]);
    311332        }
     333       
    312334        fibril_mutex_unlock(&controller->write_guard);
    313335        return size;
     
    315337
    316338/** Read data from i8042 port.
    317  * @param fun DDF function.
     339 *
     340 * @param fun    DDF function.
    318341 * @param buffer Data place.
    319  * @param size Data place size.
     342 * @param size   Data place size.
     343 *
    320344 * @return Bytes read.
     345 *
    321346 */
    322347static int i8042_read(ddf_fun_t *fun, char *data, size_t size)
     
    324349        assert(fun);
    325350        assert(fun->driver_data);
    326 
     351       
    327352        i8042_t *controller = fun->driver_data;
    328353        buffer_t *buffer = (fun == controller->aux_fun) ?
    329354            &controller->aux_buffer : &controller->kbd_buffer;
    330         for (size_t i = 0; i < size; ++i) {
     355       
     356        for (size_t i = 0; i < size; ++i)
    331357                *data++ = buffer_read(buffer);
    332         }
     358       
    333359        return size;
    334360}
    335361
    336362/** Handle data requests.
    337  * @param fun ddf_fun_t function.
    338  * @param id callid
     363 *
     364 * @param fun  ddf_fun_t function.
     365 * @param id   callid
    339366 * @param call IPC request.
     367 *
    340368 */
    341369void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
     
    343371        const sysarg_t method = IPC_GET_IMETHOD(*call);
    344372        const size_t size = IPC_GET_ARG1(*call);
     373       
    345374        switch (method) {
    346375        case IPC_CHAR_READ:
    347376                if (size <= 4 * sizeof(sysarg_t)) {
    348377                        sysarg_t message[4] = {};
    349                         i8042_read(fun, (char*)message, size);
     378                       
     379                        i8042_read(fun, (char *) message, size);
    350380                        async_answer_4(id, size, message[0], message[1],
    351381                            message[2], message[3]);
    352                 } else {
     382                } else
    353383                        async_answer_0(id, ELIMIT);
    354                 }
    355384                break;
    356 
     385       
    357386        case IPC_CHAR_WRITE:
    358387                if (size <= 3 * sizeof(sysarg_t)) {
    359388                        const sysarg_t message[3] = {
    360                                 IPC_GET_ARG2(*call), IPC_GET_ARG3(*call),
    361                                 IPC_GET_ARG4(*call) };
    362                         i8042_write(fun, (char*)message, size);
     389                                IPC_GET_ARG2(*call),
     390                                IPC_GET_ARG3(*call),
     391                                IPC_GET_ARG4(*call)
     392                        };
     393                       
     394                        i8042_write(fun, (char *) message, size);
    363395                        async_answer_0(id, size);
    364                 } else {
     396                } else
    365397                        async_answer_0(id, ELIMIT);
    366                 }
    367 
     398       
    368399        default:
    369400                async_answer_0(id, EINVAL);
    370401        }
    371402}
     403
    372404/**
    373405 * @}
  • uspace/drv/char/i8042/i8042.h

    r199112e4 rcfb79747  
    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

    r199112e4 rcfb79747  
    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/drv/char/ps2mouse/ps2mouse.c

    r199112e4 rcfb79747  
    116116        assert(mouse);
    117117        assert(dev);
    118         mouse->input_sess = NULL;
     118        mouse->client_sess = NULL;
    119119        mouse->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
    120120            dev->handle, IPC_FLAG_BLOCKING);
     
    218218
    219219                async_exch_t *exch =
    220                     async_exchange_begin(mouse->input_sess);
     220                    async_exchange_begin(mouse->client_sess);
    221221                if (!exch) {
    222222                        ddf_msg(LVL_ERROR,
    223                             "Failed to create input exchange.");
     223                            "Failed creating exchange.");
    224224                        continue;
    225225                }
     
    277277
    278278                async_exch_t *exch =
    279                     async_exchange_begin(mouse->input_sess);
     279                    async_exchange_begin(mouse->client_sess);
    280280                if (!exch) {
    281281                        ddf_msg(LVL_ERROR,
    282                             "Failed to create input exchange.");
     282                            "Failed creating exchange.");
    283283                        continue;
    284284                }
     
    386386                if (sess == NULL) {
    387387                        ddf_msg(LVL_WARN,
    388                             "Failed to create start input session");
     388                            "Failed creating client callback session");
    389389                        async_answer_0(icallid, EAGAIN);
    390390                        break;
    391391                }
    392                 if (mouse->input_sess == NULL) {
    393                         mouse->input_sess = sess;
    394                         ddf_msg(LVL_DEBUG, "Set input session");
     392                if (mouse->client_sess == NULL) {
     393                        mouse->client_sess = sess;
     394                        ddf_msg(LVL_DEBUG, "Set client session");
    395395                        async_answer_0(icallid, EOK);
    396396                } else {
    397                         ddf_msg(LVL_ERROR, "Input session already set");
     397                        ddf_msg(LVL_ERROR, "Client session already set");
    398398                        async_answer_0(icallid, ELIMIT);
    399399                }
  • uspace/drv/char/ps2mouse/ps2mouse.h

    r199112e4 rcfb79747  
    4343        ddf_fun_t *mouse_fun;      /**< Mouse function. */
    4444        async_sess_t *parent_sess; /**< Connection to device providing data. */
    45         async_sess_t *input_sess;  /**< Callback connection to consumer. */
     45        async_sess_t *client_sess;  /**< Callback connection to client. */
    4646        fid_t polling_fibril;      /**< Fibril retrieving an parsing data. */
    4747} ps2_mouse_t;
  • uspace/drv/char/xtkbd/xtkbd.c

    r199112e4 rcfb79747  
    206206        assert(kbd);
    207207        assert(dev);
    208         kbd->input_sess = NULL;
     208        kbd->client_sess = NULL;
    209209        kbd->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
    210210            dev->handle, IPC_FLAG_BLOCKING);
     
    296296                if (key != 0) {
    297297                        async_exch_t *exch =
    298                             async_exchange_begin(kbd->input_sess);
     298                            async_exchange_begin(kbd->client_sess);
    299299                        if (!exch) {
    300300                                ddf_msg(LVL_ERROR,
    301                                     "Failed to create input exchange.");
     301                                    "Failed creating exchange.");
    302302                                continue;
    303303                        }
     
    352352                if (sess == NULL) {
    353353                        ddf_msg(LVL_WARN,
    354                             "Failed to create start input session");
     354                            "Failed creating callback session");
    355355                        async_answer_0(icallid, EAGAIN);
    356356                        break;
    357357                }
    358                 if (kbd->input_sess == NULL) {
    359                         kbd->input_sess = sess;
    360                         ddf_msg(LVL_DEBUG, "Set input session");
     358                if (kbd->client_sess == NULL) {
     359                        kbd->client_sess = sess;
     360                        ddf_msg(LVL_DEBUG, "Set client session");
    361361                        async_answer_0(icallid, EOK);
    362362                } else {
    363                         ddf_msg(LVL_ERROR, "Input session already set");
     363                        ddf_msg(LVL_ERROR, "Client session already set");
    364364                        async_answer_0(icallid, ELIMIT);
    365365                }
  • uspace/drv/char/xtkbd/xtkbd.h

    r199112e4 rcfb79747  
    4343        ddf_fun_t *kbd_fun;        /**< Keyboard function. */
    4444        async_sess_t *parent_sess; /**< Connection to device providing data. */
    45         async_sess_t *input_sess;  /**< Callback connection to consumer. */
     45        async_sess_t *client_sess; /**< Callback connection to client. */
    4646        fid_t polling_fibril;      /**< Fibril retrieving an parsing data. */
    4747} xt_kbd_t;
Note: See TracChangeset for help on using the changeset viewer.