Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Xen PCI Frontend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <xen/xenbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <xen/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <xen/grant_table.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <xen/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/msi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <xen/interface/io/pciif.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <asm/xen/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/swiotlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <xen/platform_pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <asm/xen/swiotlb-xen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define INVALID_GRANT_REF (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define INVALID_EVTCHN    (-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) struct pci_bus_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define _PDEVB_op_active		(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define PDEVB_op_active			(1 << (_PDEVB_op_active))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) struct pcifront_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	struct xenbus_device *xdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	struct list_head root_buses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	int evtchn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	int gnt_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	/* Lock this when doing any operations in sh_info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	spinlock_t sh_info_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	struct xen_pci_sharedinfo *sh_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	struct work_struct op_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) struct pcifront_sd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	struct pci_sysdata sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct pcifront_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) static inline struct pcifront_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) pcifront_get_pdev(struct pcifront_sd *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	return sd->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) static inline void pcifront_init_sd(struct pcifront_sd *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 				    unsigned int domain, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 				    struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	/* Because we do not expose that information via XenBus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	sd->sd.node = first_online_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	sd->sd.domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	sd->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) static DEFINE_SPINLOCK(pcifront_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) static struct pcifront_device *pcifront_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) static int errno_to_pcibios_err(int errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	switch (errno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	case XEN_PCI_ERR_success:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 		return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	case XEN_PCI_ERR_dev_not_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		return PCIBIOS_DEVICE_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	case XEN_PCI_ERR_invalid_offset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	case XEN_PCI_ERR_op_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		return PCIBIOS_BAD_REGISTER_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	case XEN_PCI_ERR_not_implemented:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		return PCIBIOS_FUNC_NOT_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	case XEN_PCI_ERR_access_denied:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		return PCIBIOS_SET_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	return errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) static inline void schedule_pcifront_aer_op(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	if (test_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		&& !test_and_set_bit(_PDEVB_op_active, &pdev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		dev_dbg(&pdev->xdev->dev, "schedule aer frontend job\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		schedule_work(&pdev->op_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	struct xen_pci_op *active_op = &pdev->sh_info->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	unsigned long irq_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	evtchn_port_t port = pdev->evtchn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	unsigned irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	s64 ns, ns_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	memcpy(active_op, op, sizeof(struct xen_pci_op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	/* Go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	notify_remote_via_evtchn(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	 * We set a poll timeout of 3 seconds but give up on return after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	 * 2 seconds. It is better to time out too late rather than too early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	 * (in the latter case we end up continually re-executing poll() with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	 * timeout in the past). 1s difference gives plenty of slack for error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	ns_timeout = ktime_get_ns() + 2 * (s64)NSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	xen_clear_irq_pending(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	while (test_bit(_XEN_PCIF_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			(unsigned long *)&pdev->sh_info->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		xen_poll_irq_timeout(irq, jiffies + 3*HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		xen_clear_irq_pending(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		ns = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		if (ns > ns_timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 				"pciback not responding!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 			clear_bit(_XEN_PCIF_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 				  (unsigned long *)&pdev->sh_info->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 			err = XEN_PCI_ERR_dev_not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	* We might lose backend service request since we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	* reuse same evtchn with pci_conf backend response. So re-schedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	* aer pcifront service.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	if (test_bit(_XEN_PCIB_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			(unsigned long *)&pdev->sh_info->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 			"schedule aer pcifront service\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		schedule_pcifront_aer_op(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	memcpy(op, active_op, sizeof(struct xen_pci_op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	err = op->err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) /* Access to this function is spinlocked in drivers/pci/access.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			     int where, int size, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	struct xen_pci_op op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		.cmd    = XEN_PCI_OP_conf_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		.domain = pci_domain_nr(bus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		.bus    = bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		.devfn  = devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		.offset = where,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		.size   = size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	struct pcifront_sd *sd = bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	struct pcifront_device *pdev = pcifront_get_pdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	dev_dbg(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		"read dev=%04x:%02x:%02x.%d - offset %x size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		PCI_FUNC(devfn), where, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	err = do_pci_op(pdev, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	if (likely(!err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		dev_dbg(&pdev->xdev->dev, "read got back value %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 			op.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		*val = op.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	} else if (err == -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		/* No device here, pretend that it just returned 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		*val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	return errno_to_pcibios_err(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) /* Access to this function is spinlocked in drivers/pci/access.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 			      int where, int size, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	struct xen_pci_op op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		.cmd    = XEN_PCI_OP_conf_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		.domain = pci_domain_nr(bus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		.bus    = bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		.devfn  = devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		.offset = where,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		.size   = size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		.value  = val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	struct pcifront_sd *sd = bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	struct pcifront_device *pdev = pcifront_get_pdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	dev_dbg(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		"write dev=%04x:%02x:%02x.%d - offset %x size %d val %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		pci_domain_nr(bus), bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	return errno_to_pcibios_err(do_pci_op(pdev, &op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) static struct pci_ops pcifront_bus_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	.read = pcifront_bus_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	.write = pcifront_bus_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) #ifdef CONFIG_PCI_MSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) static int pci_frontend_enable_msix(struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 				    int vector[], int nvec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	struct xen_pci_op op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		.cmd    = XEN_PCI_OP_enable_msix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		.domain = pci_domain_nr(dev->bus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		.bus = dev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		.devfn = dev->devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		.value = nvec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	struct pcifront_sd *sd = dev->bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	struct pcifront_device *pdev = pcifront_get_pdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	struct msi_desc *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	if (nvec > SH_INFO_MAX_VEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		pci_err(dev, "too many vectors (0x%x) for PCI frontend:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 				   " Increase SH_INFO_MAX_VEC\n", nvec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	for_each_pci_msi_entry(entry, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		op.msix_entries[i].entry = entry->msi_attrib.entry_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		/* Vector is useless at this point. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		op.msix_entries[i].vector = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	err = do_pci_op(pdev, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (likely(!err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		if (likely(!op.value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			/* we get the result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			for (i = 0; i < nvec; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 				if (op.msix_entries[i].vector <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 					pci_warn(dev, "MSI-X entry %d is invalid: %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 						i, op.msix_entries[i].vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 					err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 					vector[i] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 				vector[i] = op.msix_entries[i].vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 			pr_info("enable msix get value %x\n", op.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 			err = op.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		pci_err(dev, "enable msix get err %x\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) static void pci_frontend_disable_msix(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	struct xen_pci_op op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		.cmd    = XEN_PCI_OP_disable_msix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		.domain = pci_domain_nr(dev->bus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		.bus = dev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		.devfn = dev->devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	struct pcifront_sd *sd = dev->bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	struct pcifront_device *pdev = pcifront_get_pdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	err = do_pci_op(pdev, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	/* What should do for error ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		pci_err(dev, "pci_disable_msix get err %x\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) static int pci_frontend_enable_msi(struct pci_dev *dev, int vector[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	struct xen_pci_op op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		.cmd    = XEN_PCI_OP_enable_msi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		.domain = pci_domain_nr(dev->bus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		.bus = dev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		.devfn = dev->devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	struct pcifront_sd *sd = dev->bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	struct pcifront_device *pdev = pcifront_get_pdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	err = do_pci_op(pdev, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	if (likely(!err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		vector[0] = op.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		if (op.value <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 			pci_warn(dev, "MSI entry is invalid: %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 				op.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 			vector[0] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		pci_err(dev, "pci frontend enable msi failed for dev "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 				    "%x:%x\n", op.bus, op.devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) static void pci_frontend_disable_msi(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	struct xen_pci_op op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		.cmd    = XEN_PCI_OP_disable_msi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		.domain = pci_domain_nr(dev->bus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		.bus = dev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		.devfn = dev->devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	struct pcifront_sd *sd = dev->bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	struct pcifront_device *pdev = pcifront_get_pdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	err = do_pci_op(pdev, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	if (err == XEN_PCI_ERR_dev_not_found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		/* XXX No response from backend, what shall we do? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		pr_info("get no response from backend for disable MSI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		/* how can pciback notify us fail? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		pr_info("get fake response from backend\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) static struct xen_pci_frontend_ops pci_frontend_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	.enable_msi = pci_frontend_enable_msi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	.disable_msi = pci_frontend_disable_msi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	.enable_msix = pci_frontend_enable_msix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	.disable_msix = pci_frontend_disable_msix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) static void pci_frontend_registrar(int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		xen_pci_frontend = &pci_frontend_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		xen_pci_frontend = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) static inline void pci_frontend_registrar(int enable) { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) #endif /* CONFIG_PCI_MSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) /* Claim resources for the PCI frontend as-is, backend won't allow changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) static int pcifront_claim_resource(struct pci_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	struct pcifront_device *pdev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	struct resource *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		r = &dev->resource[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		if (!r->parent && r->start && r->flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 			dev_info(&pdev->xdev->dev, "claiming resource %s/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 				pci_name(dev), i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			if (pci_claim_resource(dev, i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 				dev_err(&pdev->xdev->dev, "Could not claim resource %s/%d! "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 					"Device offline. Try using e820_host=1 in the guest config.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 					pci_name(dev), i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) static int pcifront_scan_bus(struct pcifront_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 				unsigned int domain, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 				struct pci_bus *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	struct pci_dev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	unsigned int devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	/* Scan the bus for functions and add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	 * We omit handling of PCI bridge attachment because pciback prevents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	 * bridges from being exported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	for (devfn = 0; devfn < 0x100; devfn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		d = pci_get_slot(b, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		if (d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 			/* Device is already known. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			pci_dev_put(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		d = pci_scan_single_device(b, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		if (d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			dev_info(&pdev->xdev->dev, "New device on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 				 "%04x:%02x:%02x.%d found.\n", domain, bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 				 PCI_SLOT(devfn), PCI_FUNC(devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) static int pcifront_scan_root(struct pcifront_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 				 unsigned int domain, unsigned int bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	struct pci_bus *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	LIST_HEAD(resources);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	struct pcifront_sd *sd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	struct pci_bus_entry *bus_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	static struct resource busn_res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		.start = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		.end = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		.flags = IORESOURCE_BUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) #ifndef CONFIG_PCI_DOMAINS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (domain != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			"PCI Root in non-zero PCI Domain! domain=%d\n", domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			"Please compile with CONFIG_PCI_DOMAINS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		 domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	if (!bus_entry || !sd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	pci_add_resource(&resources, &ioport_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	pci_add_resource(&resources, &iomem_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	pci_add_resource(&resources, &busn_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	pcifront_init_sd(sd, domain, bus, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	b = pci_scan_root_bus(&pdev->xdev->dev, bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 				  &pcifront_bus_ops, sd, &resources);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	if (!b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			"Error creating PCI Frontend Bus!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		pci_free_resource_list(&resources);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	bus_entry->bus = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	list_add(&bus_entry->list, &pdev->root_buses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	/* pci_scan_root_bus skips devices which do not have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	* devfn==0. The pcifront_scan_bus enumerates all devfn. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	err = pcifront_scan_bus(pdev, domain, bus, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	/* Claim resources before going "live" with our devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	pci_walk_bus(b, pcifront_claim_resource, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	/* Create SysFS and notify udev of the devices. Aka: "going live" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	pci_bus_add_devices(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	kfree(bus_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	kfree(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) static int pcifront_rescan_root(struct pcifront_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 				   unsigned int domain, unsigned int bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	struct pci_bus *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) #ifndef CONFIG_PCI_DOMAINS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	if (domain != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 			"PCI Root in non-zero PCI Domain! domain=%d\n", domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 			"Please compile with CONFIG_PCI_DOMAINS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	dev_info(&pdev->xdev->dev, "Rescanning PCI Frontend Bus %04x:%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		 domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	b = pci_find_bus(domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		/* If the bus is unknown, create it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		return pcifront_scan_root(pdev, domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	err = pcifront_scan_bus(pdev, domain, bus, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	/* Claim resources before going "live" with our devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	pci_walk_bus(b, pcifront_claim_resource, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	/* Create SysFS and notify udev of the devices. Aka: "going live" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	pci_bus_add_devices(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) static void free_root_bus_devs(struct pci_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	struct pci_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	while (!list_empty(&bus->devices)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		dev = container_of(bus->devices.next, struct pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 				   bus_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		pci_dbg(dev, "removing device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		pci_stop_and_remove_bus_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) static void pcifront_free_roots(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	struct pci_bus_entry *bus_entry, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		list_del(&bus_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		free_root_bus_devs(bus_entry->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		kfree(bus_entry->bus->sysdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		device_unregister(bus_entry->bus->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		pci_remove_bus(bus_entry->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		kfree(bus_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) static pci_ers_result_t pcifront_common_process(int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 						struct pcifront_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 						pci_channel_state_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	pci_ers_result_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	struct pci_driver *pdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	int bus = pdev->sh_info->aer_op.bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	int devfn = pdev->sh_info->aer_op.devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	int domain = pdev->sh_info->aer_op.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	struct pci_dev *pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	int flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	dev_dbg(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		"pcifront AER process: cmd %x (bus:%x, devfn%x)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		cmd, bus, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	result = PCI_ERS_RESULT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	if (!pcidev || !pcidev->driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		pci_dev_put(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	pdrv = pcidev->driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	if (pdrv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		if (pdrv->err_handler && pdrv->err_handler->error_detected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			pci_dbg(pcidev, "trying to call AER service\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 			if (pcidev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 				flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 				switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 				case XEN_PCI_OP_aer_detected:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 					result = pdrv->err_handler->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 						 error_detected(pcidev, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 				case XEN_PCI_OP_aer_mmio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 					result = pdrv->err_handler->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 						 mmio_enabled(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 				case XEN_PCI_OP_aer_slotreset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 					result = pdrv->err_handler->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 						 slot_reset(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 				case XEN_PCI_OP_aer_resume:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 					pdrv->err_handler->resume(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 					dev_err(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 						"bad request in aer recovery "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 						"operation!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		result = PCI_ERS_RESULT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) static void pcifront_do_aer(struct work_struct *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	struct pcifront_device *pdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		container_of(data, struct pcifront_device, op_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	int cmd = pdev->sh_info->aer_op.cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	pci_channel_state_t state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		(pci_channel_state_t)pdev->sh_info->aer_op.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	/*If a pci_conf op is in progress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		we have to wait until it is done before service aer op*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	dev_dbg(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		"pcifront service aer bus %x devfn %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		pdev->sh_info->aer_op.bus, pdev->sh_info->aer_op.devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	pdev->sh_info->aer_op.err = pcifront_common_process(cmd, pdev, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	/* Post the operation to the guest. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	clear_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	notify_remote_via_evtchn(pdev->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	/*in case of we lost an aer request in four lines time_window*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	clear_bit(_PDEVB_op_active, &pdev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	smp_mb__after_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	schedule_pcifront_aer_op(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) static irqreturn_t pcifront_handler_aer(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	struct pcifront_device *pdev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	schedule_pcifront_aer_op(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) static int pcifront_connect_and_init_dma(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	spin_lock(&pcifront_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	if (!pcifront_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		dev_info(&pdev->xdev->dev, "Installing PCI frontend\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		pcifront_dev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		err = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	spin_unlock(&pcifront_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	if (!err && !swiotlb_nr_tbl()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		err = pci_xen_swiotlb_init_late();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) static void pcifront_disconnect(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	spin_lock(&pcifront_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	if (pdev == pcifront_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		dev_info(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			 "Disconnecting PCI Frontend Buses\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		pcifront_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	spin_unlock(&pcifront_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static struct pcifront_device *alloc_pdev(struct xenbus_device *xdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	struct pcifront_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	pdev = kzalloc(sizeof(struct pcifront_device), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	pdev->sh_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	    (struct xen_pci_sharedinfo *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (pdev->sh_info == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		kfree(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	pdev->sh_info->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	/*Flag for registering PV AER handler*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	set_bit(_XEN_PCIB_AERHANDLER, (void *)&pdev->sh_info->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	dev_set_drvdata(&xdev->dev, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	pdev->xdev = xdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	INIT_LIST_HEAD(&pdev->root_buses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	spin_lock_init(&pdev->sh_info_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	pdev->evtchn = INVALID_EVTCHN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	pdev->gnt_ref = INVALID_GRANT_REF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	pdev->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	INIT_WORK(&pdev->op_work, pcifront_do_aer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	dev_dbg(&xdev->dev, "Allocated pdev @ 0x%p pdev->sh_info @ 0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		pdev, pdev->sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	return pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) static void free_pdev(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	pcifront_free_roots(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	cancel_work_sync(&pdev->op_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	if (pdev->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		unbind_from_irqhandler(pdev->irq, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	if (pdev->evtchn != INVALID_EVTCHN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		xenbus_free_evtchn(pdev->xdev, pdev->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	if (pdev->gnt_ref != INVALID_GRANT_REF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		gnttab_end_foreign_access(pdev->gnt_ref, 0 /* r/w page */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 					  (unsigned long)pdev->sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		free_page((unsigned long)pdev->sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	dev_set_drvdata(&pdev->xdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	kfree(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) static int pcifront_publish_info(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	struct xenbus_transaction trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	grant_ref_t gref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	err = xenbus_grant_ring(pdev->xdev, pdev->sh_info, 1, &gref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	pdev->gnt_ref = gref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	err = bind_evtchn_to_irqhandler(pdev->evtchn, pcifront_handler_aer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		0, "pcifront", pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	pdev->irq = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) do_publish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	err = xenbus_transaction_start(&trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 				 "Error writing configuration for backend "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 				 "(start transaction)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	err = xenbus_printf(trans, pdev->xdev->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			    "pci-op-ref", "%u", pdev->gnt_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		err = xenbus_printf(trans, pdev->xdev->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 				    "event-channel", "%u", pdev->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		err = xenbus_printf(trans, pdev->xdev->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 				    "magic", XEN_PCI_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		xenbus_transaction_end(trans, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 				 "Error writing configuration for backend");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		err = xenbus_transaction_end(trans, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		if (err == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			goto do_publish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		else if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 					 "Error completing transaction "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 					 "for backend");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	dev_dbg(&pdev->xdev->dev, "publishing successful!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) static int pcifront_try_connect(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	int err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	int i, num_roots, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	char str[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	unsigned int domain, bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	/* Only connect once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	if (xenbus_read_driver_state(pdev->xdev->nodename) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	    XenbusStateInitialised)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	err = pcifront_connect_and_init_dma(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (err && err != -EEXIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 				 "Error setting up PCI Frontend");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			   "root_num", "%d", &num_roots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	if (err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		xenbus_dev_error(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 				 "No PCI Roots found, trying 0000:00");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		err = pcifront_scan_root(pdev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 					 "Error scanning PCI root 0000:00");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		num_roots = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	} else if (err != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 				 "Error reading number of PCI roots");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	for (i = 0; i < num_roots; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		len = snprintf(str, sizeof(str), "root-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		if (unlikely(len >= (sizeof(str) - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 				   "%x:%x", &domain, &bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		if (err != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 					 "Error reading PCI root %d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		err = pcifront_scan_root(pdev, domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 					 "Error scanning PCI root %04x:%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 					 domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) static int pcifront_try_disconnect(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	enum xenbus_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	prev_state = xenbus_read_driver_state(pdev->xdev->nodename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	if (prev_state >= XenbusStateClosing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	if (prev_state == XenbusStateConnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		pcifront_free_roots(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		pcifront_disconnect(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	err = xenbus_switch_state(pdev->xdev, XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) static int pcifront_attach_devices(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	int err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	int i, num_roots, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	unsigned int domain, bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	char str[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	if (xenbus_read_driver_state(pdev->xdev->nodename) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	    XenbusStateReconfiguring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 			   "root_num", "%d", &num_roots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	if (err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		xenbus_dev_error(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 				 "No PCI Roots found, trying 0000:00");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		err = pcifront_rescan_root(pdev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 					 "Error scanning PCI root 0000:00");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		num_roots = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	} else if (err != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 				 "Error reading number of PCI roots");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	for (i = 0; i < num_roots; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		len = snprintf(str, sizeof(str), "root-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		if (unlikely(len >= (sizeof(str) - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 				   "%x:%x", &domain, &bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		if (err != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 			if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 					 "Error reading PCI root %d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		err = pcifront_rescan_root(pdev, domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 					 "Error scanning PCI root %04x:%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 					 domain, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	xenbus_switch_state(pdev->xdev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static int pcifront_detach_devices(struct pcifront_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	int i, num_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	unsigned int domain, bus, slot, func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	struct pci_dev *pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	char str[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	if (xenbus_read_driver_state(pdev->xdev->nodename) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	    XenbusStateConnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "num_devs", "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			   &num_devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (err != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 				 "Error reading number of PCI devices");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	/* Find devices being detached and remove them. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	for (i = 0; i < num_devs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		int l, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		l = snprintf(str, sizeof(str), "state-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		if (unlikely(l >= (sizeof(str) - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		state = xenbus_read_unsigned(pdev->xdev->otherend, str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 					     XenbusStateUnknown);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		if (state != XenbusStateClosing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		/* Remove device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		l = snprintf(str, sizeof(str), "vdev-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		if (unlikely(l >= (sizeof(str) - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 				   "%x:%x:%x.%x", &domain, &bus, &slot, &func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		if (err != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			xenbus_dev_fatal(pdev->xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 					 "Error reading PCI device %d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		pci_dev = pci_get_domain_bus_and_slot(domain, bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 				PCI_DEVFN(slot, func));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		if (!pci_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			dev_dbg(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 				"Cannot get PCI device %04x:%02x:%02x.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 				domain, bus, slot, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		pci_stop_and_remove_bus_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		pci_dev_put(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		dev_dbg(&pdev->xdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			"PCI device %04x:%02x:%02x.%d removed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			domain, bus, slot, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	err = xenbus_switch_state(pdev->xdev, XenbusStateReconfiguring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) static void __ref pcifront_backend_changed(struct xenbus_device *xdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 						  enum xenbus_state be_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	switch (be_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	case XenbusStateUnknown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	case XenbusStateInitialising:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	case XenbusStateInitWait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	case XenbusStateInitialised:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	case XenbusStateConnected:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		pcifront_try_connect(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	case XenbusStateClosed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		if (xdev->state == XenbusStateClosed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		fallthrough;	/* Missed the backend's CLOSING state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	case XenbusStateClosing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		dev_warn(&xdev->dev, "backend going away!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		pcifront_try_disconnect(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	case XenbusStateReconfiguring:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		pcifront_detach_devices(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	case XenbusStateReconfigured:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		pcifront_attach_devices(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static int pcifront_xenbus_probe(struct xenbus_device *xdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 				 const struct xenbus_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	struct pcifront_device *pdev = alloc_pdev(xdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	if (pdev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		xenbus_dev_fatal(xdev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 				 "Error allocating pcifront_device struct");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	err = pcifront_publish_info(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		free_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int pcifront_xenbus_remove(struct xenbus_device *xdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	if (pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		free_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static const struct xenbus_device_id xenpci_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	{"pci"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	{""},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static struct xenbus_driver xenpci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	.name			= "pcifront",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	.ids			= xenpci_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	.probe			= pcifront_xenbus_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	.remove			= pcifront_xenbus_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	.otherend_changed	= pcifront_backend_changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static int __init pcifront_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	if (!xen_pv_domain() || xen_initial_domain())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	if (!xen_has_pv_devices())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	pci_frontend_registrar(1 /* enable */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	return xenbus_register_frontend(&xenpci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static void __exit pcifront_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	xenbus_unregister_driver(&xenpci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	pci_frontend_registrar(0 /* disable */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) module_init(pcifront_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) module_exit(pcifront_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) MODULE_DESCRIPTION("Xen PCI passthrough frontend.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) MODULE_ALIAS("xen:pci");