Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:18

0001 /**
0002  * @file
0003  *
0004  * @ingroup libmisc_fb_mw Input Devices for MicroWindows
0005  *
0006  * @brief MicroWindows UID
0007  *
0008  * This module implements the input devices interface used by MicroWindows
0009  * in an embedded system environment.  It uses the RTEMS message queue as
0010  * the repository for the messages posted by the devices registered.
0011  */
0012 
0013 /*
0014  * Copyright (c) 2000 - Rosimildo da Silva
0015  */
0016 
0017 #ifdef HAVE_CONFIG_H
0018 #include "config.h"
0019 #endif
0020 
0021 #include <stdio.h>
0022 #include <fcntl.h>
0023 #include <sys/ioctl.h>
0024 #include <errno.h>
0025 #include <rtems.h>
0026 
0027 #include <rtems/mw_uid.h>
0028 #include <rtems/seterr.h>
0029 
0030 static rtems_id  queue_id = 0;
0031 static int       open_count = 0;
0032 
0033 /*
0034 #define MW_DEBUG_ON     1
0035 */
0036 
0037 /* open a message queue with the kernel */
0038 int uid_open_queue(
0039   const char *q_name,
0040   int         flags RTEMS_UNUSED,
0041   size_t      max_msgs
0042 )
0043 {
0044   rtems_status_code status;
0045 
0046   /*
0047    * For the first device calling this function we would create the queue.
0048    * It is assumed that this call is done at initialization, and no concerns
0049    * regarding multi-threading is taken in consideration here.
0050    */
0051   if ( open_count ) {
0052     open_count++;
0053     return 0;
0054   }
0055 
0056   status = rtems_message_queue_create(
0057     rtems_build_name( q_name[0], q_name[1], q_name[2], q_name[3] ),
0058     max_msgs,
0059     sizeof( struct MW_UID_MESSAGE ),
0060     RTEMS_FIFO | RTEMS_LOCAL,
0061     &queue_id
0062   );
0063   if ( status != RTEMS_SUCCESSFUL ) {
0064     #ifdef MW_DEBUG_ON
0065       printk( "UID_Queue: error creating queue: %d\n", status );
0066      #endif
0067     return -1;
0068   }
0069   #ifdef MW_DEBUG_ON
0070     printk( "UID_Queue: id=%X\n", queue_id );
0071   #endif
0072   open_count++;
0073   return 0;
0074 }
0075 
0076 
0077 /* close message queue */
0078 int uid_close_queue( void )
0079 {
0080   if ( open_count == 1 ) {
0081     rtems_message_queue_delete( queue_id );
0082     queue_id = 0;
0083   }
0084   open_count--;
0085   return 0;
0086 }
0087 
0088 /* reads for a message from the device */
0089 int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout )
0090 {
0091   rtems_status_code status;
0092   size_t            size = 0;
0093   int               wait = (timeout != 0);
0094   int ticks = RTEMS_MICROSECONDS_TO_TICKS(timeout * 1000);
0095 
0096   if (timeout == (unsigned long) -1) {
0097     ticks = RTEMS_NO_TIMEOUT;
0098   } else if (timeout && ticks == 0) {
0099     /* if timeout greater than 0 and smaller than a tick, round up to avoid
0100      * unintentionally RTEMS_NO_TIMEOUT
0101      */
0102     ticks = 1;
0103   }
0104 
0105   status = rtems_message_queue_receive(
0106    queue_id,
0107    (void*)m,
0108    &size,
0109    wait ? RTEMS_WAIT : RTEMS_NO_WAIT,
0110    ticks
0111   );
0112 
0113   if( status == RTEMS_SUCCESSFUL ) {
0114      return size;
0115   } else if( ( status == RTEMS_UNSATISFIED ) || ( status == RTEMS_TIMEOUT ) ) {
0116      rtems_set_errno_and_return_minus_one( ETIMEDOUT );
0117   }
0118   /* Here we have one error condition */
0119   #ifdef MW_DEBUG_ON
0120     printk( "UID_Queue: error reading queue: %d\n", status );
0121   #endif
0122   return -1;
0123 }
0124 
0125 /*
0126  * add a message to the queue of events. This method can be used to
0127  * simulate hardware events, and it can be very handy during development
0128  * a new interface.
0129  */
0130 int uid_send_message( struct MW_UID_MESSAGE *m )
0131 {
0132   rtems_status_code status;
0133   status = rtems_message_queue_send(
0134     queue_id, ( void * )m, sizeof( struct MW_UID_MESSAGE ) );
0135   return (status == RTEMS_SUCCESSFUL) ? 0 : -1;
0136 }
0137 
0138 /*
0139  * register the device to insert events to the message
0140  * queue named as the value passed in q_name
0141  */
0142 int uid_register_device( int fd, const char *q_name )
0143 {
0144   return ioctl( fd, MW_UID_REGISTER_DEVICE, q_name );
0145 }
0146 
0147 /* tell this device to stop adding events to the queue */
0148 int uid_unregister_device( int fd )
0149 {
0150   return ioctl( fd, MW_UID_UNREGISTER_DEVICE, NULL );
0151 }
0152 
0153 /* set the keyboard */
0154 int uid_set_kbd_mode( int fd, int mode, int *old_mode )
0155 {
0156   if (ioctl( fd, MV_KDGKBMODE, old_mode) < 0) {
0157      return -1;
0158   }
0159   if (ioctl(fd, MV_KDSKBMODE, mode ) < 0 ) {
0160      return -1;
0161   }
0162   return 0;
0163 }