2 * PCI Frontend Operations - Communicates with frontend
4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
6 #include <linux/module.h>
7 #include <linux/version.h>
8 #include <linux/init.h>
10 #include <linux/spinlock.h>
11 #include <linux/time.h>
12 #include <xen/evtchn.h>
15 static int verbose_request = 0;
16 module_param(verbose_request, int, 0644);
18 static int errno_to_pcibios_err(int errno)
21 case XEN_PCI_ERR_success:
22 return PCIBIOS_SUCCESSFUL;
24 case XEN_PCI_ERR_dev_not_found:
25 return PCIBIOS_DEVICE_NOT_FOUND;
27 case XEN_PCI_ERR_invalid_offset:
28 case XEN_PCI_ERR_op_failed:
29 return PCIBIOS_BAD_REGISTER_NUMBER;
31 case XEN_PCI_ERR_not_implemented:
32 return PCIBIOS_FUNC_NOT_SUPPORTED;
34 case XEN_PCI_ERR_access_denied:
35 return PCIBIOS_SET_FAILED;
40 static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
43 struct xen_pci_op *active_op = &pdev->sh_info->op;
44 unsigned long irq_flags;
45 evtchn_port_t port = pdev->evtchn;
49 spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
51 memcpy(active_op, op, sizeof(struct xen_pci_op));
55 set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
56 notify_remote_via_evtchn(port);
59 * We set a poll timeout of 3 seconds but give up on return after
60 * 2 seconds. It is better to time out too late rather than too early
61 * (in the latter case we end up continually re-executing poll() with a
62 * timeout in the past). 1s difference gives plenty of slack for error.
65 ns_timeout = timeval_to_ns(&tv) + 2 * NSEC_PER_SEC;
69 while (test_bit(_XEN_PCIF_active,
70 (unsigned long *)&pdev->sh_info->flags)) {
71 if (HYPERVISOR_poll(&port, 1, jiffies + 3*HZ))
75 ns = timeval_to_ns(&tv);
76 if (ns > ns_timeout) {
77 dev_err(&pdev->xdev->dev,
78 "pciback not responding!!!\n");
79 clear_bit(_XEN_PCIF_active,
80 (unsigned long *)&pdev->sh_info->flags);
81 err = XEN_PCI_ERR_dev_not_found;
86 memcpy(op, active_op, sizeof(struct xen_pci_op));
90 spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags);
94 /* Access to this function is spinlocked in drivers/pci/access.c */
95 static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn,
96 int where, int size, u32 * val)
99 struct xen_pci_op op = {
100 .cmd = XEN_PCI_OP_conf_read,
101 .domain = pci_domain_nr(bus),
107 struct pcifront_sd *sd = bus->sysdata;
108 struct pcifront_device *pdev = pcifront_get_pdev(sd);
111 dev_info(&pdev->xdev->dev,
112 "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n",
113 pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
114 PCI_FUNC(devfn), where, size);
116 err = do_pci_op(pdev, &op);
120 dev_info(&pdev->xdev->dev, "read got back value %x\n",
124 } else if (err == -ENODEV) {
125 /* No device here, pretend that it just returned 0 */
130 return errno_to_pcibios_err(err);
133 /* Access to this function is spinlocked in drivers/pci/access.c */
134 static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
135 int where, int size, u32 val)
137 struct xen_pci_op op = {
138 .cmd = XEN_PCI_OP_conf_write,
139 .domain = pci_domain_nr(bus),
146 struct pcifront_sd *sd = bus->sysdata;
147 struct pcifront_device *pdev = pcifront_get_pdev(sd);
150 dev_info(&pdev->xdev->dev,
151 "write dev=%04x:%02x:%02x.%01x - "
152 "offset %x size %d val %x\n",
153 pci_domain_nr(bus), bus->number,
154 PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
156 return errno_to_pcibios_err(do_pci_op(pdev, &op));
159 struct pci_ops pcifront_bus_ops = {
160 .read = pcifront_bus_read,
161 .write = pcifront_bus_write,
164 /* Claim resources for the PCI frontend as-is, backend won't allow changes */
165 static void pcifront_claim_resource(struct pci_dev *dev, void *data)
167 struct pcifront_device *pdev = data;
171 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
172 r = &dev->resource[i];
174 if (!r->parent && r->start && r->flags) {
175 dev_dbg(&pdev->xdev->dev, "claiming resource %s/%d\n",
177 pci_claim_resource(dev, i);
182 int pcifront_scan_root(struct pcifront_device *pdev,
183 unsigned int domain, unsigned int bus)
186 struct pcifront_sd *sd = NULL;
187 struct pci_bus_entry *bus_entry = NULL;
190 #ifndef CONFIG_PCI_DOMAINS
192 dev_err(&pdev->xdev->dev,
193 "PCI Root in non-zero PCI Domain! domain=%d\n", domain);
194 dev_err(&pdev->xdev->dev,
195 "Please compile with CONFIG_PCI_DOMAINS\n");
201 dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
204 bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
205 sd = kmalloc(sizeof(*sd), GFP_KERNEL);
206 if (!bus_entry || !sd) {
210 pcifront_init_sd(sd, domain, pdev);
212 b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
213 &pcifront_bus_ops, sd);
215 dev_err(&pdev->xdev->dev,
216 "Error creating PCI Frontend Bus!\n");
222 list_add(&bus_entry->list, &pdev->root_buses);
224 /* Claim resources before going "live" with our devices */
225 pci_walk_bus(b, pcifront_claim_resource, pdev);
227 pci_bus_add_devices(b);
238 static void free_root_bus_devs(struct pci_bus *bus)
242 spin_lock(&pci_bus_lock);
243 while (!list_empty(&bus->devices)) {
244 dev = container_of(bus->devices.next, struct pci_dev, bus_list);
245 spin_unlock(&pci_bus_lock);
247 dev_dbg(&dev->dev, "removing device\n");
248 pci_remove_bus_device(dev);
250 spin_lock(&pci_bus_lock);
252 spin_unlock(&pci_bus_lock);
255 void pcifront_free_roots(struct pcifront_device *pdev)
257 struct pci_bus_entry *bus_entry, *t;
259 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
261 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
262 list_del(&bus_entry->list);
264 free_root_bus_devs(bus_entry->bus);
266 kfree(bus_entry->bus->sysdata);
268 device_unregister(bus_entry->bus->bridge);
269 pci_remove_bus(bus_entry->bus);