socsvn commit: r254919 - soc2013/bguan/head/sys/dev/xen/usbfront
bguan at FreeBSD.org
bguan at FreeBSD.org
Thu Jul 18 16:54:20 UTC 2013
Author: bguan
Date: Thu Jul 18 16:54:19 2013
New Revision: 254919
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254919
Log:
update the xen usbfront
Added:
soc2013/bguan/head/sys/dev/xen/usbfront/
soc2013/bguan/head/sys/dev/xen/usbfront/usbfront.c
soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.h
Added: soc2013/bguan/head/sys/dev/xen/usbfront/usbfront.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2013/bguan/head/sys/dev/xen/usbfront/usbfront.c Thu Jul 18 16:54:19 2013 (r254919)
@@ -0,0 +1,343 @@
+/*
+ * A simple template of PV front driver for XenBSD device
+ *
+ * Copyright (c) 2013 Bei Guan
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+//__FBSDID("$FreeBSD: release/9.1.0/sys/dev/xen/usbfront/usbfront.c 237873 2013-07-01 05:13:50Z ken $");
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+#include <sys/condvar.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+#include <machine/intr_machdep.h>
+#include <machine/vmparam.h>
+#include <sys/bus_dma.h>
+
+#include <machine/_inttypes.h>
+#include <machine/xen/xen-os.h>
+#include <machine/xen/xenvar.h>
+#include <machine/xen/xenfunc.h>
+
+#include <xen/hypervisor.h>
+#include <xen/xen_intr.h>
+#include <xen/evtchn.h>
+#include <xen/gnttab.h>
+#include <xen/interface/grant_table.h>
+#include <xen/interface/io/protocols.h>
+#include <xen/interface/io/usbif.h>
+#include <xen/xenbus/xenbusvar.h>
+
+#include <geom/geom_disk.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/usb_pci.h>
+
+#include <dev/xen/usbfront/xenhci.h>
+#include <dev/usb/usb_device.h>
+
+#include "xenbus_if.h"
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) \
+ printf("[XEN] %s: " fmt, __func__, ##args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+static int usbfront_detach(device_t dev);
+
+/**
+ * Entry point to this code when a new device is created. Allocate the basic
+ * structures and the ring buffers for communication with the backend, and
+ * inform the backend of the appropriate details for those. Switch to
+ * Connected state.
+ */
+static int
+usbfront_probe(device_t dev)
+{
+
+ printf("[gbdebug-pvusb]probe:xenbus_get_type: %s\n", xenbus_get_type(dev));
+ if (!strcmp(xenbus_get_type(dev), "vusb")) {
+ device_set_desc(dev, "Virtual PV USB Device");
+ //device_quiet(dev);
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
+/*
+ * Setup supplies the backend dir, virtual device. We place an event
+ * channel and shared frame entries. We watch backend to wait if it's
+ * ok.
+ * TODO
+ */
+static int
+usbfront_attach(device_t dev)
+{
+ struct xenhci_softc *sc;
+ int err;
+ int rid;
+
+ int i;
+ int num_ports;
+ int usb_version;
+ const char *backend_path;
+
+ printf("[gbdebug-pvusb]usbfront_attach\n");
+
+ sc = device_get_softc(dev);
+
+ /* initialise some bus fields */
+ sc->sc_bus.parent = dev;
+
+ /* set up the bus struct */
+ sc->sc_bus.methods = &xenhci_bus_methods;
+
+ /* setup devices array */
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = XENHCI_MAX_DEVICES;
+
+ /* set the bus revision, read the revision from xenstore */
+ backend_path = xenbus_get_otherend_path(dev);
+ err = xs_scanf(XST_NIL, backend_path, "usb-ver", NULL, "%d", &usb_version);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "reading usb-ver");
+ return (err);
+ }
+ printf("[gbdebug-pvusb]usbfront_attach:usb_version=%d\n", usb_version);
+
+ switch (usb_version) {
+ case USB_VER_USB11:
+ sc->sc_bus.usbrev = USB_REV_1_1;
+ break;
+ case USB_VER_USB20:
+ sc->sc_bus.usbrev = USB_REV_2_0;
+ break;
+ default:
+ sc->sc_bus.usbrev = USB_REV_UNKNOWN;
+ xenbus_dev_fatal(dev, err, "invalid usb version");
+ return (err);
+ }
+
+ /* allocate resource for usb host controller (copy from xhci_pci.c) */
+ pci_enable_busmaster(dev);
+
+ rid = PCI_CBMEM;
+ sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (!sc->sc_io_res) {
+ device_printf(dev, "Could not map memory\n");
+ goto error;
+ }
+ sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+ sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+ sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+ usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0);
+
+ rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (sc->sc_irq_res == NULL) {
+ device_printf(dev, "Could not allocate IRQ\n");
+ }
+
+ sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+ if (sc->sc_bus.bdev == NULL) {
+ device_printf(dev, "Could not add USB device\n");
+ goto error;
+ }
+ device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+
+ /* xen related stuff*/
+ err = xs_scanf(XST_NIL, backend_path, "num-ports", NULL, "%d", &num_ports);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "reading num-ports");
+ goto error;
+ }
+ printf("[gbdebug-pvusb]create_hcdev_1:num_ports=%d\n", num_ports);
+
+ if (num_ports < 1 || num_ports > USB_MAXCHILDREN) {
+ xenbus_dev_fatal(dev, err, "invalid num-ports");
+ goto error;
+ }
+
+ sc->xb_dev = dev;
+ sc->rh_numports = num_ports;
+
+ for (i = 0; i < USB_URB_RING_SIZE; i++) {
+ sc->shadow[i].req.id = i + 1;
+ sc->shadow[i].urb = NULL;
+ }
+ sc->shadow[USB_URB_RING_SIZE-1].req.id = 0x0fff;
+
+
+ /* attach the xen host controller */
+ err = device_probe_and_attach(sc->sc_bus.bdev);
+ if (err) {
+ device_printf(dev, "XENHCI halt/start/probe failed err=%d\n", err);
+ goto error;
+ }
+ return (0);
+
+error:
+ usbfront_detach(dev);
+ return (ENXIO);
+}
+
+static int
+usbfront_suspend(device_t dev)
+{
+ printf("[gbdebug-pvusb]usbfront_suspend\n");
+
+ return (0);
+}
+
+static int
+usbfront_resume(device_t dev)
+{
+ printf("[gbdebug-pvusb]usbfront_resume\n");
+
+ //struct xenhci_softc *sc = device_get_softc(dev);
+
+ DPRINTK("usbfront_resume: %s\n", xenbus_get_node(dev));
+
+ //TODO
+ //usbfront_free(sc);
+ //usbfront_initialize(sc);
+
+ return (0);
+}
+
+static int
+usbfront_detach(device_t dev)
+{
+ printf("[gbdebug-pvusb]usbfront_detach\n");
+
+ //struct xenhci_softc *sc = device_get_softc(dev);
+
+ DPRINTK("usbfront_remove: %s removed\n", xenbus_get_node(dev));
+
+ //TODO
+ //usbfront_free(sc);
+ //mtx_destroy(&sc->xb_io_lock);
+
+ return 0;
+}
+
+/**
+ * Callback received when the backend's state changes.
+ */
+static void
+usbfront_backend_changed(device_t dev, XenbusState backend_state)
+{
+ printf("[gbdebug-pvusb]usbfront_backend_changed: backend_state=%d\n", backend_state);
+
+ //struct xenhci_softc *sc = device_get_softc(dev);
+
+ //DPRINTK("backend_state=%d\n", backend_state);
+
+ switch (backend_state) {
+ case XenbusStateUnknown:
+ case XenbusStateInitialising:
+ case XenbusStateReconfigured:
+ case XenbusStateReconfiguring:
+ case XenbusStateClosed:
+ break;
+
+ case XenbusStateInitWait:
+ case XenbusStateInitialised:
+ //TODO
+ //usbfront_initialize(sc);
+ printf("[gbdebug-pvusb]usbfront_backend_changed: initialize(sc)\n");
+ break;
+
+ case XenbusStateConnected:
+ //TODO
+ //usbfront_initialize(sc);
+ //usbfront_connect(sc);
+ printf("[gbdebug-pvusb]usbfront_backend_changed: initialize(sc);connect(sc)\n");
+ break;
+
+ case XenbusStateClosing:
+ //if (sc->users > 0) {
+ // xenbus_dev_error(dev, -EBUSY, "Device in use; refusing to close");
+ //} else {
+ //TODO
+ //usbfront_closing(dev);
+ printf("[gbdebug-pvusb]usbfront_backend_changed: closing(dev)\n");
+ //}
+ break;
+ }
+}
+
+
+/* ** Driver registration ** */
+static device_method_t usbfront_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, usbfront_probe),
+ DEVMETHOD(device_attach, usbfront_attach),
+ DEVMETHOD(device_detach, usbfront_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, usbfront_suspend),
+ DEVMETHOD(device_resume, usbfront_resume),
+
+ /* Xenbus interface */
+ DEVMETHOD(xenbus_otherend_changed, usbfront_backend_changed),
+
+ { 0, 0 }
+};
+
+static driver_t usbfront_driver = {
+ "xu",
+ usbfront_methods,
+ sizeof(struct xenhci_softc),
+};
+
+devclass_t usbfront_devclass;
+
+DRIVER_MODULE(xusb, xenbusb_front, usbfront_driver, usbfront_devclass, 0, 0);
Added: soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.h Thu Jul 18 16:54:19 2013 (r254919)
@@ -0,0 +1,161 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2013 Bei Guan. All rights reserved.
+ * Xen Host Controller Interface
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _USBFRONT_H_
+#define _USBFRONT_H_
+
+#define XENHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128)
+#define PCI_CBMEM 0x10
+
+/* USB ports. This is arbitrary.
+ * From USB 2.0 spec Table 11-13, offset 7, a hub can
+ * have up to 255 ports. The most yet reported is 10.
+ * FIXME ??
+ */
+#define USB_MAXCHILDREN 31
+
+#define USB_URB_RING_SIZE __RING_SIZE((usbif_urb_sring_t *)0, PAGE_SIZE)
+
+
+//FIXME:?
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+/* ring request shadow */
+struct usb_shadow {
+ usbif_urb_request_t req;
+ struct urb *urb;
+};
+
+/* virtual roothub port status */
+struct rhport_status {
+ unsigned int status;
+ unsigned resuming:1; /* in resuming */
+ unsigned c_connection:1; /* connection changed */
+ unsigned long timeout;
+};
+
+/* status of attached device */
+struct vdevice_status {
+ int devnum;
+ enum usb_dev_state status;
+ enum usb_dev_speed speed;
+};
+
+/////////////////////////////////////////////////
+// Moved to xenhci.h
+/////////////////////////////////////////////////
+struct xenhci_softc {
+ /* base device */
+ struct usb_bus sc_bus;
+ /* configure message */
+ struct usb_bus_msg sc_config_msg[2];
+
+ struct usb_callout sc_callout;
+
+ struct usb_device *sc_devices[XENHCI_MAX_DEVICES];
+ struct resource *sc_io_res;
+ struct resource *sc_irq_res;
+
+ void *sc_intr_hdl;
+ bus_size_t sc_io_size;
+ bus_space_tag_t sc_io_tag;
+ bus_space_handle_t sc_io_hdl;
+
+ /* Virtual Host Controller has 4 urb queues */
+ struct list_head pending_submit_list; //??
+ struct list_head pending_unlink_list; //??
+ struct list_head in_progress_list; //??
+ struct list_head giveback_waiting_list; //??
+
+ //spinlock_t lock;
+
+ /* timer that kick pending and giveback waiting urbs */
+ //struct timer_list watchdog;//??
+ unsigned long actions;
+
+ /* virtual root hub */
+ int rh_numports;
+ struct rhport_status ports[USB_MAXCHILDREN];
+ struct vdevice_status devices[USB_MAXCHILDREN];
+
+
+ /* Xen related staff */
+ /* shared ring */
+ device_t xb_dev;
+ int urb_ring_ref;
+ int conn_ring_ref;
+ usbif_urb_front_ring_t urb_ring;
+ usbif_conn_front_ring_t conn_ring;
+
+ /* event channel */
+ unsigned int irq;
+ struct usb_shadow shadow[USB_URB_RING_SIZE];
+ unsigned long shadow_free;
+
+ /* ring response thread */
+ struct task *ringthread;//struct task_struct *kthread;
+ struct list_head *wait_list; //wait_queue_head_t wq;????????
+ unsigned int waiting_resp;//
+};
+
+/*
+ * all bus methods are defined here
+*/
+
+
+
+extern struct usb_bus_methods xenhci_bus_methods;
+
+struct usb_bus_methods xenhci_bus_methods = {
+ .endpoint_init = NULL, //xhci_ep_init,
+ .endpoint_uninit = NULL, //xhci_ep_uninit,
+ .xfer_setup = NULL, //xhci_xfer_setup,
+ .xfer_unsetup = NULL, //xhci_xfer_unsetup,
+ .get_dma_delay = NULL, //xhci_get_dma_delay,
+ .device_init = NULL, //xhci_device_init,
+ .device_uninit = NULL, //xhci_device_uninit,
+ .device_resume = NULL, //xhci_device_resume,
+ .device_suspend = NULL, //xhci_device_suspend,
+ .set_hw_power = NULL, //xhci_set_hw_power,
+ .roothub_exec = NULL, //xhci_roothub_exec,
+ .xfer_poll = NULL, //xhci_do_poll,
+ .start_dma_delay = NULL, //xhci_start_dma_delay,
+ .set_address = NULL, //xhci_set_address,
+ .clear_stall = NULL, //xhci_ep_clear_stall,
+ .device_state_change = NULL, //xhci_device_state_change,
+ .set_hw_power_sleep = NULL, //xhci_set_hw_power_sleep,
+ .set_endpoint_mode = NULL, //xhci_set_endpoint_mode,
+};
+
+
+/* prototypes */
+//usb_error_t xenhci_init(struct xenhci_softc *, device_t);
+
+#endif /* _USBFRONT_H_ */
More information about the svn-soc-all
mailing list