From owner-svn-soc-all@FreeBSD.ORG Thu Jul 18 16:54:20 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 4539598E for ; Thu, 18 Jul 2013 16:54:20 +0000 (UTC) (envelope-from bguan@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) by mx1.freebsd.org (Postfix) with ESMTP id 27B71B2A for ; Thu, 18 Jul 2013 16:54:20 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6IGsJJ8025899 for ; Thu, 18 Jul 2013 16:54:19 GMT (envelope-from bguan@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r6IGsJpd025896 for svn-soc-all@FreeBSD.org; Thu, 18 Jul 2013 16:54:19 GMT (envelope-from bguan@FreeBSD.org) Date: Thu, 18 Jul 2013 16:54:19 GMT Message-Id: <201307181654.r6IGsJpd025896@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to bguan@FreeBSD.org using -f From: bguan@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r254919 - soc2013/bguan/head/sys/dev/xen/usbfront MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Jul 2013 16:54:20 -0000 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 +//__FBSDID("$FreeBSD: release/9.1.0/sys/dev/xen/usbfront/usbfront.c 237873 2013-07-01 05:13:50Z ken $"); +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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_ */