Changeset 786bd56 in mainline for uspace/drv/char/i8042/main.c


Ignore:
Timestamp:
2012-01-24T09:26:36Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 * @}
Note: See TracChangeset for help on using the changeset viewer.