Changeset bfa4ffa in mainline for uspace/srv/hid/input/input.c


Ignore:
Timestamp:
2016-12-27T13:34:08Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9185e42
Parents:
0d9b4a8 (diff), 73d8600 (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 from lp:~jakub/helenos/sun4u

This merge brings support for serial console on the QEMU sun4u machine
and by extension on any system that provides at least one device driver
for a serial port device in the 'serial' location service category and
points the 'console' boot argument to it.

The 'console' boot argument is used to differentiate character devices
that are used as a console from other character devices that may be used
for other purposes (e.g. SLIP or keyboard).

Support for real-world sun4u machines is temporarily broken. The legacy
ns16550 input port driver has been discontinued. Real-world Ultra 5,
which is fairly close to the QEMU machine should be easy to revive. In
order to support the sun4u QEMU machine, a new sun4u platform driver was
added. The isa driver was modified to be usable also for the EBUS bus.

On sparc64 the boot argument is passed in the boot-args boot prom
environment variable. On ia32 and amd64, the boot argument can be set in
grub.cfg as an argument to the multiboot command. The backslashes need
to be properly escaped. Other platforms don't have support for boot
arguments yet.

Because the user input/output subsystem is apparently not ready to drive
the serial console next to the ordinary console or the GUI, the serial
console mode is mutually exclusive with the normal
keyboard/ega/fb/compositor mode.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/input/input.c

    r0d9b4a8 rbfa4ffa  
    4242#include <ipc/services.h>
    4343#include <ipc/input.h>
    44 #include <sysinfo.h>
     44#include <config.h>
    4545#include <stdio.h>
    4646#include <unistd.h>
     
    5454#include <loc.h>
    5555#include <str_error.h>
     56#include <char_dev_iface.h>
     57#include <fibril.h>
    5658#include "layout.h"
    5759#include "kbd.h"
     
    6062#include "mouse.h"
    6163#include "mouse_proto.h"
     64#include "serial.h"
    6265#include "input.h"
    63 
    64 bool irc_service = false;
    65 async_sess_t *irc_sess = NULL;
    6666
    6767#define NUM_LAYOUTS  4
     
    9292static bool active = true;
    9393
     94/** Serial console specified by the user */
     95static char *serial_console;
     96
    9497/** List of keyboard devices */
    9598static list_t kbd_devs;
     
    97100/** List of mouse devices */
    98101static list_t mouse_devs;
     102
     103/** List of serial devices */
     104static list_t serial_devs;
    99105
    100106static FIBRIL_MUTEX_INITIALIZE(discovery_lock);
     
    395401        mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t));
    396402        if (mdev == NULL) {
    397                 printf("%s: Error allocating keyboard device. "
     403                printf("%s: Error allocating mouse device. "
    398404                    "Out of memory.\n", NAME);
    399405                return NULL;
     
    403409       
    404410        return mdev;
     411}
     412
     413static serial_dev_t *serial_dev_new(void)
     414{
     415        serial_dev_t *sdev = calloc(1, sizeof(serial_dev_t));
     416        if (sdev == NULL) {
     417                printf("%s: Error allocating serial device. "
     418                    "Out of memory.\n", NAME);
     419                return NULL;
     420        }
     421       
     422        sdev->kdev = kbd_dev_new();
     423        if (sdev->kdev == NULL) {
     424                free(sdev);
     425                return NULL;
     426        }
     427
     428        link_initialize(&sdev->link);
     429       
     430        return sdev;
    405431}
    406432
     
    532558        return -1;
    533559}
     560
     561static int serial_consumer(void *arg)
     562{
     563        serial_dev_t *sdev = (serial_dev_t *) arg;
     564
     565        while (true) {
     566                uint8_t data;
     567
     568                char_dev_read(sdev->sess, &data, sizeof(data));
     569                kbd_push_data(sdev->kdev, data);
     570        }
     571
     572        return EOK;
     573}
     574
     575/** Add new serial console device.
     576 *
     577 * @param service_id Service ID of the chardev device
     578 *
     579 */
     580static int serial_add_srldev(service_id_t service_id, serial_dev_t **sdevp)
     581{
     582        bool match = false;
     583
     584        serial_dev_t *sdev = serial_dev_new();
     585        if (sdev == NULL)
     586                return -1;
     587       
     588        sdev->kdev->svc_id = service_id;
     589       
     590        int rc = loc_service_get_name(service_id, &sdev->kdev->svc_name);
     591        if (rc != EOK)
     592                goto fail;
     593
     594        list_append(&sdev->link, &serial_devs);
     595
     596        /*
     597         * Is this the device the user wants to use as a serial console?
     598         */
     599        match = (serial_console != NULL) &&
     600            !str_cmp(serial_console, sdev->kdev->svc_name);
     601
     602        if (match) {
     603                sdev->kdev->ctl_ops = &stty_ctl;
     604
     605                /* Initialize controller driver. */
     606                if ((*sdev->kdev->ctl_ops->init)(sdev->kdev) != 0) {
     607                        list_remove(&sdev->link);
     608                        goto fail;
     609                }
     610
     611                sdev->sess = loc_service_connect(service_id, INTERFACE_DDF,
     612                    IPC_FLAG_BLOCKING);
     613
     614                fid_t fid = fibril_create(serial_consumer, sdev);
     615                fibril_add_ready(fid);
     616        }
     617       
     618        *sdevp = sdev;
     619        return EOK;
     620       
     621fail:
     622        if (sdev->kdev->svc_name != NULL)
     623                free(sdev->kdev->svc_name);
     624        free(sdev->kdev);
     625        free(sdev);
     626        return -1;
     627}
     628
    534629
    535630/** Add legacy drivers/devices. */
     
    555650        kbd_add_dev(&niagara_port, &stty_ctl);
    556651#endif
    557 #if defined(UARCH_sparc64) && defined(MACHINE_generic)
    558         kbd_add_dev(&ns16550_port, &sun_ctl);
    559 #endif
    560652        /* Silence warning on abs32le about kbd_add_dev() being unused */
    561653        (void) kbd_add_dev;
     
    678770}
    679771
     772static int dev_check_new_serialdevs(void)
     773{
     774        category_id_t serial_cat;
     775        service_id_t *svcs;
     776        size_t count, i;
     777        bool already_known;
     778        int rc;
     779       
     780        rc = loc_category_get_id("serial", &serial_cat, IPC_FLAG_BLOCKING);
     781        if (rc != EOK) {
     782                printf("%s: Failed resolving category 'serial'.\n", NAME);
     783                return ENOENT;
     784        }
     785       
     786        /*
     787         * Check for new serial devices
     788         */
     789        rc = loc_category_get_svcs(serial_cat, &svcs, &count);
     790        if (rc != EOK) {
     791                printf("%s: Failed getting list of serial devices.\n",
     792                    NAME);
     793                return EIO;
     794        }
     795
     796        for (i = 0; i < count; i++) {
     797                already_known = false;
     798               
     799                /* Determine whether we already know this device. */
     800                list_foreach(serial_devs, link, serial_dev_t, sdev) {
     801                        if (sdev->kdev->svc_id == svcs[i]) {
     802                                already_known = true;
     803                                break;
     804                        }
     805                }
     806               
     807                if (!already_known) {
     808                        serial_dev_t *sdev;
     809                        if (serial_add_srldev(svcs[i], &sdev) == EOK) {
     810                                printf("%s: Connected serial device '%s'\n",
     811                                    NAME, sdev->kdev->svc_name);
     812                        }
     813                }
     814        }
     815       
     816        free(svcs);
     817       
     818        /* XXX Handle device removal */
     819       
     820        return EOK;
     821}
     822
    680823static int dev_check_new(void)
    681824{
     
    684827        fibril_mutex_lock(&discovery_lock);
    685828       
    686         rc = dev_check_new_kbdevs();
    687         if (rc != EOK) {
    688                 fibril_mutex_unlock(&discovery_lock);
    689                 return rc;
    690         }
    691        
    692         rc = dev_check_new_mousedevs();
    693         if (rc != EOK) {
    694                 fibril_mutex_unlock(&discovery_lock);
    695                 return rc;
     829        if (!serial_console) {
     830                rc = dev_check_new_kbdevs();
     831                if (rc != EOK) {
     832                        fibril_mutex_unlock(&discovery_lock);
     833                        return rc;
     834                }
     835       
     836                rc = dev_check_new_mousedevs();
     837                if (rc != EOK) {
     838                        fibril_mutex_unlock(&discovery_lock);
     839                        return rc;
     840                }
     841        } else {
     842                rc = dev_check_new_serialdevs();
     843                if (rc != EOK) {
     844                        fibril_mutex_unlock(&discovery_lock);
     845                        return rc;
     846                }
    696847        }
    697848       
     
    726877int main(int argc, char **argv)
    727878{
     879        int rc;
     880
    728881        if (argc < 2) {
    729882                usage(argv[0]);
     
    733886        printf("%s: HelenOS input service\n", NAME);
    734887       
    735         sysarg_t obio;
    736        
    737888        list_initialize(&clients);
    738889        list_initialize(&kbd_devs);
    739890        list_initialize(&mouse_devs);
    740        
    741         if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
    742                 irc_service = true;
    743        
    744         if (irc_service) {
    745                 while (irc_sess == NULL)
    746                         irc_sess = service_connect_blocking(SERVICE_IRC,
    747                             INTERFACE_IRC, 0);
    748         }
     891        list_initialize(&serial_devs);
     892       
     893        serial_console = config_get_value("console");
    749894       
    750895        /* Add legacy keyboard devices. */
     
    759904        async_set_fallback_port_handler(client_connection, NULL);
    760905       
    761         int rc = loc_server_register(NAME);
     906        rc = loc_server_register(NAME);
    762907        if (rc != EOK) {
    763908                printf("%s: Unable to register server\n", NAME);
Note: See TracChangeset for help on using the changeset viewer.