00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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;
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
00113
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
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
00139
00140
00141
00142 rc = usb_device_auto_poll(dev,
00143
00144 USB_KBD_POLL_EP_NO,
00145
00146 usb_kbd_polling_callback,
00147
00148 dev->pipes[USB_KBD_POLL_EP_NO].pipe->max_packet_size,
00149
00150 usb_kbd_polling_ended_callback,
00151
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
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
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
00218
00219 static usb_driver_ops_t usb_kbd_driver_ops = {
00220 .add_device = usb_kbd_add_device,
00221 };
00222
00223
00224
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