svn commit: r186767 - user/dfr/xenhvm/6/sys/dev/xen/xenpci

Doug Rabson dfr at FreeBSD.org
Mon Jan 5 02:43:49 PST 2009


Author: dfr
Date: Mon Jan  5 10:43:48 2009
New Revision: 186767
URL: http://svn.freebsd.org/changeset/base/186767

Log:
  Tidy this up a lot and improve the comments somewhat.

Modified:
  user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpci.c
  user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpcivar.h

Modified: user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpci.c
==============================================================================
--- user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpci.c	Mon Jan  5 10:41:54 2009	(r186766)
+++ user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpci.c	Mon Jan  5 10:43:48 2009	(r186767)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) [year] [your name]
+ * Copyright (c) 2008 Citrix Systems, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,101 +68,12 @@ shared_info_t *HYPERVISOR_shared_info;
 static vm_paddr_t shared_info_pa;
 
 /*
- * The softc is automatically allocated by the parent bus using the
- * size specified in the driver_t declaration below.
+ * This is used to find our platform device instance.
  */
-#define DEVICE2SOFTC(dev) ((struct xenpci_softc *) device_get_softc(dev))
-
-/* Function prototypes (these should all be static). */
-static int xenpci_deallocate_resources(device_t device);
-static int xenpci_allocate_resources(device_t device);
-static int xenpci_attach(device_t device, struct xenpci_softc *scp);
-static int xenpci_detach(device_t device, struct xenpci_softc *scp);
-
-static int xenpci_alloc_space_int(struct xenpci_softc *scp, size_t sz,
-    u_long *pa);
-
 static devclass_t xenpci_devclass;
 
-static int	xenpci_pci_probe(device_t);
-static int	xenpci_pci_attach(device_t);
-static int	xenpci_pci_detach(device_t);
-static int	xenpci_pci_resume(device_t);
-
-static device_method_t xenpci_pci_methods[] = {
-	/* Device interface */
-	DEVMETHOD(device_probe,		xenpci_pci_probe),
-	DEVMETHOD(device_attach,	xenpci_pci_attach),
-	DEVMETHOD(device_detach,	xenpci_pci_detach),
-	DEVMETHOD(device_resume,	xenpci_pci_resume),
-
-	/* Bus interface */
-	DEVMETHOD(bus_add_child,	bus_generic_add_child),
-
-	{ 0, 0 }
-};
-
-static driver_t xenpci_pci_driver = {
-	"xenpci",
-	xenpci_pci_methods,
-	sizeof(struct xenpci_softc),
-};
-
-DRIVER_MODULE(xenpci, pci, xenpci_pci_driver, xenpci_devclass, 0, 0);
-
-static struct _pcsid
-{
-	u_int32_t	type;
-	const char	*desc;
-} pci_ids[] = {
-	{ 0x00015853,	"Xen Platform Device"			},
-	{ 0x00000000,	NULL					}
-};
-
-static int
-xenpci_pci_probe (device_t device)
-{
-	u_int32_t	type = pci_get_devid(device);
-	struct _pcsid	*ep = pci_ids;
-
-	while (ep->type && ep->type != type)
-		++ep;
-	if (ep->desc) {
-		device_set_desc(device, ep->desc);
-		return (bus_generic_probe(device));
-	} else
-		return (ENXIO);
-}
-
-static int
-xenpci_pci_attach(device_t device)
-{
-        int	error;
-	struct xenpci_softc *scp = DEVICE2SOFTC(device);
-
-        error = xenpci_attach(device, scp);
-        if (error)
-                xenpci_pci_detach(device);
-        return (error);
-}
-
-static int
-xenpci_pci_detach (device_t device)
-{
-	struct xenpci_softc *scp = DEVICE2SOFTC(device);
-
-        return (xenpci_detach(device, scp));
-}
-
-static int
-xenpci_pci_resume(device_t device)
-{
-
-	return (bus_generic_resume(device));
-}
-
 /*
- * Common Attachment sub-functions
+ * Return the CPUID base address for Xen functions.
  */
 static uint32_t
 xenpci_cpuid_base(void)
@@ -178,21 +89,24 @@ xenpci_cpuid_base(void)
 	return (0);
 }
 
+/*
+ * Allocate and fill in the hypcall page.
+ */
 static int
