]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/xen/xen-pciback/xenbus.c
xen/pciback: Cleanup the driver based on checkpatch warnings and errors.
[mv-sheeva.git] / drivers / xen / xen-pciback / xenbus.c
1 /*
2  * PCI Backend Xenbus Setup - handles setup with frontend and xend
3  *
4  *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
5  */
6 #include <linux/module.h>
7 #include <linux/init.h>
8 #include <linux/list.h>
9 #include <linux/vmalloc.h>
10 #include <linux/workqueue.h>
11 #include <xen/xenbus.h>
12 #include <xen/events.h>
13 #include <linux/workqueue.h>
14 #include "pciback.h"
15
16 #define INVALID_EVTCHN_IRQ  (-1)
17 struct workqueue_struct *pciback_wq;
18
19 static struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
20 {
21         struct pciback_device *pdev;
22
23         pdev = kzalloc(sizeof(struct pciback_device), GFP_KERNEL);
24         if (pdev == NULL)
25                 goto out;
26         dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
27
28         pdev->xdev = xdev;
29         dev_set_drvdata(&xdev->dev, pdev);
30
31         spin_lock_init(&pdev->dev_lock);
32
33         pdev->sh_info = NULL;
34         pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
35         pdev->be_watching = 0;
36
37         INIT_WORK(&pdev->op_work, pciback_do_op);
38
39         if (pciback_init_devices(pdev)) {
40                 kfree(pdev);
41                 pdev = NULL;
42         }
43 out:
44         return pdev;
45 }
46
47 static void pciback_disconnect(struct pciback_device *pdev)
48 {
49         spin_lock(&pdev->dev_lock);
50
51         /* Ensure the guest can't trigger our handler before removing devices */
52         if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) {
53                 unbind_from_irqhandler(pdev->evtchn_irq, pdev);
54                 pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
55         }
56
57         /* If the driver domain started an op, make sure we complete it
58          * before releasing the shared memory */
59         flush_workqueue(pciback_wq);
60
61         if (pdev->sh_info != NULL) {
62                 xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info);
63                 pdev->sh_info = NULL;
64         }
65
66         spin_unlock(&pdev->dev_lock);
67 }
68
69 static void free_pdev(struct pciback_device *pdev)
70 {
71         if (pdev->be_watching)
72                 unregister_xenbus_watch(&pdev->be_watch);
73
74         pciback_disconnect(pdev);
75
76         pciback_release_devices(pdev);
77
78         dev_set_drvdata(&pdev->xdev->dev, NULL);
79         pdev->xdev = NULL;
80
81         kfree(pdev);
82 }
83
84 static int pciback_do_attach(struct pciback_device *pdev, int gnt_ref,
85                              int remote_evtchn)
86 {
87         int err = 0;
88         void *vaddr;
89
90         dev_dbg(&pdev->xdev->dev,
91                 "Attaching to frontend resources - gnt_ref=%d evtchn=%d\n",
92                 gnt_ref, remote_evtchn);
93
94         err = xenbus_map_ring_valloc(pdev->xdev, gnt_ref, &vaddr);
95         if (err < 0) {
96                 xenbus_dev_fatal(pdev->xdev, err,
97                                 "Error mapping other domain page in ours.");
98                 goto out;
99         }
100         pdev->sh_info = vaddr;
101
102         err = bind_interdomain_evtchn_to_irqhandler(
103                 pdev->xdev->otherend_id, remote_evtchn, pciback_handle_event,
104                 0, "pciback", pdev);
105         if (err < 0) {
106                 xenbus_dev_fatal(pdev->xdev, err,
107                                  "Error binding event channel to IRQ");
108                 goto out;
109         }
110         pdev->evtchn_irq = err;
111         err = 0;
112
113         dev_dbg(&pdev->xdev->dev, "Attached!\n");
114 out:
115         return err;
116 }
117
118 static int pciback_attach(struct pciback_device *pdev)
119 {
120         int err = 0;
121         int gnt_ref, remote_evtchn;
122         char *magic = NULL;
123
124         spin_lock(&pdev->dev_lock);
125
126         /* Make sure we only do this setup once */
127         if (xenbus_read_driver_state(pdev->xdev->nodename) !=
128             XenbusStateInitialised)
129                 goto out;
130
131         /* Wait for frontend to state that it has published the configuration */
132         if (xenbus_read_driver_state(pdev->xdev->otherend) !=
133             XenbusStateInitialised)
134                 goto out;
135
136         dev_dbg(&pdev->xdev->dev, "Reading frontend config\n");
137
138         err = xenbus_gather(XBT_NIL, pdev->xdev->otherend,
139                             "pci-op-ref", "%u", &gnt_ref,
140                             "event-channel", "%u", &remote_evtchn,
141                             "magic", NULL, &magic, NULL);
142         if (err) {
143                 /* If configuration didn't get read correctly, wait longer */
144                 xenbus_dev_fatal(pdev->xdev, err,
145                                  "Error reading configuration from frontend");
146                 goto out;
147         }
148
149         if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) {
150                 xenbus_dev_fatal(pdev->xdev, -EFAULT,
151                                  "version mismatch (%s/%s) with pcifront - "
152                                  "halting pciback",
153                                  magic, XEN_PCI_MAGIC);
154                 goto out;
155         }
156
157         err = pciback_do_attach(pdev, gnt_ref, remote_evtchn);
158         if (err)
159                 goto out;
160
161         dev_dbg(&pdev->xdev->dev, "Connecting...\n");
162
163         err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
164         if (err)
165                 xenbus_dev_fatal(pdev->xdev, err,
166                                  "Error switching to connected state!");
167
168         dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err);
169 out:
170         spin_unlock(&pdev->dev_lock);
171
172         kfree(magic);
173
174         return err;
175 }
176
177 static int pciback_publish_pci_dev(struct pciback_device *pdev,
178                                    unsigned int domain, unsigned int bus,
179                                    unsigned int devfn, unsigned int devid)
180 {
181         int err;
182         int len;
183         char str[64];
184
185         len = snprintf(str, sizeof(str), "vdev-%d", devid);
186         if (unlikely(len >= (sizeof(str) - 1))) {
187                 err = -ENOMEM;
188                 goto out;
189         }
190
191         err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
192                             "%04x:%02x:%02x.%02x", domain, bus,
193                             PCI_SLOT(devfn), PCI_FUNC(devfn));
194
195 out:
196         return err;
197 }
198
199 static int pciback_export_device(struct pciback_device *pdev,
200                                  int domain, int bus, int slot, int func,
201                                  int devid)
202 {
203         struct pci_dev *dev;
204         int err = 0;
205
206         dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n",
207                 domain, bus, slot, func);
208
209         dev = pcistub_get_pci_dev_by_slot(pdev, domain, bus, slot, func);
210         if (!dev) {
211                 err = -EINVAL;
212                 xenbus_dev_fatal(pdev->xdev, err,
213                                  "Couldn't locate PCI device "
214                                  "(%04x:%02x:%02x.%01x)! "
215                                  "perhaps already in-use?",
216                                  domain, bus, slot, func);
217                 goto out;
218         }
219
220         err = pciback_add_pci_dev(pdev, dev, devid, pciback_publish_pci_dev);
221         if (err)
222                 goto out;
223
224         /* TODO: It'd be nice to export a bridge and have all of its children
225          * get exported with it. This may be best done in xend (which will
226          * have to calculate resource usage anyway) but we probably want to
227          * put something in here to ensure that if a bridge gets given to a
228          * driver domain, that all devices under that bridge are not given
229          * to other driver domains (as he who controls the bridge can disable
230          * it and stop the other devices from working).
231          */
232 out:
233         return err;
234 }
235
236 static int pciback_remove_device(struct pciback_device *pdev,
237                                  int domain, int bus, int slot, int func)
238 {
239         int err = 0;
240         struct pci_dev *dev;
241
242         dev_dbg(&pdev->xdev->dev, "removing dom %x bus %x slot %x func %x\n",
243                 domain, bus, slot, func);
244
245         dev = pciback_get_pci_dev(pdev, domain, bus, PCI_DEVFN(slot, func));
246         if (!dev) {
247                 err = -EINVAL;
248                 dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device "
249                         "(%04x:%02x:%02x.%01x)! not owned by this domain\n",
250                         domain, bus, slot, func);
251                 goto out;
252         }
253
254         pciback_release_pci_dev(pdev, dev);
255
256 out:
257         return err;
258 }
259
260 static int pciback_publish_pci_root(struct pciback_device *pdev,
261                                     unsigned int domain, unsigned int bus)
262 {
263         unsigned int d, b;
264         int i, root_num, len, err;
265         char str[64];
266
267         dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n");
268
269         err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
270                            "root_num", "%d", &root_num);
271         if (err == 0 || err == -ENOENT)
272                 root_num = 0;
273         else if (err < 0)
274                 goto out;
275
276         /* Verify that we haven't already published this pci root */
277         for (i = 0; i < root_num; i++) {
278                 len = snprintf(str, sizeof(str), "root-%d", i);
279                 if (unlikely(len >= (sizeof(str) - 1))) {
280                         err = -ENOMEM;
281                         goto out;
282                 }
283
284                 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
285                                    str, "%x:%x", &d, &b);
286                 if (err < 0)
287                         goto out;
288                 if (err != 2) {
289                         err = -EINVAL;
290                         goto out;
291                 }
292
293                 if (d == domain && b == bus) {
294                         err = 0;
295                         goto out;
296                 }
297         }
298
299         len = snprintf(str, sizeof(str), "root-%d", root_num);
300         if (unlikely(len >= (sizeof(str) - 1))) {
301                 err = -ENOMEM;
302                 goto out;
303         }
304
305         dev_dbg(&pdev->xdev->dev, "writing root %d at %04x:%02x\n",
306                 root_num, domain, bus);
307
308         err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
309                             "%04x:%02x", domain, bus);
310         if (err)
311                 goto out;
312
313         err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,
314                             "root_num", "%d", (root_num + 1));
315
316 out:
317         return err;
318 }
319
320 static int pciback_reconfigure(struct pciback_device *pdev)
321 {
322         int err = 0;
323         int num_devs;
324         int domain, bus, slot, func;
325         int substate;
326         int i, len;
327         char state_str[64];
328         char dev_str[64];
329
330         spin_lock(&pdev->dev_lock);
331
332         dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n");
333
334         /* Make sure we only reconfigure once */
335         if (xenbus_read_driver_state(pdev->xdev->nodename) !=
336             XenbusStateReconfiguring)
337                 goto out;
338
339         err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
340                            &num_devs);
341         if (err != 1) {
342                 if (err >= 0)
343                         err = -EINVAL;
344                 xenbus_dev_fatal(pdev->xdev, err,
345                                  "Error reading number of devices");
346                 goto out;
347         }
348
349         for (i = 0; i < num_devs; i++) {
350                 len = snprintf(state_str, sizeof(state_str), "state-%d", i);
351                 if (unlikely(len >= (sizeof(state_str) - 1))) {
352                         err = -ENOMEM;
353                         xenbus_dev_fatal(pdev->xdev, err,
354                                          "String overflow while reading "
355                                          "configuration");
356                         goto out;
357                 }
358                 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, state_str,
359                                    "%d", &substate);
360                 if (err != 1)
361                         substate = XenbusStateUnknown;
362
363                 switch (substate) {
364                 case XenbusStateInitialising:
365                         dev_dbg(&pdev->xdev->dev, "Attaching dev-%d ...\n", i);
366
367                         len = snprintf(dev_str, sizeof(dev_str), "dev-%d", i);
368                         if (unlikely(len >= (sizeof(dev_str) - 1))) {
369                                 err = -ENOMEM;
370                                 xenbus_dev_fatal(pdev->xdev, err,
371                                                  "String overflow while "
372                                                  "reading configuration");
373                                 goto out;
374                         }
375                         err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
376                                            dev_str, "%x:%x:%x.%x",
377                                            &domain, &bus, &slot, &func);
378                         if (err < 0) {
379                                 xenbus_dev_fatal(pdev->xdev, err,
380                                                  "Error reading device "
381                                                  "configuration");
382                                 goto out;
383                         }
384                         if (err != 4) {
385                                 err = -EINVAL;
386                                 xenbus_dev_fatal(pdev->xdev, err,
387                                                  "Error parsing pci device "
388                                                  "configuration");
389                                 goto out;
390                         }
391
392                         err = pciback_export_device(pdev, domain, bus, slot,
393                                                     func, i);
394                         if (err)
395                                 goto out;
396
397                         /* Publish pci roots. */
398                         err = pciback_publish_pci_roots(pdev,
399                                                 pciback_publish_pci_root);
400                         if (err) {
401                                 xenbus_dev_fatal(pdev->xdev, err,
402                                                  "Error while publish PCI root"
403                                                  "buses for frontend");
404                                 goto out;
405                         }
406
407                         err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,
408                                             state_str, "%d",
409                                             XenbusStateInitialised);
410                         if (err) {
411                                 xenbus_dev_fatal(pdev->xdev, err,
412                                                  "Error switching substate of "
413                                                  "dev-%d\n", i);
414                                 goto out;
415                         }
416                         break;
417
418                 case XenbusStateClosing:
419                         dev_dbg(&pdev->xdev->dev, "Detaching dev-%d ...\n", i);
420
421                         len = snprintf(dev_str, sizeof(dev_str), "vdev-%d", i);
422                         if (unlikely(len >= (sizeof(dev_str) - 1))) {
423                                 err = -ENOMEM;
424                                 xenbus_dev_fatal(pdev->xdev, err,
425                                                  "String overflow while "
426                                                  "reading configuration");
427                                 goto out;
428                         }
429                         err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
430                                            dev_str, "%x:%x:%x.%x",
431                                            &domain, &bus, &slot, &func);
432                         if (err < 0) {
433                                 xenbus_dev_fatal(pdev->xdev, err,
434                                                  "Error reading device "
435                                                  "configuration");
436                                 goto out;
437                         }
438                         if (err != 4) {
439                                 err = -EINVAL;
440                                 xenbus_dev_fatal(pdev->xdev, err,
441                                                  "Error parsing pci device "
442                                                  "configuration");
443                                 goto out;
444                         }
445
446                         err = pciback_remove_device(pdev, domain, bus, slot,
447                                                     func);
448                         if (err)
449                                 goto out;
450
451                         /* TODO: If at some point we implement support for pci
452                          * root hot-remove on pcifront side, we'll need to
453                          * remove unnecessary xenstore nodes of pci roots here.
454                          */
455
456                         break;
457
458                 default:
459                         break;
460                 }
461         }
462
463         err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured);
464         if (err) {
465                 xenbus_dev_fatal(pdev->xdev, err,
466                                  "Error switching to reconfigured state!");
467                 goto out;
468         }
469
470 out:
471         spin_unlock(&pdev->dev_lock);
472
473         return 0;
474 }
475
476 static void pciback_frontend_changed(struct xenbus_device *xdev,
477                                      enum xenbus_state fe_state)
478 {
479         struct pciback_device *pdev = dev_get_drvdata(&xdev->dev);
480
481         dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state);
482
483         switch (fe_state) {
484         case XenbusStateInitialised:
485                 pciback_attach(pdev);
486                 break;
487
488         case XenbusStateReconfiguring:
489                 pciback_reconfigure(pdev);
490                 break;
491
492         case XenbusStateConnected:
493                 /* pcifront switched its state from reconfiguring to connected.
494                  * Then switch to connected state.
495                  */
496                 xenbus_switch_state(xdev, XenbusStateConnected);
497                 break;
498
499         case XenbusStateClosing:
500                 pciback_disconnect(pdev);
501                 xenbus_switch_state(xdev, XenbusStateClosing);
502                 break;
503
504         case XenbusStateClosed:
505                 pciback_disconnect(pdev);
506                 xenbus_switch_state(xdev, XenbusStateClosed);
507                 if (xenbus_dev_is_online(xdev))
508                         break;
509                 /* fall through if not online */
510         case XenbusStateUnknown:
511                 dev_dbg(&xdev->dev, "frontend is gone! unregister device\n");
512                 device_unregister(&xdev->dev);
513                 break;
514
515         default:
516                 break;
517         }
518 }
519
520 static int pciback_setup_backend(struct pciback_device *pdev)
521 {
522         /* Get configuration from xend (if available now) */
523         int domain, bus, slot, func;
524         int err = 0;
525         int i, num_devs;
526         char dev_str[64];
527         char state_str[64];
528
529         spin_lock(&pdev->dev_lock);
530
531         /* It's possible we could get the call to setup twice, so make sure
532          * we're not already connected.
533          */
534         if (xenbus_read_driver_state(pdev->xdev->nodename) !=
535             XenbusStateInitWait)
536                 goto out;
537
538         dev_dbg(&pdev->xdev->dev, "getting be setup\n");
539
540         err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
541                            &num_devs);
542         if (err != 1) {
543                 if (err >= 0)
544                         err = -EINVAL;
545                 xenbus_dev_fatal(pdev->xdev, err,
546                                  "Error reading number of devices");
547                 goto out;
548         }
549
550         for (i = 0; i < num_devs; i++) {
551                 int l = snprintf(dev_str, sizeof(dev_str), "dev-%d", i);
552                 if (unlikely(l >= (sizeof(dev_str) - 1))) {
553                         err = -ENOMEM;
554                         xenbus_dev_fatal(pdev->xdev, err,
555                                          "String overflow while reading "
556                                          "configuration");
557                         goto out;
558                 }
559
560                 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, dev_str,
561                                    "%x:%x:%x.%x", &domain, &bus, &slot, &func);
562                 if (err < 0) {
563                         xenbus_dev_fatal(pdev->xdev, err,
564                                          "Error reading device configuration");
565                         goto out;
566                 }
567                 if (err != 4) {
568                         err = -EINVAL;
569                         xenbus_dev_fatal(pdev->xdev, err,
570                                          "Error parsing pci device "
571                                          "configuration");
572                         goto out;
573                 }
574
575                 err = pciback_export_device(pdev, domain, bus, slot, func, i);
576                 if (err)
577                         goto out;
578
579                 /* Switch substate of this device. */
580                 l = snprintf(state_str, sizeof(state_str), "state-%d", i);
581                 if (unlikely(l >= (sizeof(state_str) - 1))) {
582                         err = -ENOMEM;
583                         xenbus_dev_fatal(pdev->xdev, err,
584                                          "String overflow while reading "
585                                          "configuration");
586                         goto out;
587                 }
588                 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, state_str,
589                                     "%d", XenbusStateInitialised);
590                 if (err) {
591                         xenbus_dev_fatal(pdev->xdev, err, "Error switching "
592                                          "substate of dev-%d\n", i);
593                         goto out;
594                 }
595         }
596
597         err = pciback_publish_pci_roots(pdev, pciback_publish_pci_root);
598         if (err) {
599                 xenbus_dev_fatal(pdev->xdev, err,
600                                  "Error while publish PCI root buses "
601                                  "for frontend");
602                 goto out;
603         }
604
605         err = xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
606         if (err)
607                 xenbus_dev_fatal(pdev->xdev, err,
608                                  "Error switching to initialised state!");
609
610 out:
611         spin_unlock(&pdev->dev_lock);
612
613         if (!err)
614                 /* see if pcifront is already configured (if not, we'll wait) */
615                 pciback_attach(pdev);
616
617         return err;
618 }
619
620 static void pciback_be_watch(struct xenbus_watch *watch,
621                              const char **vec, unsigned int len)
622 {
623         struct pciback_device *pdev =
624             container_of(watch, struct pciback_device, be_watch);
625
626         switch (xenbus_read_driver_state(pdev->xdev->nodename)) {
627         case XenbusStateInitWait:
628                 pciback_setup_backend(pdev);
629                 break;
630
631         default:
632                 break;
633         }
634 }
635
636 static int pciback_xenbus_probe(struct xenbus_device *dev,
637                                 const struct xenbus_device_id *id)
638 {
639         int err = 0;
640         struct pciback_device *pdev = alloc_pdev(dev);
641
642         if (pdev == NULL) {
643                 err = -ENOMEM;
644                 xenbus_dev_fatal(dev, err,
645                                  "Error allocating pciback_device struct");
646                 goto out;
647         }
648
649         /* wait for xend to configure us */
650         err = xenbus_switch_state(dev, XenbusStateInitWait);
651         if (err)
652                 goto out;
653
654         /* watch the backend node for backend configuration information */
655         err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch,
656                                 pciback_be_watch);
657         if (err)
658                 goto out;
659         pdev->be_watching = 1;
660
661         /* We need to force a call to our callback here in case
662          * xend already configured us!
663          */
664         pciback_be_watch(&pdev->be_watch, NULL, 0);
665
666 out:
667         return err;
668 }
669
670 static int pciback_xenbus_remove(struct xenbus_device *dev)
671 {
672         struct pciback_device *pdev = dev_get_drvdata(&dev->dev);
673
674         if (pdev != NULL)
675                 free_pdev(pdev);
676
677         return 0;
678 }
679
680 static const struct xenbus_device_id xenpci_ids[] = {
681         {"pci"},
682         {""},
683 };
684
685 static struct xenbus_driver xenbus_pciback_driver = {
686         .name                   = "pciback",
687         .owner                  = THIS_MODULE,
688         .ids                    = xenpci_ids,
689         .probe                  = pciback_xenbus_probe,
690         .remove                 = pciback_xenbus_remove,
691         .otherend_changed       = pciback_frontend_changed,
692 };
693
694 int __init pciback_xenbus_register(void)
695 {
696         pciback_wq = create_workqueue("pciback_workqueue");
697         if (!pciback_wq) {
698                 printk(KERN_ERR "%s: create"
699                         "pciback_workqueue failed\n", __func__);
700                 return -EFAULT;
701         }
702         return xenbus_register_backend(&xenbus_pciback_driver);
703 }
704
705 void __exit pciback_xenbus_unregister(void)
706 {
707         destroy_workqueue(pciback_wq);
708         xenbus_unregister_driver(&xenbus_pciback_driver);
709 }