main.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Vojtech Horky
00003  * Copyright (c) 2011 Lubos Slovak
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * - Redistributions of source code must retain the above copyright
00011  *   notice, this list of conditions and the following disclaimer.
00012  * - Redistributions in binary form must reproduce the above copyright
00013  *   notice, this list of conditions and the following disclaimer in the
00014  *   documentation and/or other materials provided with the distribution.
00015  * - The name of the author may not be used to endorse or promote products
00016  *   derived from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00019  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00020  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00021  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00023  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00024  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00025  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00027  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00038 #include <ddf/driver.h>
00039 #include <usb/debug.h>
00040 #include <errno.h>
00041 #include <str_error.h>
00042 
00043 #include <usb/dev/driver.h>
00044 
00045 #include "kbddev.h"
00046 #include "kbdrepeat.h"
00047 
00048 /*----------------------------------------------------------------------------*/
00049 
00050 #define NAME "usbkbd"
00051 
00077 static int usb_kbd_try_add_device(usb_device_t *dev)
00078 {
00079         /* Create the function exposed under /dev/devices. */
00080         ddf_fun_t *kbd_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, 
00081             "keyboard");
00082         if (kbd_fun == NULL) {
00083                 usb_log_error("Could not create DDF function node.\n");
00084                 return ENOMEM;
00085         }
00086         
00087         /* 
00088          * Initialize device (get and process descriptors, get address, etc.)
00089          */
00090         usb_log_debug("Initializing USB/HID KBD device...\n");
00091         
00092         usb_kbd_t *kbd_dev = usb_kbd_new();
00093         if (kbd_dev == NULL) {
00094                 usb_log_error("Error while creating USB/HID KBD device "
00095                     "structure.\n");
00096                 ddf_fun_destroy(kbd_fun);
00097                 return ENOMEM;  // TODO: some other code??
00098         }
00099         
00100         int rc = usb_kbd_init(kbd_dev, dev);
00101         
00102         if (rc != EOK) {
00103                 usb_log_error("Failed to initialize USB/HID KBD device.\n");
00104                 ddf_fun_destroy(kbd_fun);
00105                 usb_kbd_free(&kbd_dev);
00106                 return rc;
00107         }       
00108         
00109         usb_log_debug("USB/HID KBD device structure initialized.\n");
00110         
00111         /*
00112          * Store the initialized keyboard device and keyboard ops
00113          * to the DDF function.
00114          */
00115         kbd_fun->driver_data = kbd_dev;
00116         kbd_fun->ops = &keyboard_ops;
00117 
00118         rc = ddf_fun_bind(kbd_fun);
00119         if (rc != EOK) {
00120                 usb_log_error("Could not bind DDF function: %s.\n",
00121                     str_error(rc));
00122                 // TODO: Can / should I destroy the DDF function?
00123                 ddf_fun_destroy(kbd_fun);
00124                 usb_kbd_free(&kbd_dev);
00125                 return rc;
00126         }
00127         
00128         rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
00129         if (rc != EOK) {
00130                 usb_log_error(
00131                     "Could not add DDF function to class 'keyboard': %s.\n",
00132                     str_error(rc));
00133                 ddf_fun_destroy(kbd_fun);
00134                 usb_kbd_free(&kbd_dev);
00135                 return rc;
00136         }
00137         
00138         /* Start automated polling function.
00139          * This will create a separate fibril that will query the device
00140          * for the data continuously 
00141          */
00142        rc = usb_device_auto_poll(dev,
00143            /* Index of the polling pipe. */
00144            USB_KBD_POLL_EP_NO,
00145            /* Callback when data arrives. */
00146            usb_kbd_polling_callback,
00147            /* How much data to request. */
00148            dev->pipes[USB_KBD_POLL_EP_NO].pipe->max_packet_size,
00149            /* Callback when the polling ends. */
00150            usb_kbd_polling_ended_callback,
00151            /* Custom argument. */
00152            kbd_dev);
00153         
00154         
00155         if (rc != EOK) {
00156                 usb_log_error("Failed to start polling fibril for `%s'.\n",
00157                     dev->ddf_dev->name);
00158                 return rc;
00159         }
00160         
00161         /*
00162          * Create new fibril for auto-repeat
00163          */
00164         fid_t fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);
00165         if (fid == 0) {
00166                 usb_log_error("Failed to start fibril for KBD auto-repeat");
00167                 return ENOMEM;
00168         }
00169         fibril_add_ready(fid);
00170 
00171         (void)keyboard_ops;
00172 
00173         /*
00174          * Hurrah, device is initialized.
00175          */
00176         return EOK;
00177 }
00178 
00179 /*----------------------------------------------------------------------------*/
00190 static int usb_kbd_add_device(usb_device_t *dev)
00191 {
00192         usb_log_debug("usb_kbd_add_device()\n");
00193         
00194         if (dev->interface_no < 0) {
00195                 usb_log_warning("Device is not a supported keyboard.\n");
00196                 usb_log_error("Failed to add USB KBD device: endpoint not "
00197                     "found.\n");
00198                 return ENOTSUP;
00199         }
00200         
00201         int rc = usb_kbd_try_add_device(dev);
00202         
00203         if (rc != EOK) {
00204                 usb_log_warning("Device is not a supported keyboard.\n");
00205                 usb_log_error("Failed to add KBD device: %s.\n",
00206                     str_error(rc));
00207                 return rc;
00208         }
00209         
00210         usb_log_info("Keyboard `%s' ready to use.\n", dev->ddf_dev->name);
00211 
00212         return EOK;
00213 }
00214 
00215 /*----------------------------------------------------------------------------*/
00216 
00217 /* Currently, the framework supports only device adding. Once the framework
00218  * supports unplug, more callbacks will be added. */
00219 static usb_driver_ops_t usb_kbd_driver_ops = {
00220         .add_device = usb_kbd_add_device,
00221 };
00222 
00223 
00224 /* The driver itself. */
00225 static usb_driver_t usb_kbd_driver = {
00226         .name = NAME,
00227         .ops = &usb_kbd_driver_ops,
00228         .endpoints = usb_kbd_endpoints
00229 };
00230 
00231 /*----------------------------------------------------------------------------*/
00232 
00233 int main(int argc, char *argv[])
00234 {
00235         printf(NAME ": HelenOS USB KBD driver.\n");
00236 
00237         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
00238 
00239         return usb_driver_main(&usb_kbd_driver);
00240 }
00241 

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