-xenpci_init_hypercall_stubs(device_t device, struct xenpci_softc * scp)
+xenpci_init_hypercall_stubs(device_t dev, struct xenpci_softc * scp)
 {
 	uint32_t base, regs[4];
 	int i;
 
 	base = xenpci_cpuid_base();
 	if (!base) {
-		device_printf(device, "Xen platform device but not Xen VMM\n");
+		device_printf(dev, "Xen platform device but not Xen VMM\n");
 		return (EINVAL);
 	}
 
 	if (bootverbose) {
 		do_cpuid(base + 1, regs);
-		device_printf(device, "Xen version %d.%d.\n",
+		device_printf(dev, "Xen version %d.%d.\n",
 		    regs[0] >> 16, regs[0] & 0xffff);
 	}
 
@@ -210,8 +124,11 @@ xenpci_init_hypercall_stubs(device_t dev
 	return (0);
 }
 
+/*
+ * After a resume, re-initialise the hypercall page.
+ */
 static void
-xenpci_resume_hypercall_stubs(device_t device, struct xenpci_softc * scp)
+xenpci_resume_hypercall_stubs(device_t dev, struct xenpci_softc * scp)
 {
 	uint32_t base, regs[4];
 	int i;
@@ -224,19 +141,22 @@ xenpci_resume_hypercall_stubs(device_t d
 	}
 }
 
+/*
+ * Tell the hypervisor how to contact us for event channel callbacks.
+ */
 static void
-xenpci_set_callback(device_t device)
+xenpci_set_callback(device_t dev)
 {
 	int irq;
 	uint64_t callback;
 	struct xen_hvm_param xhp;
 
-	irq = pci_get_irq(device);
+	irq = pci_get_irq(dev);
 	if (irq < 16) {
 		callback = irq;
 	} else {
-		callback = (pci_get_intpin(device) - 1) & 3;
-		callback |= pci_get_slot(device) << 11;
+		callback = (pci_get_intpin(dev) - 1) & 3;
+		callback |= pci_get_slot(dev) << 11;
 		callback |= 1ull << 56;
 	}
 
@@ -247,135 +167,62 @@ xenpci_set_callback(device_t device)
 		panic("Can't set evtchn callback");
 }
 
-static int
-xenpci_attach(device_t device, struct xenpci_softc * scp)
-{
-	struct xen_add_to_physmap xatp;
-	vm_offset_t shared_va;
-
-	if (xenpci_allocate_resources(device))
-		goto errexit;
-
-	scp->phys_next = rman_get_start(scp->res_memory);
-
-	if (xenpci_init_hypercall_stubs(device, scp))
-		goto errexit;
-
-	setup_xen_features();
-
-	xenpci_alloc_space_int(scp, PAGE_SIZE, &shared_info_pa); 
-
-	xatp.domid = DOMID_SELF;
-	xatp.idx = 0;
-	xatp.space = XENMAPSPACE_shared_info;
-	xatp.gpfn = shared_info_pa >> PAGE_SHIFT;
-	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
-		panic("HYPERVISOR_memory_op failed");
-
-	shared_va = kmem_alloc_nofault(kernel_map, PAGE_SIZE);
-	pmap_kenter(shared_va, shared_info_pa);
-	HYPERVISOR_shared_info = (void *) shared_va;
-
-	/*
-	 * Hook the irq up to evtchn
-	 */
-	xenpci_irq_init(device, scp);
-	xenpci_set_callback(device);
-
-	return (bus_generic_attach(device));
-
-errexit:
-	/*
-	 * Undo anything we may have done.
-	 */
-	xenpci_detach(device, scp);
-	return (ENXIO);
-}
 
+/*
+ * Deallocate anything allocated by xenpci_allocate_resources.
+ */
 static int
-xenpci_detach(device_t device, struct xenpci_softc *scp)
+xenpci_deallocate_resources(device_t dev)
 {
-	device_t parent = device_get_parent(device);
+	struct xenpci_softc *scp = device_get_softc(dev);
 
-	/*
-	 * Take our interrupt handler out of the list of handlers
-	 * that can handle this irq.
-	 */
-	if (scp->intr_cookie != NULL) {
-		if (BUS_TEARDOWN_INTR(parent, device,
-			scp->res_irq, scp->intr_cookie) != 0)
-				printf("intr teardown failed.. continuing\n");
-		scp->intr_cookie = NULL;
+	if (scp->res_irq != 0) {
+		bus_deactivate_resource(dev, SYS_RES_IRQ,
+			scp->rid_irq, scp->res_irq);
+		bus_release_resource(dev, SYS_RES_IRQ,
+			scp->rid_irq, scp->res_irq);
+		scp->res_irq = 0;
+	}
+	if (scp->res_memory != 0) {
+		bus_deactivate_resource(dev, SYS_RES_MEMORY,
+			scp->rid_memory, scp->res_memory);
+		bus_release_resource(dev, SYS_RES_MEMORY,
+			scp->rid_memory, scp->res_memory);
+		scp->res_memory = 0;
 	}
 
-	/*
-	 * Deallocate any system resources we may have
-	 * allocated on behalf of this driver.
-	 */
-	return xenpci_deallocate_resources(device);
+	return (0);
 }
 
+/*
+ * Allocate irq and memory resources.
+ */
 static int
-xenpci_allocate_resources(device_t device)
+xenpci_allocate_resources(device_t dev)
 {
-	int error;
-	struct xenpci_softc *scp = DEVICE2SOFTC(device);
+	struct xenpci_softc *scp = device_get_softc(dev);
 
-	scp->res_irq = bus_alloc_resource_any(device, SYS_RES_IRQ,
+	scp->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
 			&scp->rid_irq, RF_SHAREABLE|RF_ACTIVE);
 	if (scp->res_irq == NULL)
 		goto errexit;
 
-	scp->rid_ioport = PCIR_BAR(0);
-	scp->res_ioport = bus_alloc_resource_any(device, SYS_RES_IOPORT,
-			&scp->rid_ioport, RF_ACTIVE);
-	if (scp->res_ioport == NULL)
-		goto errexit;
-
 	scp->rid_memory = PCIR_BAR(1);
-	scp->res_memory = bus_alloc_resource_any(device, SYS_RES_MEMORY,
+	scp->res_memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
 			&scp->rid_memory, RF_ACTIVE);
 	if (scp->res_memory == NULL)
 		goto errexit;
 	return (0);
 
 errexit:
-	error = ENXIO;
 	/* Cleanup anything we may have assigned. */
-	xenpci_deallocate_resources(device);
+	xenpci_deallocate_resources(dev);
 	return (ENXIO); /* For want of a better idea. */
 }
 
-static int
-xenpci_deallocate_resources(device_t device)
-{
-	struct xenpci_softc *scp = DEVICE2SOFTC(device);
-
-	if (scp->res_irq != 0) {
-		bus_deactivate_resource(device, SYS_RES_IRQ,
-			scp->rid_irq, scp->res_irq);
-		bus_release_resource(device, SYS_RES_IRQ,
-			scp->rid_irq, scp->res_irq);
-		scp->res_irq = 0;
-	}
-	if (scp->res_ioport != 0) {
-		bus_deactivate_resource(device, SYS_RES_IOPORT,
-			scp->rid_ioport, scp->res_ioport);
-		bus_release_resource(device, SYS_RES_IOPORT,
-			scp->rid_ioport, scp->res_ioport);
-		scp->res_ioport = 0;
-	}
-	if (scp->res_memory != 0) {
-		bus_deactivate_resource(device, SYS_RES_MEMORY,
-			scp->rid_memory, scp->res_memory);
-		bus_release_resource(device, SYS_RES_MEMORY,
-			scp->rid_memory, scp->res_memory);
-		scp->res_memory = 0;
-	}
-
-	return (0);
-}
-
+/*
+ * Allocate a physical address range from our mmio region.
+ */
 static int
 xenpci_alloc_space_int(struct xenpci_softc *scp, size_t sz,
     vm_paddr_t *pa)
@@ -391,27 +238,35 @@ xenpci_alloc_space_int(struct xenpci_sof
 	return (0);
 }
 
+/*
+ * Allocate a physical address range from our mmio region.
+ */
 int
 xenpci_alloc_space(size_t sz, vm_paddr_t *pa)
 {
-	device_t device = devclass_get_device(xenpci_devclass, 0);
+	device_t dev = devclass_get_device(xenpci_devclass, 0);
 
-	if (device) {
-		return (xenpci_alloc_space_int(DEVICE2SOFTC(device),
+	if (dev) {
+		return (xenpci_alloc_space_int(device_get_softc(dev),
 			sz, pa));
 	} else {
 		return (ENOMEM);
 	}
 }
 
+/*
+ * Called very early in the resume sequence - reinitialise the various
+ * bits of Xen machinery including the hypercall page and the shared
+ * info page.
+ */
 void
 xenpci_resume()
 {
-	device_t device = devclass_get_device(xenpci_devclass, 0);
-	struct xenpci_softc *scp = DEVICE2SOFTC(device);
+	device_t dev = devclass_get_device(xenpci_devclass, 0);
+	struct xenpci_softc *scp = device_get_softc(dev);
 	struct xen_add_to_physmap xatp;
 
-	xenpci_resume_hypercall_stubs(device, scp);
+	xenpci_resume_hypercall_stubs(dev, scp);
 
 	xatp.domid = DOMID_SELF;
 	xatp.idx = 0;
@@ -422,9 +277,123 @@ xenpci_resume()
 
 	pmap_kenter((vm_offset_t) HYPERVISOR_shared_info, shared_info_pa);
 
-	xenpci_set_callback(device);
+	xenpci_set_callback(dev);
 
 	gnttab_resume();
 	irq_resume();
 }
 
+/*
+ * Probe - just check device ID.
+ */
+static int
+xenpci_probe(device_t dev)
+{
+
+	if (pci_get_devid(dev) != 0x00015853)
+		return (ENXIO);
+
+	device_set_desc(dev, "Xen Platform Device");
+	return (bus_generic_probe(dev));
+}
+
+/*
+ * Attach - find resources and talk to Xen.
+ */
+static int
+xenpci_attach(device_t dev)
+{
+        int error;
+	struct xenpci_softc *scp = device_get_softc(dev);
+	struct xen_add_to_physmap xatp;
+	vm_offset_t shared_va;
+
+	error = xenpci_allocate_resources(dev);
+	if (error)
+		goto errexit;
+
+	scp->phys_next = rman_get_start(scp->res_memory);
+
+	error = xenpci_init_hypercall_stubs(dev, scp);
+	if (error)
+		goto errexit;
+
+	setup_xen_features();
+
+	xenpci_alloc_space_int(scp, PAGE_SIZE, &shared_info_pa); 
+
+	xatp.domid = DOMID_SELF;
+	xatp.idx = 0;
+	xatp.space = XENMAPSPACE_shared_info;
+	xatp.gpfn = shared_info_pa >> PAGE_SHIFT;
+	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+		panic("HYPERVISOR_memory_op failed");
+
+	shared_va = kmem_alloc_nofault(kernel_map, PAGE_SIZE);
+	pmap_kenter(shared_va, shared_info_pa);
+	HYPERVISOR_shared_info = (void *) shared_va;
+
+	/*
+	 * Hook the irq up to evtchn
+	 */
+	xenpci_irq_init(dev, scp);
+	xenpci_set_callback(dev);
+
+	return (bus_generic_attach(dev));
+
+errexit:
+	/*
+	 * Undo anything we may have done.
+	 */
+	xenpci_deallocate_resources(dev);
+        return (error);
+}
+
+/*
+ * Detach - reverse anything done by attach.
+ */
+static int
+xenpci_detach(device_t dev)
+{
+	struct xenpci_softc *scp = device_get_softc(dev);
+	device_t parent = device_get_parent(dev);
+
+	/*
+	 * Take our interrupt handler out of the list of handlers
+	 * that can handle this irq.
+	 */
+	if (scp->intr_cookie != NULL) {
+		if (BUS_TEARDOWN_INTR(parent, dev,
+			scp->res_irq, scp->intr_cookie) != 0)
+				printf("intr teardown failed.. continuing\n");
+		scp->intr_cookie = NULL;
+	}
+
+	/*
+	 * Deallocate any system resources we may have
+	 * allocated on behalf of this driver.
+	 */
+	return (xenpci_deallocate_resources(dev));
+}
+
+static device_method_t xenpci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		xenpci_probe),
+	DEVMETHOD(device_attach,	xenpci_attach),
+	DEVMETHOD(device_detach,	xenpci_detach),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_add_child,	bus_generic_add_child),
+
+	{ 0, 0 }
+};
+
+static driver_t xenpci_driver = {
+	"xenpci",
+	xenpci_methods,
+	sizeof(struct xenpci_softc),
+};
+
+DRIVER_MODULE(xenpci, pci, xenpci_driver, xenpci_devclass, 0, 0);

Modified: user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpcivar.h
==============================================================================
--- user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpcivar.h	Mon Jan  5 10:41:54 2009	(r186766)
+++ user/dfr/xenhvm/6/sys/dev/xen/xenpci/xenpcivar.h	Mon Jan  5 10:43:48 2009	(r186767)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) [year] [your name]
+ * Copyright (c) 2008 Citrix Systems, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,6 @@ struct xenpci_softc {
 	int rid_ioport;
 	int rid_memory;
 	int rid_irq;
-	struct resource* res_ioport;	/* Resource for port range. */
 	struct resource* res_memory;	/* Resource for mem range. */
 	struct resource* res_irq;	/* Resource for irq range. */
 	void	*intr_cookie;


More information about the svn-src-user mailing list