- Update Xen patches to 3.3-rc5 and c/s 1157.
[linux-flexiantxendom0-3.2.10.git] / drivers / pci / guestdev.c
1 /*
2  * Copyright (c) 2008, 2009 NEC Corporation.
3  * Copyright (c) 2009 Isaku Yamahata
4  *                    VA Linux Systems Japan K.K.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17  * Place - Suite 330, Boston, MA 02111-1307 USA.
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/list.h>
22 #include <linux/mm.h>
23 #include <linux/pci.h>
24 #include <linux/export.h>
25 #include <linux/string.h>
26 #include <linux/acpi.h>
27 #include <asm/setup.h>
28
29 #define HID_LEN 8
30 #define UID_LEN 8
31 #define DEV_LEN 2
32 #define FUNC_LEN 1
33 #define DEV_NUM_MAX 31
34 #define FUNC_NUM_MAX 7
35 #define INVALID_SEG (-1)
36 #define INVALID_BBN (-1)
37 #define GUESTDEV_STR_MAX 128
38
39 #define GUESTDEV_FLAG_TYPE_MASK 0x3
40 #define GUESTDEV_FLAG_DEVICEPATH 0x1
41 #define GUESTDEV_FLAG_SBDF 0x2
42
43 #define GUESTDEV_OPT_IOMUL      0x1
44
45 struct guestdev {
46         int flags;
47         int options;
48         struct list_head root_list;
49         union {
50                 struct devicepath {
51                         char hid[HID_LEN + 1];
52                         char uid[UID_LEN + 1];
53                         int seg;
54                         int bbn;
55                         struct devicepath_node *child;
56                 } devicepath;
57                 struct sbdf {
58                         int seg;
59                         int bus;
60                         int dev;
61                         int func;
62                 } sbdf;
63         } u;
64 };
65
66 struct devicepath_node {
67         int dev;
68         int func;
69         struct devicepath_node *child;
70 };
71
72 struct pcidev_sbdf {
73         int seg;
74         int bus;
75         struct pcidev_sbdf_node *child;
76 };
77
78 struct pcidev_sbdf_node {
79         int dev;
80         int func;
81         struct pcidev_sbdf_node *child;
82 };
83
84 static char __initdata guestdev_param[COMMAND_LINE_SIZE];
85 static LIST_HEAD(guestdev_list);
86
87 /* Get hid and uid */
88 static int __init pci_get_hid_uid(char *str, char *hid, char *uid)
89 {
90         char *sp, *ep;
91         int len;
92
93         sp = str;
94         ep = strchr(sp, ':');
95         if (!ep) {
96                 ep = strchr(sp, '-');
97                 if (!ep)
98                         goto format_err_end;
99         }
100         /* hid length */
101         len = ep - sp;
102         if (len <= 0 || HID_LEN < len)
103                 goto format_err_end;
104
105         strlcpy(hid, sp, len);
106
107         if (*ep == '-') { /* no uid */
108                 uid[0] = '\0';
109                 return TRUE;
110         }
111
112         sp = ep + 1;
113         ep = strchr(sp, '-');
114         if (!ep)
115                 ep = strchr(sp, '\0');
116
117         /* uid length */
118         len = ep - sp;
119         if (len <= 0 || UID_LEN < len)
120                 goto format_err_end;
121
122         strlcpy(uid, sp, len);
123         return TRUE;
124
125 format_err_end:
126         return FALSE;
127 }
128
129 /* Get device and function */
130 static int __init pci_get_dev_func(char *str, int *dev, int *func)
131 {
132         if (sscanf(str, "%02x.%01x", dev, func) != 2)
133                 goto format_err_end;
134
135         if (*dev < 0 || DEV_NUM_MAX < *dev)
136                 goto format_err_end;
137
138         if (*func < 0 || FUNC_NUM_MAX < *func)
139                 goto format_err_end;
140
141         return TRUE;
142
143 format_err_end:
144         return FALSE;
145 }
146
147 /* Check extended guestdev parameter format error */
148 static int __init pci_check_extended_guestdev_format(char *str)
149 {
150         int flg;
151         char *p;
152
153         /* Check extended format */
154         if (strpbrk(str, "(|)") == NULL)
155                 return TRUE;
156
157         flg = 0;
158         p = str;
159         while (*p) {
160                 switch (*p) {
161                 case '(':
162                         /* Check nesting error */
163                         if (flg != 0)
164                                 goto format_err_end;
165                         flg = 1;
166                         /* Check position of '(' is head or
167                            previos charactor of '(' is not '-'. */
168                         if (p == str || *(p - 1) != '-')
169                                 goto format_err_end;
170                         break;
171                 case ')':
172                         /* Check nesting error */
173                         if (flg != 1)
174                                 goto format_err_end;
175                         flg = 0;
176                         /* Check next charactor of ')' is not '\0' */
177                         if (*(p + 1) != '\0')
178                                 goto format_err_end;
179                         break;
180                 case '|':
181                         /* Check position of '|' is outside of '(' and ')' */
182                         if (flg != 1)
183                                 goto format_err_end;
184                         break;
185                 default:
186                         break;
187                 }
188                 p++;
189         }
190         /* Check number of '(' and ')' are not equal */
191         if (flg != 0)
192                 goto format_err_end;
193         return TRUE;
194
195 format_err_end:
196         pr_err("PCI: The format of the guestdev parameter is illegal. [%s]\n",
197                str);
198         return FALSE;
199 }
200
201 /* Make guestdev strings */
202 static void pci_make_guestdev_str(struct guestdev *gdev,
203                                         char *gdev_str, int buf_size)
204 {
205         struct devicepath_node *node;
206         int count;
207
208         switch (gdev->flags & GUESTDEV_FLAG_TYPE_MASK) {
209         case GUESTDEV_FLAG_DEVICEPATH:
210                 memset(gdev_str, 0, buf_size);
211
212                 if (strlen(gdev->u.devicepath.uid))
213                         count = snprintf(gdev_str, buf_size, "%s:%s",
214                                                 gdev->u.devicepath.hid,
215                                                 gdev->u.devicepath.uid);
216                 else
217                         count = snprintf(gdev_str, buf_size, "%s",
218                                                  gdev->u.devicepath.hid);
219                 if (count < 0)
220                         return;
221
222                 node = gdev->u.devicepath.child;
223                 while (node) {
224                         gdev_str += count;
225                         buf_size -= count;
226                         if (buf_size <= 0)
227                                 return;
228                         count = snprintf(gdev_str, buf_size, "-%02x.%01x",
229                                 node->dev, node->func);
230                         if (count < 0)
231                                 return;
232                         node = node->child;
233                 }
234                 break;
235         case GUESTDEV_FLAG_SBDF:
236                 snprintf(gdev_str, buf_size, "%04x:%02x:%02x.%01x",
237                                         gdev->u.sbdf.seg, gdev->u.sbdf.bus,
238                                         gdev->u.sbdf.dev, gdev->u.sbdf.func);
239                 break;
240         default:
241                 BUG();
242         }
243 }
244
245 /* Free guestdev and nodes */
246 static void __init pci_free_guestdev(struct guestdev *gdev)
247 {
248         struct devicepath_node *node, *next;
249
250         if (!gdev)
251                 return;
252         if (gdev->flags & GUESTDEV_FLAG_DEVICEPATH) {
253                 node = gdev->u.devicepath.child;
254                 while (node) {
255                         next = node->child;
256                         kfree(node);
257                         node = next;
258                 }
259         }
260         list_del(&gdev->root_list);
261         kfree(gdev);
262 }
263
264 /* Copy guestdev and nodes */
265 struct guestdev __init *pci_copy_guestdev(struct guestdev *gdev_src)
266 {
267         struct guestdev *gdev;
268         struct devicepath_node *node, *node_src, *node_upper;
269
270         BUG_ON(!(gdev_src->flags & GUESTDEV_FLAG_DEVICEPATH));
271
272         gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);
273         if (!gdev)
274                 goto allocate_err_end;
275
276         INIT_LIST_HEAD(&gdev->root_list);
277         gdev->flags = gdev_src->flags;
278         gdev->options = gdev_src->options;
279         strcpy(gdev->u.devicepath.hid, gdev_src->u.devicepath.hid);
280         strcpy(gdev->u.devicepath.uid, gdev_src->u.devicepath.uid);
281         gdev->u.devicepath.seg = gdev_src->u.devicepath.seg;
282         gdev->u.devicepath.bbn = gdev_src->u.devicepath.bbn;
283
284         node_upper = NULL;
285
286         node_src = gdev_src->u.devicepath.child;
287         while (node_src) {
288                 node = kzalloc(sizeof(*node), GFP_KERNEL);
289                 if (!node)
290                         goto allocate_err_end;
291                 node->dev = node_src->dev;
292                 node->func = node_src->func;
293                 if (!node_upper)
294                         gdev->u.devicepath.child = node;
295                 else
296                         node_upper->child = node;
297                 node_upper = node;
298                 node_src = node_src->child;
299         }
300
301         return gdev;
302
303 allocate_err_end:
304         if (gdev)
305                 pci_free_guestdev(gdev);
306         pr_err("PCI: failed to allocate memory\n");
307         return NULL;
308 }
309
310 /* Make guestdev from path strings */
311 static int __init pci_make_devicepath_guestdev(char *path_str, int options)
312 {
313         char hid[HID_LEN + 1], uid[UID_LEN + 1];
314         char *sp, *ep;
315         struct guestdev *gdev, *gdev_org;
316         struct devicepath_node *node, *node_tmp;
317         int dev, func, ret_val;
318
319         ret_val = 0;
320         gdev = gdev_org = NULL;
321         sp = path_str;
322         /* Look for end of hid:uid'-' */
323         ep = strchr(sp, '-');
324         /* Only hid, uid. (No dev, func) */
325         if (!ep)
326                 goto format_err_end;
327
328         memset(hid, 0 ,sizeof(hid));
329         memset(uid, 0, sizeof(uid));
330         if (!pci_get_hid_uid(sp, hid, uid))
331                 goto format_err_end;
332
333         gdev_org = kzalloc(sizeof(*gdev_org), GFP_KERNEL);
334         if (!gdev_org)
335                 goto allocate_err_end;
336         INIT_LIST_HEAD(&gdev_org->root_list);
337         gdev_org->flags = GUESTDEV_FLAG_DEVICEPATH;
338         gdev_org->options = options;
339         strcpy(gdev_org->u.devicepath.hid, hid);
340         strcpy(gdev_org->u.devicepath.uid, uid);
341         gdev_org->u.devicepath.seg = INVALID_SEG;
342         gdev_org->u.devicepath.bbn = INVALID_BBN;
343
344         gdev = gdev_org;
345
346         sp = ep + 1;
347         ep = sp;
348         do {
349                 if (*sp == '(') {
350                         sp++;
351                         if (strchr(sp, '|')) {
352                                 gdev = pci_copy_guestdev(gdev_org);
353                                 if (!gdev) {
354                                         ret_val = -ENOMEM;
355                                         goto end;
356                                 }
357                         }
358                         continue;
359                 }
360                 if (gdev && pci_get_dev_func(sp, &dev, &func)) {
361                         node = kzalloc(sizeof(*node), GFP_KERNEL);
362                         if (!node)
363                                 goto allocate_err_end;
364                         node->dev = dev;
365                         node->func = func;
366                         /* add node to end of guestdev */
367                         if (gdev->u.devicepath.child) {
368                                 node_tmp = gdev->u.devicepath.child;
369                                 while (node_tmp->child) {
370                                         node_tmp = node_tmp->child;
371                                 }
372                                 node_tmp->child = node;
373                         } else
374                                 gdev->u.devicepath.child = node;
375                 } else if (gdev) {
376                         pr_err("PCI: Can't obtain dev# and #func# from %s.\n",
377                                sp);
378                         ret_val = -EINVAL;
379                         if (gdev == gdev_org)
380                                 goto end;
381                         pci_free_guestdev(gdev);
382                         gdev = NULL;
383                 }
384
385                 ep = strpbrk(sp, "-|)");
386                 if (!ep)
387                         ep = strchr(sp, '\0');
388                 /* Is *ep '|' OR ')' OR '\0' ? */
389                 if (*ep != '-') {
390                         if (gdev)
391                                 list_add_tail(&gdev->root_list, &guestdev_list);
392                         if (*ep == '|') {
393                                 /* Between '|' and '|' ? */
394                                 if (strchr(ep + 1, '|')) {
395                                         gdev = pci_copy_guestdev(gdev_org);
396                                         if (!gdev) {
397                                                 ret_val = -ENOMEM;
398                                                 goto end;
399                                         }
400                                 } else {
401                                         gdev = gdev_org;
402                                         gdev_org = NULL;
403                                 }
404                         } else {
405                                 gdev_org = NULL;
406                                 gdev = NULL;
407                         }
408                 }
409                 if (*ep == ')')
410                         ep++;
411                 sp = ep + 1;
412         } while (*ep != '\0');
413
414         goto end;
415
416 format_err_end:
417         pr_err("PCI: The format of the guestdev parameter is illegal. [%s]\n",
418                path_str);
419         ret_val = -EINVAL;
420         goto end;
421
422 allocate_err_end:
423         pr_err("PCI: failed to allocate memory\n");
424         ret_val = -ENOMEM;
425         goto end;
426
427 end:
428         if (gdev_org && (gdev_org != gdev))
429                 pci_free_guestdev(gdev_org);
430         if (gdev)
431                 pci_free_guestdev(gdev);
432         return ret_val;
433 }
434
435 static int __init pci_make_sbdf_guestdev(char* str, int options)
436 {
437         struct guestdev *gdev;
438         int seg, bus, dev, func;
439
440         if (sscanf(str, "%x:%x:%x.%x", &seg, &bus, &dev, &func) != 4) {
441                 seg = 0;
442                 if (sscanf(str, "%x:%x.%x", &bus, &dev, &func) != 3)
443                         return -EINVAL;
444         }
445         gdev = kmalloc(sizeof(*gdev), GFP_KERNEL);
446         if (!gdev) {
447                 pr_err("PCI: failed to allocate memory\n");
448                 return -ENOMEM;
449         }
450         INIT_LIST_HEAD(&gdev->root_list);
451         gdev->flags = GUESTDEV_FLAG_SBDF;
452         gdev->options = options;
453         gdev->u.sbdf.seg = seg;
454         gdev->u.sbdf.bus = bus;
455         gdev->u.sbdf.dev = dev;
456         gdev->u.sbdf.func = func;
457         list_add_tail(&gdev->root_list, &guestdev_list);
458         return 0;
459 }
460
461 static int __init pci_parse_options(const char *str)
462 {
463         int options = 0;
464         char *ep;
465
466         while (str) {
467                 str++;
468                 ep = strchr(str, '+');
469                 if (ep)
470                         ep = '\0';      /* Chop */
471
472                 if (!strcmp(str, "iomul"))
473                         options |= GUESTDEV_OPT_IOMUL;
474
475                 str = ep;
476         }
477         return options;
478 }
479
480 /* Parse guestdev parameter */
481 static int __init pci_parse_guestdev(void)
482 {
483         int len;
484         char *sp, *ep, *op;
485         int options;
486         struct list_head *head;
487         struct guestdev *gdev;
488         char path_str[GUESTDEV_STR_MAX];
489         int ret_val = 0;
490
491         len = strlen(guestdev_param);
492         if (len == 0)
493                 return 0;
494
495         sp = guestdev_param;
496
497         do {
498                 ep = strchr(sp, ',');
499                 /* Chop */
500                 if (ep)
501                         *ep = '\0';
502                 options = 0;
503                 op = strchr(sp, '+');
504                 if (op && (!ep || op < ep)) {
505                         options = pci_parse_options(op);
506                         *op = '\0';     /* Chop */
507                 }
508                 ret_val = pci_make_sbdf_guestdev(sp, options);
509                 if (ret_val == -EINVAL) {
510                         if (pci_check_extended_guestdev_format(sp)) {
511                                 ret_val = pci_make_devicepath_guestdev(
512                                         sp, options);
513                                 if (ret_val && ret_val != -EINVAL)
514                                         break;
515                         }
516                 } else if (ret_val)
517                         break;
518
519                 if (ep)
520                         ep++;
521                 sp = ep;
522         } while (ep);
523
524         list_for_each(head, &guestdev_list) {
525                 gdev = list_entry(head, struct guestdev, root_list);
526                 pci_make_guestdev_str(gdev, path_str, GUESTDEV_STR_MAX);
527                 printk(KERN_DEBUG
528                         "PCI: %s has been reserved for guest domain.\n",
529                         path_str);
530         }
531         return 0;
532 }
533
534 arch_initcall(pci_parse_guestdev);
535
536 /* Get command line */
537 static int __init pci_guestdev_setup(char *str)
538 {
539         if (strlen(str) >= COMMAND_LINE_SIZE)
540                 return 0;
541         strlcpy(guestdev_param, str, sizeof(guestdev_param));
542         return 1;
543 }
544
545 __setup("guestdev=", pci_guestdev_setup);
546
547 /* Free sbdf and nodes */
548 static void pci_free_sbdf(struct pcidev_sbdf *sbdf)
549 {
550         struct pcidev_sbdf_node *node, *next;
551
552         node = sbdf->child;
553         while (node) {
554                 next = node->child;
555                 kfree(node);
556                 node = next;
557         }
558         /* Skip kfree(sbdf) */
559 }
560
561 /* Does PCI device belong to sub tree specified by guestdev with device path? */
562 typedef int (*pci_node_match_t)(const struct devicepath_node *gdev_node,
563                                 const struct pcidev_sbdf_node *sbdf_node,
564                                 int options);
565
566 static int pci_node_match(const struct devicepath_node *gdev_node,
567                           const struct pcidev_sbdf_node *sbdf_node,
568                           int options_unused)
569 {
570         return (gdev_node->dev == sbdf_node->dev &&
571                 gdev_node->func == sbdf_node->func);
572 }
573
574 static int pci_is_in_devicepath_sub_tree(struct guestdev *gdev,
575                                          struct pcidev_sbdf *sbdf,
576                                          pci_node_match_t match)
577 {
578         int seg, bbn;
579         struct devicepath_node *gdev_node;
580         struct pcidev_sbdf_node *sbdf_node;
581
582         if (!gdev || !sbdf)
583                 return FALSE;
584
585         BUG_ON(!(gdev->flags & GUESTDEV_FLAG_DEVICEPATH));
586
587         /* Compare seg and bbn */
588         if (gdev->u.devicepath.seg == INVALID_SEG ||
589             gdev->u.devicepath.bbn == INVALID_BBN) {
590                 if (acpi_pci_get_root_seg_bbn(gdev->u.devicepath.hid,
591                     gdev->u.devicepath.uid, &seg, &bbn)) {
592                         gdev->u.devicepath.seg = seg;
593                         gdev->u.devicepath.bbn = bbn;
594                 } else
595                         return FALSE;
596         }
597
598         if (gdev->u.devicepath.seg != sbdf->seg ||
599             gdev->u.devicepath.bbn != sbdf->bus)
600                 return FALSE;
601
602         gdev_node = gdev->u.devicepath.child;
603         sbdf_node = sbdf->child;
604
605         /* Compare dev and func */
606         while (gdev_node) {
607                 if (!sbdf_node)
608                         return FALSE;
609                 if (!match(gdev_node, sbdf_node, gdev->options))
610                         return FALSE;
611                 gdev_node = gdev_node->child;
612                 sbdf_node = sbdf_node->child;
613         }
614         return TRUE;
615 }
616
617 /* Get sbdf from device */
618 static int pci_get_sbdf_from_pcidev(
619         struct pci_dev *dev, struct pcidev_sbdf *sbdf)
620 {
621         struct pcidev_sbdf_node *node;
622
623         if (!dev)
624                 return FALSE;
625
626         for(;;) {
627                 node = kzalloc(sizeof(*node), GFP_KERNEL);
628                 if (!node) {
629                         pr_err("PCI: failed to allocate memory\n");
630                         goto err_end;
631                 }
632                 node->dev = PCI_SLOT(dev->devfn);
633                 node->func = PCI_FUNC(dev->devfn);
634
635                 if (!sbdf->child)
636                         sbdf->child = node;
637                 else {
638                         node->child = sbdf->child;
639                         sbdf->child = node;
640                 }
641                 if (!dev->bus)
642                         goto err_end;
643                 if (!dev->bus->self)
644                         break;
645                 dev = dev->bus->self;
646         }
647         if (sscanf(dev_name(&dev->dev), "%04x:%02x", &sbdf->seg, &sbdf->bus) != 2)
648                 goto err_end;
649         return TRUE;
650
651 err_end:
652         pci_free_sbdf(sbdf);
653         return FALSE;
654 }
655
656 /* Does PCI device belong to sub tree specified by guestdev with sbdf? */
657 typedef int (*pci_sbdf_match_t)(const struct guestdev *gdev,
658                                 const  struct pci_dev *dev);
659
660 static int pci_sbdf_match(const struct guestdev *gdev,
661                           const struct pci_dev *dev)
662 {
663         int seg, bus;
664
665         if (sscanf(dev_name(&dev->dev), "%04x:%02x", &seg, &bus) != 2)
666                 return FALSE;
667
668         return gdev->u.sbdf.seg == seg &&
669                 gdev->u.sbdf.bus == bus &&
670                 gdev->u.sbdf.dev == PCI_SLOT(dev->devfn) &&
671                 gdev->u.sbdf.func == PCI_FUNC(dev->devfn);
672 }
673
674 static int pci_is_in_sbdf_sub_tree(struct guestdev *gdev, struct pci_dev *dev,
675                                    pci_sbdf_match_t match)
676 {
677         BUG_ON(!(gdev->flags & GUESTDEV_FLAG_SBDF));
678         for (;;) {
679                 if (match(gdev, dev))
680                         return TRUE;
681                 if (!dev->bus || !dev->bus->self)
682                         break;
683                 dev = dev->bus->self;
684         }
685         return FALSE;
686 }
687
688 /* Does PCI device belong to sub tree specified by guestdev parameter? */
689 static int __pci_is_guestdev(struct pci_dev *dev, pci_node_match_t node_match,
690                              pci_sbdf_match_t sbdf_match)
691 {
692         struct guestdev *gdev;
693         struct pcidev_sbdf pcidev_sbdf, *sbdf = NULL;
694         struct list_head *head;
695         int result = FALSE;
696
697         if (!dev)
698                 return FALSE;
699
700         list_for_each(head, &guestdev_list) {
701                 gdev = list_entry(head, struct guestdev, root_list);
702                 switch (gdev->flags & GUESTDEV_FLAG_TYPE_MASK) {
703                 case GUESTDEV_FLAG_DEVICEPATH:
704                         if (sbdf == NULL) {
705                                 sbdf = &pcidev_sbdf;
706                                 memset(sbdf, 0 ,sizeof(*sbdf));
707                                 if (!pci_get_sbdf_from_pcidev(dev, sbdf))
708                                         goto out;
709                         }
710                         if (pci_is_in_devicepath_sub_tree(gdev, sbdf,
711                                                           node_match)) {
712                                 result = TRUE;
713                                 goto out;
714                         }
715                         break;
716                 case GUESTDEV_FLAG_SBDF:
717                         if (pci_is_in_sbdf_sub_tree(gdev, dev, sbdf_match)) {
718                                 result = TRUE;
719                                 goto out;
720                         }
721                         break;
722                 default:
723                         BUG();
724                 }
725         }
726 out:
727         if (sbdf)
728                 pci_free_sbdf(sbdf);
729         return result;
730 }
731
732 int pci_is_guestdev(struct pci_dev *dev)
733 {
734         return __pci_is_guestdev(dev, pci_node_match, pci_sbdf_match);
735 }
736 EXPORT_SYMBOL_GPL(pci_is_guestdev);
737
738 static int reassign_resources;
739
740 static int __init pci_set_reassign_resources(char *str)
741 {
742         if (str && !strcmp(str, "all"))
743                 reassign_resources = -1;
744         else
745                 reassign_resources = 1;
746
747         return 1;
748 }
749 __setup("reassign_resources", pci_set_reassign_resources);
750
751 int pci_is_guestdev_to_reassign(struct pci_dev *dev)
752 {
753         if (reassign_resources < 0)
754                 return TRUE;
755         if (reassign_resources)
756                 return pci_is_guestdev(dev);
757         return FALSE;
758 }
759
760 #if defined(CONFIG_PCI_IOMULTI) || defined(CONFIG_PCI_IOMULTI_MODULE)
761 static int pci_iomul_node_match(const struct devicepath_node *gdev_node,
762                                 const struct pcidev_sbdf_node *sbdf_node,
763                                 int options)
764 {
765         return (options & GUESTDEV_OPT_IOMUL) &&
766                 ((gdev_node->child != NULL &&
767                   sbdf_node->child != NULL &&
768                   gdev_node->dev == sbdf_node->dev &&
769                   gdev_node->func == sbdf_node->func) ||
770                  (gdev_node->child == NULL &&
771                   sbdf_node->child == NULL &&
772                   gdev_node->dev == sbdf_node->dev));
773 }
774
775 static int pci_iomul_sbdf_match(const struct guestdev *gdev,
776                                 const struct pci_dev *dev)
777 {
778         int seg, bus;
779
780         if (sscanf(dev_name(&dev->dev), "%04x:%02x", &seg, &bus) != 2)
781                 return FALSE;
782
783         return (gdev->options & GUESTDEV_OPT_IOMUL) &&
784                 gdev->u.sbdf.seg == seg &&
785                 gdev->u.sbdf.bus == bus &&
786                 gdev->u.sbdf.dev == PCI_SLOT(dev->devfn);
787 }
788
789 int pci_is_iomuldev(struct pci_dev *dev)
790 {
791         return __pci_is_guestdev(dev,
792                                  pci_iomul_node_match, pci_iomul_sbdf_match);
793 }
794 #endif /* CONFIG_PCI_IOMULTI */
795
796 /* Check whether the devicepath exists under the pci root bus */
797 static int __init pci_check_devicepath_exists(
798                 struct guestdev *gdev, struct pci_bus *bus)
799 {
800         struct devicepath_node *node;
801         struct pci_dev *dev;
802
803         BUG_ON(!(gdev->flags & GUESTDEV_FLAG_DEVICEPATH));
804
805         node = gdev->u.devicepath.child;
806         while (node) {
807                 if (!bus)
808                         return FALSE;
809                 dev = pci_get_slot(bus, PCI_DEVFN(node->dev, node->func));
810                 if (!dev)
811                         return FALSE;
812                 bus = dev->subordinate;
813                 node = node->child;
814                 pci_dev_put(dev);
815         }
816         return TRUE;
817 }
818
819 /* Check whether the guestdev exists in the PCI device tree */
820 static int __init pci_check_guestdev_exists(void)
821 {
822         struct list_head *head;
823         struct guestdev *gdev;
824         int seg, bbn;
825         struct pci_bus *bus;
826         struct pci_dev *dev;
827         char path_str[GUESTDEV_STR_MAX];
828
829         list_for_each(head, &guestdev_list) {
830                 gdev = list_entry(head, struct guestdev, root_list);
831                 switch (gdev->flags & GUESTDEV_FLAG_TYPE_MASK) {
832                 case GUESTDEV_FLAG_DEVICEPATH:
833                         if (gdev->u.devicepath.seg == INVALID_SEG ||
834                                 gdev->u.devicepath.bbn == INVALID_BBN) {
835                                 if (acpi_pci_get_root_seg_bbn(
836                                         gdev->u.devicepath.hid,
837                                         gdev->u.devicepath.uid, &seg, &bbn)) {
838                                         gdev->u.devicepath.seg = seg;
839                                         gdev->u.devicepath.bbn = bbn;
840                                 } else {
841                                         pci_make_guestdev_str(gdev,
842                                                 path_str, GUESTDEV_STR_MAX);
843                                         pr_info("PCI: "
844                                                 "device %s does not exist\n",
845                                                 path_str);
846                                         continue;
847                                 }
848                         }
849
850                         bus = pci_find_bus(gdev->u.devicepath.seg,
851                                                 gdev->u.devicepath.bbn);
852                         if (!bus || !pci_check_devicepath_exists(gdev, bus)) {
853                                 pci_make_guestdev_str(gdev, path_str,
854                                         GUESTDEV_STR_MAX);
855                                 pr_info("PCI: device %s does not exist\n",
856                                         path_str);
857                         }
858                         break;
859                 case GUESTDEV_FLAG_SBDF:
860                         bus = pci_find_bus(gdev->u.sbdf.seg, gdev->u.sbdf.bus);
861                         if (bus) {
862                                 dev = pci_get_slot(bus,
863                                         PCI_DEVFN(gdev->u.sbdf.dev,
864                                                         gdev->u.sbdf.func));
865                                 if (dev) {
866                                         pci_dev_put(dev);
867                                         continue;
868                                 }
869                         }
870                         pci_make_guestdev_str(gdev, path_str, GUESTDEV_STR_MAX);
871                         pr_info("PCI: device %s does not exist\n", path_str);
872                         break;
873                 default:
874                         BUG();
875                 }
876         }
877         return 0;
878 }
879
880 fs_initcall(pci_check_guestdev_exists);
881