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

Changeset 2df6f6fe in mainline


Ignore:
Timestamp:
2012-01-23T18:24:10Z (8 years ago)
Author:
Martin Decky <martin@…>
Branches:
master
Children:
786bd56, 876f6463, 948911d
Parents:
88dfee7
Message:

cstyle and cleanup
(no change in functionality)

Location:
uspace/drv
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/pci/pciintel/pci.c

    r88dfee7 r2df6f6fe  
    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

    r88dfee7 r2df6f6fe  
    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

    r88dfee7 r2df6f6fe  
    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

    r88dfee7 r2df6f6fe  
    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

    r88dfee7 r2df6f6fe  
    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 * @}
Note: See TracChangeset for help on using the changeset viewer.