/* * Frame Buffer + Keyboard driver for Mini-OS. * Samuel Thibault , 2008 * Based on blkfront.c. */ #include #include #include #include #include #include #include #include #include #include DECLARE_WAIT_QUEUE_HEAD(kbdfront_queue); struct kbdfront_dev { domid_t dom; struct xenkbd_page *page; evtchn_port_t evtchn; char *nodename; char *backend; xenbus_event_queue events; #ifdef HAVE_LIBC int fd; #endif }; void kbdfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) { #ifdef HAVE_LIBC struct kbdfront_dev *dev = data; int fd = dev->fd; if (fd != -1) files[fd].read = 1; #endif wake_up(&kbdfront_queue); } static void free_kbdfront(struct kbdfront_dev *dev) { mask_evtchn(dev->evtchn); free(dev->backend); free_page(dev->page); unbind_evtchn(dev->evtchn); free(dev->nodename); free(dev); } struct kbdfront_dev *init_kbdfront(char *_nodename, int abs_pointer) { xenbus_transaction_t xbt; char* err; char* message=NULL; struct xenkbd_page *s; int retry=0; char* msg; char* nodename = _nodename ? _nodename : "device/vkbd/0"; struct kbdfront_dev *dev; char path[strlen(nodename) + 1 + 10 + 1]; printk("******************* KBDFRONT for %s **********\n\n\n", nodename); dev = malloc(sizeof(*dev)); dev->nodename = strdup(nodename); #ifdef HAVE_LIBC dev->fd = -1; #endif snprintf(path, sizeof(path), "%s/backend-id", nodename); dev->dom = xenbus_read_integer(path); evtchn_alloc_unbound(dev->dom, kbdfront_handler, dev, &dev->evtchn); dev->page = s = (struct xenkbd_page*) alloc_page(); memset(s,0,PAGE_SIZE); dev->events = NULL; s->in_cons = s->in_prod = 0; s->out_cons = s->out_prod = 0; again: err = xenbus_transaction_start(&xbt); if (err) { printk("starting transaction\n"); } err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s)); if (err) { message = "writing page-ref"; goto abort_transaction; } err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn); if (err) { message = "writing event-channel"; goto abort_transaction; } if (abs_pointer) { err = xenbus_printf(xbt, nodename, "request-abs-pointer", "1"); if (err) { message = "writing event-channel"; goto abort_transaction; } } snprintf(path, sizeof(path), "%s/state", nodename); err = xenbus_switch_state(xbt, path, XenbusStateInitialised); if (err) printk("error writing initialized: %s\n", err); err = xenbus_transaction_end(xbt, 0, &retry); if (retry) { goto again; printk("completing transaction\n"); } goto done; abort_transaction: xenbus_transaction_end(xbt, 1, &retry); goto error; done: snprintf(path, sizeof(path), "%s/backend", nodename); msg = xenbus_read(XBT_NIL, path, &dev->backend); if (msg) { printk("Error %s when reading the backend path %s\n", msg, path); goto error; } printk("backend at %s\n", dev->backend); { XenbusState state; char path[strlen(dev->backend) + 1 + 6 + 1]; char frontpath[strlen(nodename) + 1 + 6 + 1]; snprintf(path, sizeof(path), "%s/state", dev->backend); xenbus_watch_path_token(XBT_NIL, path, path, &dev->events); err = NULL; state = xenbus_read_integer(path); while (err == NULL && state < XenbusStateConnected) err = xenbus_wait_for_state_change(path, &state, &dev->events); if (state != XenbusStateConnected) { printk("backend not available, state=%d\n", state); xenbus_unwatch_path(XBT_NIL, path); goto error; } printk("%s connected\n", dev->backend); snprintf(frontpath, sizeof(frontpath), "%s/state", nodename); if((err = xenbus_switch_state(XBT_NIL, frontpath, XenbusStateConnected)) != NULL) { printk("error switching state: %s\n", err); xenbus_unwatch_path(XBT_NIL, path); goto error; } } unmask_evtchn(dev->evtchn); printk("************************** KBDFRONT\n"); return dev; error: free_kbdfront(dev); return NULL; } int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n) { struct xenkbd_page *page = dev->page; uint32_t prod, cons; int i; #ifdef HAVE_LIBC if (dev->fd != -1) { files[dev->fd].read = 0; mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ } #endif prod = page->in_prod; if (prod == page->in_cons) return 0; rmb(); /* ensure we see ring contents up to prod */ for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++) memcpy(buf + i, &XENKBD_IN_RING_REF(page, cons), sizeof(*buf)); mb(); /* ensure we got ring contents */ page->in_cons = cons; notify_remote_via_evtchn(dev->evtchn); #ifdef HAVE_LIBC if (cons != prod && dev->fd != -1) /* still some events to read */ files[dev->fd].read = 1; #endif return i; } void shutdown_kbdfront(struct kbdfront_dev *dev) { char* err = NULL; XenbusState state; char path[strlen(dev->backend) + 1 + 5 + 1]; char nodename[strlen(dev->nodename) + 1 + 5 + 1]; printk("close kbd: backend at %s\n",dev->backend); snprintf(path, sizeof(path), "%s/state", dev->backend); snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename); if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) { printk("shutdown_kbdfront: error changing state to %d: %s\n", XenbusStateClosing, err); goto close_kbdfront; } state = xenbus_read_integer(path); whil
#
# Copyright (C) 2006-2008 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

