niagara.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Pavel Rimsky
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #include <as.h>
00038 #include <ddi.h>
00039 #include <async.h>
00040 #include <kbd.h>
00041 #include <kbd_port.h>
00042 #include <sysinfo.h>
00043 #include <stdio.h>
00044 #include <thread.h>
00045 #include <bool.h>
00046 #include <errno.h>
00047 
00048 #define POLL_INTERVAL  10000
00049 
00053 static uintptr_t input_buffer_addr;
00054 
00055 /*
00056  * Kernel counterpart of the driver pushes characters (it has read) here.
00057  * Keep in sync with the definition from
00058  * kernel/arch/sparc64/src/drivers/niagara.c.
00059  */
00060 #define INPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
00061 
00062 typedef volatile struct {
00063         uint64_t write_ptr;
00064         uint64_t read_ptr;
00065         char data[INPUT_BUFFER_SIZE];
00066 }
00067         __attribute__ ((packed))
00068         __attribute__ ((aligned(PAGE_SIZE)))
00069         *input_buffer_t;
00070 
00071 /* virtual address of the shared buffer */
00072 input_buffer_t input_buffer;
00073 
00074 static volatile bool polling_disabled = false;
00075 static void niagara_thread_impl(void *arg);
00076 
00081 int kbd_port_init(void)
00082 {
00083         sysarg_t paddr;
00084         if (sysinfo_get_value("niagara.inbuf.address", &paddr) != EOK)
00085                 return -1;
00086         
00087         input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
00088         int rc = physmem_map((void *) paddr, (void *) input_buffer_addr,
00089             1, AS_AREA_READ | AS_AREA_WRITE);
00090         
00091         if (rc != 0) {
00092                 printf("Niagara: uspace driver couldn't map physical memory: %d\n",
00093                     rc);
00094                 return rc;
00095         }
00096         
00097         input_buffer = (input_buffer_t) input_buffer_addr;
00098         
00099         thread_id_t tid;
00100         rc = thread_create(niagara_thread_impl, NULL, "kbd_poll", &tid);
00101         if (rc != 0)
00102                 return rc;
00103         
00104         return 0;
00105 }
00106 
00107 void kbd_port_yield(void)
00108 {
00109         polling_disabled = true;
00110 }
00111 
00112 void kbd_port_reclaim(void)
00113 {
00114         polling_disabled = false;
00115 }
00116 
00117 void kbd_port_write(uint8_t data)
00118 {
00119         (void) data;
00120 }
00121 
00126 static void niagara_key_pressed(void)
00127 {
00128         char c;
00129         
00130         while (input_buffer->read_ptr != input_buffer->write_ptr) {
00131                 c = input_buffer->data[input_buffer->read_ptr];
00132                 input_buffer->read_ptr =
00133                         ((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE;
00134                 kbd_push_scancode(c);
00135         }
00136 }
00137 
00141 static void niagara_thread_impl(void *arg)
00142 {
00143         (void) arg;
00144 
00145         while (1) {
00146                 if (polling_disabled == false)
00147                         niagara_key_pressed();
00148                 usleep(POLL_INTERVAL);
00149         }
00150 }

Generated on Thu Jun 2 07:45:49 2011 for HelenOS/USB by  doxygen 1.4.7