- patches.rt/0001-sched-count-of-queued-RT-tasks.patch: Delete.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / pcifront / pci_op.c
1 /*
2  * PCI Frontend Operations - Communicates with frontend
3  *
4  *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
5  */
6 #include <linux/module.h>
7 #include <linux/version.h>
8 #include <linux/init.h>
9 #include <linux/pci.h>
10 #include <linux/spinlock.h>
11 #include <linux/time.h>
12 #include <xen/evtchn.h>
13 #include "pcifront.h"
14
15 static int verbose_request = 0;
16 module_param(verbose_request, int, 0644);
17
18 #ifdef __ia64__
19 static void pcifront_init_sd(struct pcifront_sd *sd,
20                              unsigned int domain, unsigned int bus,
21                              struct pcifront_device *pdev)
22 {
23         int err, i, j, k, len, root_num, res_count;
24         struct acpi_resource res;
25         unsigned int d, b, byte;
26         unsigned long magic;
27         char str[64], tmp[3];
28         unsigned char *buf, *bufp;
29         u8 *ptr;
30
31         memset(sd, 0, sizeof(*sd));
32
33         sd->segment = domain;
34         sd->node = -1;  /* Revisit for NUMA */
35         sd->platform_data = pdev;
36
37         /* Look for resources for this controller in xenbus. */
38         err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "root_num",
39                            "%d", &root_num);
40         if (err != 1)
41                 return;
42
43         for (i = 0; i < root_num; i++) {
44                 len = snprintf(str, sizeof(str), "root-%d", i);
45                 if (unlikely(len >= (sizeof(str) - 1)))
46                         return;
47
48                 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
49                                    str, "%x:%x", &d, &b);
50                 if (err != 2)
51                         return;
52
53                 if (d == domain && b == bus)
54                         break;
55         }
56
57         if (i == root_num)
58                 return;
59
60         len = snprintf(str, sizeof(str), "root-resource-magic");
61
62         err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
63                            str, "%lx", &magic);
64
65         if (err != 1)
66                 return; /* No resources, nothing to do */
67
68         if (magic != (sizeof(res) * 2) + 1) {
69                 printk(KERN_WARNING "pcifront: resource magic mismatch\n");
70                 return;
71         }
72
73         len = snprintf(str, sizeof(str), "root-%d-resources", i);
74         if (unlikely(len >= (sizeof(str) - 1)))
75                 return;
76
77         err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
78                            str, "%d", &res_count);
79
80         if (err != 1)
81                 return; /* No resources, nothing to do */
82
83         sd->window = kzalloc(sizeof(*sd->window) * res_count, GFP_KERNEL);
84         if (!sd->window)
85                 return;
86
87         /* magic is also the size of the byte stream in xenbus */
88         buf = kmalloc(magic, GFP_KERNEL);
89         if (!buf) {
90                 kfree(sd->window);
91                 sd->window = NULL;
92                 return;
93         }
94
95         /* Read the resources out of xenbus */
96         for (j = 0; j < res_count; j++) {
97                 memset(&res, 0, sizeof(res));
98                 memset(buf, 0, magic);
99
100                 len = snprintf(str, sizeof(str), "root-%d-resource-%d", i, j);
101                 if (unlikely(len >= (sizeof(str) - 1)))
102                         return;
103
104                 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
105                                    "%s", buf);
106                 if (err != 1) {
107                         printk(KERN_WARNING "pcifront: error reading "
108                                "resource %d on bus %04x:%02x\n",
109                                j, domain, bus);
110                         continue;
111                 }
112
113                 bufp = buf;
114                 ptr = (u8 *)&res;
115                 memset(tmp, 0, sizeof(tmp));
116
117                 /* Copy ASCII byte stream into structure */
118                 for (k = 0; k < magic - 1; k += 2) {
119                         memcpy(tmp, bufp, 2);
120                         bufp += 2;
121
122                         sscanf(tmp, "%02x", &byte);
123                         *ptr = byte;
124                         ptr++;
125                 }
126
127                 xen_add_resource(sd, domain, bus, &res);
128                 sd->windows++;
129         }
130         kfree(buf);
131 }
132 #endif
133
134 static int errno_to_pcibios_err(int errno)
135 {
136         switch (errno) {
137         case XEN_PCI_ERR_success:
138                 return PCIBIOS_SUCCESSFUL;
139
140         case XEN_PCI_ERR_dev_not_found:
141                 return PCIBIOS_DEVICE_NOT_FOUND;
142
143         case XEN_PCI_ERR_invalid_offset:
144         case XEN_PCI_ERR_op_failed:
145                 return PCIBIOS_BAD_REGISTER_NUMBER;
146
147         case XEN_PCI_ERR_not_implemented:
148                 return PCIBIOS_FUNC_NOT_SUPPORTED;
149
150         case XEN_PCI_ERR_access_denied:
151                 return PCIBIOS_SET_FAILED;
152         }
153         return errno;
154 }
155
156 static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
157 {
158         int err = 0;
159         struct xen_pci_op *active_op = &pdev->sh_info->op;
160         unsigned long irq_flags;
161         evtchn_port_t port = pdev->evtchn;
162         s64 ns, ns_timeout;
163         struct timeval tv;
164
165         spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
166
167         memcpy(active_op, op, sizeof(struct xen_pci_op));
168
169         /* Go */
170         wmb();
171         set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
172         notify_remote_via_evtchn(port);
173
174         /*
175          * We set a poll timeout of 3 seconds but give up on return after
176          * 2 seconds. It is better to time out too late rather than too early
177          * (in the latter case we end up continually re-executing poll() with a
178          * timeout in the past). 1s difference gives plenty of slack for error.
179          */
180         do_gettimeofday(&tv);
181         ns_timeout = timeval_to_ns(&tv) + 2 * (s64)NSEC_PER_SEC;
182
183         clear_evtchn(port);
184
185         while (test_bit(_XEN_PCIF_active,
186                         (unsigned long *)&pdev->sh_info->flags)) {
187                 if (HYPERVISOR_poll(&port, 1, jiffies + 3*HZ))
188                         BUG();
189                 clear_evtchn(port);
190                 do_gettimeofday(&tv);
191                 ns = timeval_to_ns(&tv);
192                 if (ns > ns_timeout) {
193                         dev_err(&pdev->xdev->dev,
194                                 "pciback not responding!!!\n");
195                         clear_bit(_XEN_PCIF_active,
196                                   (unsigned long *)&pdev->sh_info->flags);
197                         err = XEN_PCI_ERR_dev_not_found;
198                         goto out;
199                 }
200         }
201
202         memcpy(op, active_op, sizeof(struct xen_pci_op));
203
204         err = op->err;
205       out:
206         spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags);
207         return err;
208 }
209
210 /* Access to this function is spinlocked in drivers/pci/access.c */
211 static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn,
212                              int where, int size, u32 * val)
213 {
214         int err = 0;
215         struct xen_pci_op op = {
216                 .cmd    = XEN_PCI_OP_conf_read,
217                 .domain = pci_domain_nr(bus),
218                 .bus    = bus->number,
219                 .devfn  = devfn,
220                 .offset = where,
221                 .size   = size,
222         };
223         struct pcifront_sd *sd = bus->sysdata;
224         struct pcifront_device *pdev = pcifront_get_pdev(sd);
225
226         if (verbose_request)
227                 dev_info(&pdev->xdev->dev,
228                          "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n",
229                          pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
230                          PCI_FUNC(devfn), where, size);
231
232         err = do_pci_op(pdev, &op);
233
234         if (likely(!err)) {
235                 if (verbose_request)
236                         dev_info(&pdev->xdev->dev, "read got back value %x\n",
237                                  op.value);
238
239                 *val = op.value;
240         } else if (err == -ENODEV) {
241                 /* No device here, pretend that it just returned 0 */
242                 err = 0;
243                 *val = 0;
244         }
245
246         return errno_to_pcibios_err(err);
247 }
248
249 /* Access to this function is spinlocked in drivers/pci/access.c */
250 static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
251                               int where, int size, u32 val)
252 {
253         struct xen_pci_op op = {
254                 .cmd    = XEN_PCI_OP_conf_write,
255                 .domain = pci_domain_nr(bus),
256                 .bus    = bus->number,
257                 .devfn  = devfn,
258                 .offset = where,
259                 .size   = size,
260                 .value  = val,
261         };
262         struct pcifront_sd *sd = bus->sysdata;
263         struct pcifront_device *pdev = pcifront_get_pdev(sd);
264
265         if (verbose_request)
266                 dev_info(&pdev->xdev->dev,
267                          "write dev=%04x:%02x:%02x.%01x - "
268                          "offset %x size %d val %x\n",
269                          pci_domain_nr(bus), bus->number,
270                          PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
271
272         return errno_to_pcibios_err(do_pci_op(pdev, &op));
273 }
274
275 struct pci_ops pcifront_bus_ops = {
276         .read = pcifront_bus_read,
277         .write = pcifront_bus_write,
278 };
279
280 /* Claim resources for the PCI frontend as-is, backend won't allow changes */
281 static void pcifront_claim_resource(struct pci_dev *dev, void *data)
282 {
283         struct pcifront_device *pdev = data;
284         int i;
285         struct resource *r;
286
287         for (i = 0; i < PCI_NUM_RESOURCES; i++) {
288                 r = &dev->resource[i];
289
290                 if (!r->parent && r->start && r->flags) {
291                         dev_dbg(&pdev->xdev->dev, "claiming resource %s/%d\n",
292                                 pci_name(dev), i);
293                         pci_claim_resource(dev, i);
294                 }
295         }
296 }
297
298 int pcifront_scan_root(struct pcifront_device *pdev,
299                        unsigned int domain, unsigned int bus)
300 {
301         struct pci_bus *b;
302         struct pcifront_sd *sd = NULL;
303         struct pci_bus_entry *bus_entry = NULL;
304         int err = 0;
305
306 #ifndef CONFIG_PCI_DOMAINS
307         if (domain != 0) {
308                 dev_err(&pdev->xdev->dev,
309                         "PCI Root in non-zero PCI Domain! domain=%d\n", domain);
310                 dev_err(&pdev->xdev->dev,
311                         "Please compile with CONFIG_PCI_DOMAINS\n");
312                 err = -EINVAL;
313                 goto err_out;
314         }
315 #endif
316
317         dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
318                  domain, bus);
319
320         bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
321         sd = kmalloc(sizeof(*sd), GFP_KERNEL);
322         if (!bus_entry || !sd) {
323                 err = -ENOMEM;
324                 goto err_out;
325         }
326         pcifront_init_sd(sd, domain, bus, pdev);
327
328         b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
329                                   &pcifront_bus_ops, sd);
330         if (!b) {
331                 dev_err(&pdev->xdev->dev,
332                         "Error creating PCI Frontend Bus!\n");
333                 err = -ENOMEM;
334                 goto err_out;
335         }
336
337         pcifront_setup_root_resources(b, sd);
338         bus_entry->bus = b;
339
340         list_add(&bus_entry->list, &pdev->root_buses);
341
342         /* Claim resources before going "live" with our devices */
343         pci_walk_bus(b, pcifront_claim_resource, pdev);
344
345         pci_bus_add_devices(b);
346
347         return 0;
348
349       err_out:
350         kfree(bus_entry);
351         kfree(sd);
352
353         return err;
354 }
355
356 static void free_root_bus_devs(struct pci_bus *bus)
357 {
358         struct pci_dev *dev;
359
360         while (!list_empty(&bus->devices)) {
361                 dev = container_of(bus->devices.next, struct pci_dev,
362                                    bus_list);
363                 dev_dbg(&dev->dev, "removing device\n");
364                 pci_remove_bus_device(dev);
365         }
366 }
367
368 void pcifront_free_roots(struct pcifront_device *pdev)
369 {
370         struct pci_bus_entry *bus_entry, *t;
371
372         dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
373
374         list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
375                 list_del(&bus_entry->list);
376
377                 free_root_bus_devs(bus_entry->bus);
378
379                 kfree(bus_entry->bus->sysdata);
380
381                 device_unregister(bus_entry->bus->bridge);
382                 pci_remove_bus(bus_entry->bus);
383
384                 kfree(bus_entry);
385         }
386 }