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