WIRELESS_MENU:=Wireless Drivers

define KernelPackage/net-prism54
  SUBMENU:=$(WIRELESS_MENU)
  TITLE:=Intersil Prism54 support
  DEPENDS:=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT +prism54-firmware
  KCONFIG:=CONFIG_PRISM54
  FILES:= \
	$(LINUX_DIR)/drivers/net/wireless/prism54/prism54.ko@lt4.5 \
	$(LINUX_DIR)/drivers/net/wireless/intersil/prism54/prism54.ko@ge4.5
  AUTOLOAD:=$(call AutoProbe,prism54)
endef

define KernelPackage/net-prism54/description
 Kernel modules for Intersil Prism54 support
endef

$(eval $(call KernelPackage,net-prism54))


define KernelPackage/net-rtl8192su
  SUBMENU:=$(WIRELESS_MENU)
  TITLE:=RTL8192SU support (staging)
  DEPENDS:=@USB_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-usb-core +rtl8192su-firmware
  KCONFIG:=\
	CONFIG_STAGING=y \
	CONFIG_R8712U
  FILES:=$(LINUX_DIR)/drivers/staging/rtl8712/r8712u.ko
  AUTOLOAD:=$(call AutoProbe,r8712u)
endef

define KernelPackage/net-rtl8192su/description
 Kernel modules for RealTek RTL8712 and RTL81XXSU fullmac support.
endef

$(eval $(call KernelPackage,net-rtl8192su))


define KernelPackage/owl-loader
  SUBMENU:=$(WIRELESS_MENU)
  TITLE:=Owl loader for initializing Atheros PCI(e) Wifi chips
  DEPENDS:=@PCI_SUPPORT
  KCONFIG:=CONFIG_OWL_LOADER
  FILES:=$(LINUX_DIR)/drivers/misc/owl-loader.ko
  AUTOLOAD:=$(call AutoProbe,owl-loader)
endef

define KernelPackage/owl-loader/description
  Kernel module that helps to initialize certain Qualcomm
  Atheros' PCI(e) Wifi chips, which have the init data
  (which contains the PCI device ID for example) stored
  together with the calibration data in the file system.

  This is necessary for devices like the Cisco Meraki Z1.
endef

$(eval $(call KernelPackage,owl-loader))
ch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) { printk("shutdown_fbfront: error changing state to %d: %s\n", XenbusStateClosing, err); goto close_fbfront; } state = xenbus_read_integer(path); while (err == NULL && state < XenbusStateClosing) err = xenbus_wait_for_state_change(path, &state, &dev->events); if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) { printk("shutdown_fbfront: error changing state to %d: %s\n", XenbusStateClosed, err); goto close_fbfront; } state = xenbus_read_integer(path); if (state < XenbusStateClosed) xenbus_wait_for_state_change(path, &state, &dev->events); if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) { printk("shutdown_fbfront: error changing state to %d: %s\n", XenbusStateInitialising, err); goto close_fbfront; } // does not work yet //xenbus_wait_for_value(path, "2", &dev->events); close_fbfront: xenbus_unwatch_path(XBT_NIL, path); snprintf(path, sizeof(path), "%s/page-ref", nodename); xenbus_rm(XBT_NIL, path); snprintf(path, sizeof(path), "%s/event-channel", nodename); xenbus_rm(XBT_NIL, path); snprintf(path, sizeof(path), "%s/protocol", nodename); xenbus_rm(XBT_NIL, path); snprintf(path, sizeof(path), "%s/feature-update", nodename); xenbus_rm(XBT_NIL, path); unbind_evtchn(dev->evtchn); free_fbfront(dev); } #ifdef HAVE_LIBC int fbfront_open(struct fbfront_dev *dev) { dev->fd = alloc_fd(FTYPE_FB); printk("fb_open(%s) -> %d\n", dev->nodename, dev->fd); files[dev->fd].fb.dev = dev; return dev->fd; } #endif