Changeset 15c5418 in mainline for uspace/drv/hid/ps2mouse/ps2mouse.c


Ignore:
Timestamp:
2017-11-18T20:06:15Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
75fcf9b
Parents:
efb9fd08
Message:

chardev_open, chardev_close.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/hid/ps2mouse/ps2mouse.c

    refb9fd08 r15c5418  
    11/*
    22 * Copyright (c) 2011 Jan Vesely
     3 * Copyright (c) 2017 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3031 */
    3132/** @file
    32  * @brief ps2 mouse driver.
     33 * @brief PS/2 mouse driver.
    3334 */
    3435
     
    7071#define PS2_BUTTON_MASK(button) (1 << button)
    7172
    72 #define MOUSE_READ_BYTE_TEST(sess, value_) \
     73#define MOUSE_READ_BYTE_TEST(mouse, value_) \
    7374do { \
    7475        uint8_t value = (value_); \
    7576        uint8_t data = 0; \
    76         const ssize_t size = chardev_read(sess, &data, 1); \
     77        const ssize_t size = chardev_read((mouse)->chardev, &data, 1); \
    7778        if (size != 1) { \
    7879                ddf_msg(LVL_ERROR, "Failed reading byte: %zd)", size);\
     
    8687} while (0)
    8788
    88 #define MOUSE_WRITE_BYTE(sess, value_) \
     89#define MOUSE_WRITE_BYTE(mouse, value_) \
    8990do { \
    9091        uint8_t value = (value_); \
    9192        uint8_t data = (value); \
    92         const ssize_t size = chardev_write(sess, &data, 1); \
     93        const ssize_t size = chardev_write((mouse)->chardev, &data, 1); \
    9394        if (size < 0 ) { \
    9495                ddf_msg(LVL_ERROR, "Failed writing byte: %hhx", value); \
     
    99100static int polling_ps2(void *);
    100101static int polling_intellimouse(void *);
    101 static int probe_intellimouse(async_exch_t *, bool);
     102static int probe_intellimouse(ps2_mouse_t *, bool);
    102103static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    103104
     
    108109
    109110/** Initialize mouse driver structure.
     111 *
     112 * Connects to parent, creates keyboard function, starts polling fibril.
     113 *
    110114 * @param kbd Mouse driver structure to initialize.
    111115 * @param dev DDF device structure.
    112116 *
    113  * Connects to parent, creates keyboard function, starts polling fibril.
     117 * @return EOK on success or non-zero error code
    114118 */
    115119int ps2_mouse_init(ps2_mouse_t *mouse, ddf_dev_t *dev)
    116120{
     121        async_sess_t *parent_sess;
     122        bool bound = false;
     123        int rc;
     124
    117125        mouse->client_sess = NULL;
    118         mouse->parent_sess = ddf_dev_parent_sess_get(dev);
    119         if (!mouse->parent_sess)
    120                 return ENOMEM;
     126
     127        parent_sess = ddf_dev_parent_sess_get(dev);
     128        if (parent_sess == NULL) {
     129                ddf_msg(LVL_ERROR, "Failed getting parent session.");
     130                rc = ENOMEM;
     131                goto error;
     132        }
     133
     134        rc = chardev_open(parent_sess, &mouse->chardev);
     135        if (rc != EOK) {
     136                ddf_msg(LVL_ERROR, "Failed opening character device.");
     137                goto error;
     138        }
    121139
    122140        mouse->mouse_fun = ddf_fun_create(dev, fun_exposed, "mouse");
    123         if (!mouse->mouse_fun) {
    124                 return ENOMEM;
    125         }
     141        if (mouse->mouse_fun == NULL) {
     142                ddf_msg(LVL_ERROR, "Error creating mouse function.");
     143                rc = ENOMEM;
     144                goto error;
     145        }
     146
    126147        ddf_fun_set_ops(mouse->mouse_fun, &mouse_ops);
    127148
    128         int ret = ddf_fun_bind(mouse->mouse_fun);
    129         if (ret != EOK) {
    130                 ddf_fun_destroy(mouse->mouse_fun);
    131                 return ENOMEM;
    132         }
    133 
    134         ret = ddf_fun_add_to_category(mouse->mouse_fun, "mouse");
    135         if (ret != EOK) {
    136                 ddf_fun_unbind(mouse->mouse_fun);
    137                 ddf_fun_destroy(mouse->mouse_fun);
    138                 return ENOMEM;
    139         }
     149        rc = ddf_fun_bind(mouse->mouse_fun);
     150        if (rc != EOK) {
     151                ddf_msg(LVL_ERROR, "Failed binding mouse function.");
     152                goto error;
     153        }
     154
     155        bound = true;
     156
     157        rc = ddf_fun_add_to_category(mouse->mouse_fun, "mouse");
     158        if (rc != EOK) {
     159                ddf_msg(LVL_ERROR, "Failed adding mouse function to category.");
     160                goto error;
     161        }
     162
    140163        /* Probe IntelliMouse extensions. */
    141164        int (*polling_f)(void*) = polling_ps2;
    142         async_exch_t *exch = async_exchange_begin(mouse->parent_sess);
    143         if (probe_intellimouse(exch, false) == EOK) {
     165        if (probe_intellimouse(mouse, false) == EOK) {
    144166                ddf_msg(LVL_NOTE, "Enabled IntelliMouse extensions");
    145167                polling_f = polling_intellimouse;
    146                 if (probe_intellimouse(exch, true) == EOK)
     168                if (probe_intellimouse(mouse, true) == EOK)
    147169                        ddf_msg(LVL_NOTE, "Enabled 4th and 5th button.");
    148170        }
     171
    149172        /* Enable mouse data reporting. */
    150173        uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT;
    151         ssize_t size = chardev_write(exch, &report, 1);
     174        ssize_t size = chardev_write(mouse->chardev, &report, 1);
    152175        if (size != 1) {
    153176                ddf_msg(LVL_ERROR, "Failed to enable data reporting.");
    154                 async_exchange_end(exch);
    155                 ddf_fun_unbind(mouse->mouse_fun);
    156                 ddf_fun_destroy(mouse->mouse_fun);
    157                 return EIO;
    158         }
    159 
    160         size = chardev_read(exch, &report, 1);
    161         async_exchange_end(exch);
     177                rc = EIO;
     178                goto error;
     179        }
     180
     181        size = chardev_read(mouse->chardev, &report, 1);
    162182        if (size != 1 || report != PS2_MOUSE_ACK) {
    163183                ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.",
    164184                    report);
    165                 ddf_fun_unbind(mouse->mouse_fun);
    166                 ddf_fun_destroy(mouse->mouse_fun);
    167                 return EIO;
     185                rc = EIO;
     186                goto error;
    168187        }
    169188
    170189        mouse->polling_fibril = fibril_create(polling_f, mouse);
    171         if (!mouse->polling_fibril) {
    172                 ddf_fun_unbind(mouse->mouse_fun);
    173                 ddf_fun_destroy(mouse->mouse_fun);
    174                 return ENOMEM;
    175         }
     190        if (mouse->polling_fibril == 0) {
     191                rc = ENOMEM;
     192                goto error;
     193        }
     194
    176195        fibril_add_ready(mouse->polling_fibril);
    177196        return EOK;
     197error:
     198        if (bound)
     199                ddf_fun_unbind(mouse->mouse_fun);
     200        if (mouse->mouse_fun != NULL) {
     201                ddf_fun_destroy(mouse->mouse_fun);
     202                mouse->mouse_fun = NULL;
     203        }
     204
     205        chardev_close(mouse->chardev);
     206        mouse->chardev = NULL;
     207        return rc;
    178208}
    179209
     
    184214int polling_ps2(void *arg)
    185215{
    186         assert(arg);
    187         const ps2_mouse_t *mouse = arg;
    188 
    189         assert(mouse->parent_sess);
     216        ps2_mouse_t *mouse = (ps2_mouse_t *) arg;
     217
    190218        bool buttons[PS2_BUTTON_COUNT] = {};
    191         async_exch_t *parent_exch = async_exchange_begin(mouse->parent_sess);
    192219        while (1) {
    193 
    194220                uint8_t packet[PS2_BUFSIZE] = {};
    195221                const ssize_t size =
    196                     chardev_read(parent_exch, packet, PS2_BUFSIZE);
     222                    chardev_read(mouse->chardev, packet, PS2_BUFSIZE);
    197223
    198224                if (size != PS2_BUFSIZE) {
     
    232258                async_exchange_end(exch);
    233259        }
    234         async_exchange_end(parent_exch);
     260
     261        return 0;
    235262}
    236263
     
    241268static int polling_intellimouse(void *arg)
    242269{
    243         assert(arg);
    244         const ps2_mouse_t *mouse = arg;
    245 
    246         assert(mouse->parent_sess);
     270        ps2_mouse_t *mouse = (ps2_mouse_t *) arg;
     271
    247272        bool buttons[INTELLIMOUSE_BUTTON_COUNT] = {};
    248         async_exch_t *parent_exch = NULL;
    249273        while (1) {
    250                 if (!parent_exch)
    251                         parent_exch = async_exchange_begin(mouse->parent_sess);
    252 
    253274                uint8_t packet[INTELLIMOUSE_BUFSIZE] = {};
    254275                const ssize_t size = chardev_read(
    255                     parent_exch, packet, INTELLIMOUSE_BUFSIZE);
     276                    mouse->chardev, packet, INTELLIMOUSE_BUFSIZE);
    256277
    257278                if (size != INTELLIMOUSE_BUFSIZE) {
     
    310331                async_exchange_end(exch);
    311332        }
    312         async_exchange_end(parent_exch);
     333
     334        return 0;
    313335}
    314336
     
    319341 * See http://www.computer-engineering.org/ps2mouse/ for details.
    320342 */
    321 static int probe_intellimouse(async_exch_t *exch, bool buttons)
     343static int probe_intellimouse(ps2_mouse_t *mouse, bool buttons)
    322344{
    323         assert(exch);
    324 
    325         MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE);
    326         MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
    327         MOUSE_WRITE_BYTE(exch, 200);
    328         MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
    329 
    330         MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE);
    331         MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
    332         MOUSE_WRITE_BYTE(exch, buttons ? 200 : 100);
    333         MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
    334 
    335         MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE);
    336         MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
    337         MOUSE_WRITE_BYTE(exch, 80);
    338         MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
    339 
    340         MOUSE_WRITE_BYTE(exch, PS2_MOUSE_GET_DEVICE_ID);
    341         MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
    342         MOUSE_READ_BYTE_TEST(exch, buttons ? 4 : 3);
     345        MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE);
     346        MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
     347        MOUSE_WRITE_BYTE(mouse, 200);
     348        MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
     349
     350        MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE);
     351        MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
     352        MOUSE_WRITE_BYTE(mouse, buttons ? 200 : 100);
     353        MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
     354
     355        MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE);
     356        MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
     357        MOUSE_WRITE_BYTE(mouse, 80);
     358        MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
     359
     360        MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_GET_DEVICE_ID);
     361        MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
     362        MOUSE_READ_BYTE_TEST(mouse, buttons ? 4 : 3);
    343363
    344364        return EOK;
Note: See TracChangeset for help on using the changeset viewer.