2 * Copyright (c) 2006, Cisco Systems, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Cisco Systems, Inc. nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/module.h>
36 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h>
40 #include <sys/socket.h>
41 #include <sys/queue.h>
43 #include <machine/vmparam.h>
47 #include <machine/bus.h>
48 #include <machine/resource.h>
49 #include <machine/frame.h>
54 #include <machine/intr_machdep.h>
56 #include <machine/xen-os.h>
57 #include <machine/hypervisor.h>
58 #include <machine/hypervisor-ifs.h>
59 #include <machine/xen_intr.h>
60 #include <machine/evtchn.h>
61 #include <machine/xenbus.h>
62 #include <machine/gnttab.h>
63 #include <machine/xen-public/memory.h>
64 #include <machine/xen-public/io/pciif.h>
66 #include <sys/pciio.h>
67 #include <dev/pci/pcivar.h>
70 #ifdef XEN_PCIDEV_FE_DEBUG
71 #define DPRINTF(fmt, args...) \
72 printf("pcifront (%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
74 #define DPRINTF(fmt, args...) ((void)0)
76 #define WPRINTF(fmt, args...) \
77 printf("pcifront (%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
79 #define INVALID_GRANT_REF (0)
80 #define INVALID_EVTCHN (-1)
81 #define virt_to_mfn(x) (vtomach(x) >> PAGE_SHIFT)
83 struct pcifront_device {
84 STAILQ_ENTRY(pcifront_device) next;
86 struct xenbus_device *xdev;
92 /* Lock this when doing any operations in sh_info */
93 struct mtx sh_info_lock;
94 struct xen_pci_sharedinfo *sh_info;
101 static STAILQ_HEAD(pcifront_dlist, pcifront_device) pdev_list = STAILQ_HEAD_INITIALIZER(pdev_list);
106 struct pcifront_device *pdev;
109 /* Allocate a PCI device structure */
110 static struct pcifront_device *
111 alloc_pdev(struct xenbus_device *xdev)
113 struct pcifront_device *pdev = NULL;
116 err = sscanf(xdev->nodename, "device/pci/%d", &unit);
120 xenbus_dev_fatal(pdev->xdev, err, "Error scanning pci device instance number");
124 pdev = (struct pcifront_device *)malloc(sizeof(struct pcifront_device), M_DEVBUF, M_NOWAIT);
127 xenbus_dev_fatal(xdev, err, "Error allocating pcifront_device struct");
134 pdev->sh_info = (struct xen_pci_sharedinfo *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
135 if (pdev->sh_info == NULL) {
136 free(pdev, M_DEVBUF);
139 xenbus_dev_fatal(xdev, err, "Error allocating sh_info struct");
142 pdev->sh_info->flags = 0;
146 mtx_init(&pdev->sh_info_lock, "info_lock", "pci shared dev info lock", MTX_DEF);
148 pdev->evtchn = INVALID_EVTCHN;
149 pdev->gnt_ref = INVALID_GRANT_REF;
151 STAILQ_INSERT_TAIL(&pdev_list, pdev, next);
153 DPRINTF("Allocated pdev @ 0x%p (unit=%d)\n", pdev, unit);
159 /* Hold a reference to a pcifront device */
161 get_pdev(struct pcifront_device *pdev)
166 /* Release a reference to a pcifront device */
168 put_pdev(struct pcifront_device *pdev)
170 if (--pdev->ref_cnt > 0)
173 DPRINTF("freeing pdev @ 0x%p (ref_cnt=%d)\n", pdev, pdev->ref_cnt);
175 if (pdev->evtchn != INVALID_EVTCHN)
176 xenbus_free_evtchn(pdev->xdev, pdev->evtchn);
178 if (pdev->gnt_ref != INVALID_GRANT_REF)
179 gnttab_end_foreign_access(pdev->gnt_ref, 0, (void *)pdev->sh_info);
181 pdev->xdev->data = NULL;
183 free(pdev, M_DEVBUF);
187 /* Write to the xenbus info needed by backend */
189 pcifront_publish_info(struct pcifront_device *pdev)
192 struct xenbus_transaction *trans;
194 err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info));
196 WPRINTF("error granting access to ring page\n");
202 err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn);
207 trans = xenbus_transaction_start();
209 xenbus_dev_fatal(pdev->xdev, err,
210 "Error writing configuration for backend "
211 "(start transaction)");
215 err = xenbus_printf(trans, pdev->xdev->nodename,
216 "pci-op-ref", "%u", pdev->gnt_ref);
218 err = xenbus_printf(trans, pdev->xdev->nodename,
219 "event-channel", "%u", pdev->evtchn);
221 err = xenbus_printf(trans, pdev->xdev->nodename,
222 "magic", XEN_PCI_MAGIC);
224 err = xenbus_switch_state(pdev->xdev, trans,
225 XenbusStateInitialised);
228 xenbus_transaction_end(trans, 1);
229 xenbus_dev_fatal(pdev->xdev, err,
230 "Error writing configuration for backend");
233 err = xenbus_transaction_end(trans, 0);
237 xenbus_dev_fatal(pdev->xdev, err,
238 "Error completing transaction for backend");
247 /* The backend is now connected so complete the connection process on our side */
249 pcifront_connect(struct pcifront_device *pdev)
252 devclass_t nexus_devclass;
254 /* We will add our device as a child of the nexus0 device */
255 if (!(nexus_devclass = devclass_find("nexus")) ||
256 !(nexus = devclass_get_device(nexus_devclass, 0))) {
257 WPRINTF("could not find nexus0!\n");
261 /* Create a newbus device representing this frontend instance */
262 pdev->ndev = BUS_ADD_CHILD(nexus, 0, "xpcife", pdev->unit);
264 WPRINTF("could not create xpcife%d!\n", pdev->unit);
268 device_set_ivars(pdev->ndev, pdev);
270 /* Good to go connected now */
271 xenbus_switch_state(pdev->xdev, NULL, XenbusStateConnected);
273 printf("pcifront: connected to %s\n", pdev->xdev->nodename);
276 device_probe_and_attach(pdev->ndev);
282 /* The backend is closing so process a disconnect */
284 pcifront_disconnect(struct pcifront_device *pdev)
287 XenbusState prev_state;
289 prev_state = xenbus_read_driver_state(pdev->xdev->nodename);
291 if (prev_state < XenbusStateClosing) {
292 err = xenbus_switch_state(pdev->xdev, NULL, XenbusStateClosing);
293 if (!err && prev_state == XenbusStateConnected) {
294 /* TODO - need to detach the newbus devices */
301 /* Process a probe from the xenbus */
303 pcifront_probe(struct xenbus_device *xdev,
304 const struct xenbus_device_id *id)
307 struct pcifront_device *pdev;
309 DPRINTF("xenbus probing\n");
311 if ((pdev = alloc_pdev(xdev)) == NULL)
314 err = pcifront_publish_info(pdev);
322 /* Remove the xenbus PCI device */
324 pcifront_remove(struct xenbus_device *xdev)
326 DPRINTF("removing xenbus device node (%s)\n", xdev->nodename);
328 put_pdev(xdev->data);
332 /* Called by xenbus when our backend node changes state */
334 pcifront_backend_changed(struct xenbus_device *xdev,
335 XenbusState be_state)
337 struct pcifront_device *pdev = xdev->data;
340 case XenbusStateClosing:
341 DPRINTF("backend closing (%s)\n", xdev->nodename);
342 pcifront_disconnect(pdev);
345 case XenbusStateClosed:
346 DPRINTF("backend closed (%s)\n", xdev->nodename);
347 pcifront_disconnect(pdev);
350 case XenbusStateConnected:
351 DPRINTF("backend connected (%s)\n", xdev->nodename);
352 pcifront_connect(pdev);
360 /* Process PCI operation */
362 do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
365 struct xen_pci_op *active_op = &pdev->sh_info->op;
366 evtchn_port_t port = pdev->evtchn;
369 mtx_lock(&pdev->sh_info_lock);
371 memcpy(active_op, op, sizeof(struct xen_pci_op));
375 set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
376 notify_remote_via_evtchn(port);
378 timeout = time_uptime + 2;
382 /* Spin while waiting for the answer */
384 (_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags)) {
385 int err = HYPERVISOR_poll(&port, 1, 3 * hz);
387 panic("Failed HYPERVISOR_poll: err=%d", err);
389 if (time_uptime > timeout) {
390 WPRINTF("pciback not responding!!!\n");
391 clear_bit(_XEN_PCIF_active,
392 (unsigned long *)&pdev->sh_info->flags);
393 err = XEN_PCI_ERR_dev_not_found;
398 memcpy(op, active_op, sizeof(struct xen_pci_op));
402 mtx_unlock(&pdev->sh_info_lock);
406 /* ** XenBus Driver registration ** */
408 static struct xenbus_device_id pcifront_ids[] = {
413 static struct xenbus_driver pcifront = {
416 .probe = pcifront_probe,
417 .remove = pcifront_remove,
418 .otherend_changed = pcifront_backend_changed,
421 /* Register the driver with xenbus during sys init */
423 pcifront_init(void *unused)
425 if ((xen_start_info->flags & SIF_INITDOMAIN))
428 DPRINTF("xenbus registering\n");
430 xenbus_register_frontend(&pcifront);
433 SYSINIT(pciif, SI_SUB_PSEUDO, SI_ORDER_ANY, pcifront_init, NULL)
436 /* Newbus xpcife device driver probe */
438 xpcife_probe(device_t dev)
440 #ifdef XEN_PCIDEV_FE_DEBUG
441 struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(dev);
442 DPRINTF("xpcife probe (unit=%d)\n", pdev->unit);
447 /* Newbus xpcife device driver attach */
449 xpcife_attach(device_t dev)
451 struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(dev);
452 int i, num_roots, len, err;
454 unsigned int domain, bus;
456 DPRINTF("xpcife attach (unit=%d)\n", pdev->unit);
458 err = xenbus_scanf(NULL, pdev->xdev->otherend,
459 "root_num", "%d", &num_roots);
463 xenbus_dev_fatal(pdev->xdev, err,
464 "Error reading number of PCI roots");
468 /* Add a pcib device for each root */
469 for (i = 0; i < num_roots; i++) {
472 len = snprintf(str, sizeof(str), "root-%d", i);
473 if (unlikely(len >= (sizeof(str) - 1))) {
478 err = xenbus_scanf(NULL, pdev->xdev->otherend, str,
479 "%x:%x", &domain, &bus);
483 xenbus_dev_fatal(pdev->xdev, err,
484 "Error reading PCI root %d", i);
488 if (domain != pdev->xdev->otherend_id) {
490 xenbus_dev_fatal(pdev->xdev, err,
491 "Domain mismatch %d != %d", domain, pdev->xdev->otherend_id);
495 child = device_add_child(dev, "pcib", bus);
498 xenbus_dev_fatal(pdev->xdev, err,
499 "Unable to create pcib%d", bus);
505 return bus_generic_attach(dev);
508 static devclass_t xpcife_devclass;
510 static device_method_t xpcife_methods[] = {
511 /* Device interface */
512 DEVMETHOD(device_probe, xpcife_probe),
513 DEVMETHOD(device_attach, xpcife_attach),
514 DEVMETHOD(device_detach, bus_generic_detach),
515 DEVMETHOD(device_shutdown, bus_generic_shutdown),
516 DEVMETHOD(device_suspend, bus_generic_suspend),
517 DEVMETHOD(device_resume, bus_generic_resume),
519 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
520 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
521 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
522 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
523 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
524 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
529 static driver_t xpcife_driver = {
535 DRIVER_MODULE(xpcife, nexus, xpcife_driver, xpcife_devclass, 0, 0);
538 /* Newbus xen pcib device driver probe */
540 xpcib_probe(device_t dev)
542 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev);
543 struct pcifront_device *pdev = (struct pcifront_device *)device_get_ivars(device_get_parent(dev));
545 DPRINTF("xpcib probe (bus=%d)\n", device_get_unit(dev));
547 sc->domain = pdev->xdev->otherend_id;
548 sc->bus = device_get_unit(dev);
554 /* Newbus xen pcib device driver attach */
556 xpcib_attach(device_t dev)
558 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev);
560 DPRINTF("xpcib attach (bus=%d)\n", sc->bus);
562 device_add_child(dev, "pci", sc->bus);
563 return bus_generic_attach(dev);
567 xpcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
569 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev);
578 /* Return the number of slots supported */
580 xpcib_maxslots(device_t dev)
585 #define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
587 /* Read configuration space register */
589 xpcib_read_config(device_t dev, int bus, int slot, int func,
592 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev);
593 struct xen_pci_op op = {
594 .cmd = XEN_PCI_OP_conf_read,
595 .domain = sc->domain,
597 .devfn = PCI_DEVFN(slot, func),
603 err = do_pci_op(sc->pdev, &op);
605 DPRINTF("read config (b=%d, s=%d, f=%d, reg=%d, len=%d, val=%x, err=%d)\n",
606 bus, slot, func, reg, bytes, op.value, err);
614 /* Write configuration space register */
616 xpcib_write_config(device_t dev, int bus, int slot, int func,
617 int reg, u_int32_t data, int bytes)
619 struct xpcib_softc *sc = (struct xpcib_softc *)device_get_softc(dev);
620 struct xen_pci_op op = {
621 .cmd = XEN_PCI_OP_conf_write,
622 .domain = sc->domain,
624 .devfn = PCI_DEVFN(slot, func),
631 err = do_pci_op(sc->pdev, &op);
633 DPRINTF("write config (b=%d, s=%d, f=%d, reg=%d, len=%d, val=%x, err=%d)\n",
634 bus, slot, func, reg, bytes, data, err);
638 xpcib_route_interrupt(device_t pcib, device_t dev, int pin)
640 struct pci_devinfo *dinfo = device_get_ivars(dev);
641 pcicfgregs *cfg = &dinfo->cfg;
643 DPRINTF("route intr (pin=%d, line=%d)\n", pin, cfg->intline);
648 static device_method_t xpcib_methods[] = {
649 /* Device interface */
650 DEVMETHOD(device_probe, xpcib_probe),
651 DEVMETHOD(device_attach, xpcib_attach),
652 DEVMETHOD(device_detach, bus_generic_detach),
653 DEVMETHOD(device_shutdown, bus_generic_shutdown),
654 DEVMETHOD(device_suspend, bus_generic_suspend),
655 DEVMETHOD(device_resume, bus_generic_resume),
658 DEVMETHOD(bus_read_ivar, xpcib_read_ivar),
659 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
660 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
661 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
662 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
663 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
664 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
667 DEVMETHOD(pcib_maxslots, xpcib_maxslots),
668 DEVMETHOD(pcib_read_config, xpcib_read_config),
669 DEVMETHOD(pcib_write_config, xpcib_write_config),
670 DEVMETHOD(pcib_route_interrupt, xpcib_route_interrupt),
675 static devclass_t xpcib_devclass;
677 DEFINE_CLASS_0(pcib, xpcib_driver, xpcib_methods, sizeof(struct xpcib_softc));
678 DRIVER_MODULE(pcib, xpcife, xpcib_driver, xpcib_devclass, 0, 0);
686 * indent-tabs-mode: t