Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.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 static int errno_to_pcibios_err(int errno)
19 {
20         switch (errno) {
21         case XEN_PCI_ERR_success:
22                 return PCIBIOS_SUCCESSFUL;
23
24         case XEN_PCI_ERR_dev_not_found:
25                 return PCIBIOS_DEVICE_NOT_FOUND;
26
27         case XEN_PCI_ERR_invalid_offset:
28         case XEN_PCI_ERR_op_failed:
29                 return PCIBIOS_BAD_REGISTER_NUMBER;
30
31         case XEN_PCI_ERR_not_implemented:
32                 return PCIBIOS_FUNC_NOT_SUPPORTED;
33
34         case XEN_PCI_ERR_access_denied:
35                 return PCIBIOS_SET_FAILED;
36         }
37         return errno;
38 }
39
40 static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
41 {
42         int err = 0;
43         struct xen_pci_op *active_op = &pdev->sh_info->op;
44         unsigned long irq_flags;
45         evtchn_port_t port = pdev->evtchn;
46         s64 ns, ns_timeout;
47         struct timeval tv;
48
49         spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
50
51         memcpy(active_op, op, sizeof(struct xen_pci_op));
52
53         /* Go */
54         wmb();
55         set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
56         notify_remote_via_evtchn(port);
57
58         /*
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.
63          */
64         do_gettimeofday(&tv);
65         ns_timeout = timeval_to_ns(&tv) + 2 * NSEC_PER_SEC;
66
67         clear_evtchn(port);
68
69         while (test_bit(_XEN_PCIF_active,
70                         (unsigned long *)&pdev->sh_info->flags)) {
71                 if (HYPERVISOR_poll(&port, 1, jiffies + 3*HZ))
72                         BUG();
73                 clear_evtchn(port);
74                 do_gettimeofday(&tv);
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;
82                         goto out;
83                 }
84         }
85
86         memcpy(op, active_op, sizeof(struct xen_pci_op));
87
88         err = op->err;
89       out:
90         spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags);
91         return err;
92 }
93
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)
97 {
98         int err = 0;
99         struct xen_pci_op op = {
100                 .cmd    = XEN_PCI_OP_conf_read,
101                 .domain = pci_domain_nr(bus),
102                 .bus    = bus->number,
103                 .devfn  = devfn,
104                 .offset = where,
105                 .size   = size,
106         };
107         struct pcifront_sd *sd = bus->sysdata;
108         struct pcifront_device *pdev = pcifront_get_pdev(sd);
109
110         if (verbose_request)
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);
115
116         err = do_pci_op(pdev, &op);
117
118         if (likely(!err)) {
119                 if (verbose_request)
120                         dev_info(&pdev->xdev->dev, "read got back value %x\n",
121                                  op.value);
122
123                 *val = op.value;
124         } else if (err == -ENODEV) {
125                 /* No device here, pretend that it just returned 0 */
126                 err = 0;
127                 *val = 0;
128         }
129
130         return errno_to_pcibios_err(err);
131 }
132
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)
136 {
137         struct xen_pci_op op = {
138                 .cmd    = XEN_PCI_OP_conf_write,
139                 .domain = pci_domain_nr(bus),
140                 .bus    = bus->number,
141                 .devfn  = devfn,
142                 .offset = where,
143                 .size   = size,
144                 .value  = val,
145         };
146         struct pcifront_sd *sd = bus->sysdata;
147         struct pcifront_device *pdev = pcifront_get_pdev(sd);
148
149         if (verbose_request)
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);
155
156         return errno_to_pcibios_err(do_pci_op(pdev, &op));
157 }
158
159 struct pci_ops pcifront_bus_ops = {
160         .read = pcifront_bus_read,
161         .write = pcifront_bus_write,
162 };
163
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)
166 {
167         struct pcifront_device *pdev = data;
168         int i;
169         struct resource *r;
170
171         for (i = 0; i < PCI_NUM_RESOURCES; i++) {
172                 r = &dev->resource[i];
173
174                 if (!r->parent && r->start && r->flags) {
175                         dev_dbg(&pdev->xdev->dev, "claiming resource %s/%d\n",
176                                 pci_name(dev), i);
177                         pci_claim_resource(dev, i);
178                 }
179         }
180 }
181
182 int pcifront_scan_root(struct pcifront_device *pdev,
183                        unsigned int domain, unsigned int bus)
184 {
185         struct pci_bus *b;
186         struct pcifront_sd *sd = NULL;
187         struct pci_bus_entry *bus_entry = NULL;
188         int err = 0;
189
190 #ifndef CONFIG_PCI_DOMAINS
191         if (domain != 0) {
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");
196                 err = -EINVAL;
197                 goto err_out;
198         }
199 #endif
200
201         dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
202                  domain, bus);
203
204         bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
205         sd = kmalloc(sizeof(*sd), GFP_KERNEL);
206         if (!bus_entry || !sd) {
207                 err = -ENOMEM;
208                 goto err_out;
209         }
210         pcifront_init_sd(sd, domain, pdev);
211
212         b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
213                                   &pcifront_bus_ops, sd);
214         if (!b) {
215                 dev_err(&pdev->xdev->dev,
216                         "Error creating PCI Frontend Bus!\n");
217                 err = -ENOMEM;
218                 goto err_out;
219         }
220         bus_entry->bus = b;
221
222         list_add(&bus_entry->list, &pdev->root_buses);
223
224         /* Claim resources before going "live" with our devices */
225         pci_walk_bus(b, pcifront_claim_resource, pdev);
226
227         pci_bus_add_devices(b);
228
229         return 0;
230
231       err_out:
232         kfree(bus_entry);
233         kfree(sd);
234
235         return err;
236 }
237
238 static void free_root_bus_devs(struct pci_bus *bus)
239 {
240         struct pci_dev *dev;
241
242         down_write(&pci_bus_sem);
243         while (!list_empty(&bus->devices)) {
244                 dev = container_of(bus->devices.next, struct pci_dev, bus_list);
245                 up_write(&pci_bus_sem);
246
247                 dev_dbg(&dev->dev, "removing device\n");
248                 pci_remove_bus_device(dev);
249
250                 down_write(&pci_bus_sem);
251         }
252         up_write(&pci_bus_sem);
253 }
254
255 void pcifront_free_roots(struct pcifront_device *pdev)
256 {
257         struct pci_bus_entry *bus_entry, *t;
258
259         dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
260
261         list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
262                 list_del(&bus_entry->list);
263
264                 free_root_bus_devs(bus_entry->bus);
265
266                 kfree(bus_entry->bus->sysdata);
267
268                 device_unregister(bus_entry->bus->bridge);
269                 pci_remove_bus(bus_entry->bus);
270
271                 kfree(bus_entry);
272         }
273 }