2 * Copyright (c) 2008, 2009 NEC Corporation.
3 * Copyright (c) 2009 Isaku Yamahata
4 * VA Linux Systems Japan K.K.
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.
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
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.
20 #include <linux/kernel.h>
21 #include <linux/list.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>
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
39 #define GUESTDEV_FLAG_TYPE_MASK 0x3
40 #define GUESTDEV_FLAG_DEVICEPATH 0x1
41 #define GUESTDEV_FLAG_SBDF 0x2
43 #define GUESTDEV_OPT_IOMUL 0x1
48 struct list_head root_list;
51 char hid[HID_LEN + 1];
52 char uid[UID_LEN + 1];
55 struct devicepath_node *child;
66 struct devicepath_node {
69 struct devicepath_node *child;
75 struct pcidev_sbdf_node *child;
78 struct pcidev_sbdf_node {
81 struct pcidev_sbdf_node *child;
84 static char __initdata guestdev_param[COMMAND_LINE_SIZE];
85 static LIST_HEAD(guestdev_list);
88 static int __init pci_get_hid_uid(char *str, char *hid, char *uid)
102 if (len <= 0 || HID_LEN < len)
105 strlcpy(hid, sp, len);
107 if (*ep == '-') { /* no uid */
113 ep = strchr(sp, '-');
115 ep = strchr(sp, '\0');
119 if (len <= 0 || UID_LEN < len)
122 strlcpy(uid, sp, len);
129 /* Get device and function */
130 static int __init pci_get_dev_func(char *str, int *dev, int *func)
132 if (sscanf(str, "%02x.%01x", dev, func) != 2)
135 if (*dev < 0 || DEV_NUM_MAX < *dev)
138 if (*func < 0 || FUNC_NUM_MAX < *func)
147 /* Check extended guestdev parameter format error */
148 static int __init pci_check_extended_guestdev_format(char *str)
153 /* Check extended format */
154 if (strpbrk(str, "(|)") == NULL)
162 /* Check nesting error */
166 /* Check position of '(' is head or
167 previos charactor of '(' is not '-'. */
168 if (p == str || *(p - 1) != '-')
172 /* Check nesting error */
176 /* Check next charactor of ')' is not '\0' */
177 if (*(p + 1) != '\0')
181 /* Check position of '|' is outside of '(' and ')' */
190 /* Check number of '(' and ')' are not equal */
196 pr_err("PCI: The format of the guestdev parameter is illegal. [%s]\n",
201 /* Make guestdev strings */
202 static void pci_make_guestdev_str(struct guestdev *gdev,
203 char *gdev_str, int buf_size)
205 struct devicepath_node *node;
208 switch (gdev->flags & GUESTDEV_FLAG_TYPE_MASK) {
209 case GUESTDEV_FLAG_DEVICEPATH:
210 memset(gdev_str, 0, buf_size);
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);
217 count = snprintf(gdev_str, buf_size, "%s",
218 gdev->u.devicepath.hid);
222 node = gdev->u.devicepath.child;
228 count = snprintf(gdev_str, buf_size, "-%02x.%01x",
229 node->dev, node->func);
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);
245 /* Free guestdev and nodes */
246 static void __init pci_free_guestdev(struct guestdev *gdev)
248 struct devicepath_node *node, *next;
252 if (gdev->flags & GUESTDEV_FLAG_DEVICEPATH) {
253 node = gdev->u.devicepath.child;
260 list_del(&gdev->root_list);
264 /* Copy guestdev and nodes */
265 struct guestdev __init *pci_copy_guestdev(struct guestdev *gdev_src)
267 struct guestdev *gdev;
268 struct devicepath_node *node, *node_src, *node_upper;
270 BUG_ON(!(gdev_src->flags & GUESTDEV_FLAG_DEVICEPATH));
272 gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);
274 goto allocate_err_end;
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;
286 node_src = gdev_src->u.devicepath.child;
288 node = kzalloc(sizeof(*node), GFP_KERNEL);
290 goto allocate_err_end;
291 node->dev = node_src->dev;
292 node->func = node_src->func;
294 gdev->u.devicepath.child = node;
296 node_upper->child = node;
298 node_src = node_src->child;
305 pci_free_guestdev(gdev);
306 pr_err("PCI: failed to allocate memory\n");
310 /* Make guestdev from path strings */
311 static int __init pci_make_devicepath_guestdev(char *path_str, int options)
313 char hid[HID_LEN + 1], uid[UID_LEN + 1];
315 struct guestdev *gdev, *gdev_org;
316 struct devicepath_node *node, *node_tmp;
317 int dev, func, ret_val;
320 gdev = gdev_org = NULL;
322 /* Look for end of hid:uid'-' */
323 ep = strchr(sp, '-');
324 /* Only hid, uid. (No dev, func) */
328 memset(hid, 0 ,sizeof(hid));
329 memset(uid, 0, sizeof(uid));
330 if (!pci_get_hid_uid(sp, hid, uid))
333 gdev_org = kzalloc(sizeof(*gdev_org), GFP_KERNEL);
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;
351 if (strchr(sp, '|')) {
352 gdev = pci_copy_guestdev(gdev_org);
360 if (gdev && pci_get_dev_func(sp, &dev, &func)) {
361 node = kzalloc(sizeof(*node), GFP_KERNEL);
363 goto allocate_err_end;
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;
372 node_tmp->child = node;
374 gdev->u.devicepath.child = node;
376 pr_err("PCI: Can't obtain dev# and #func# from %s.\n",
379 if (gdev == gdev_org)
381 pci_free_guestdev(gdev);
385 ep = strpbrk(sp, "-|)");
387 ep = strchr(sp, '\0');
388 /* Is *ep '|' OR ')' OR '\0' ? */
391 list_add_tail(&gdev->root_list, &guestdev_list);
393 /* Between '|' and '|' ? */
394 if (strchr(ep + 1, '|')) {
395 gdev = pci_copy_guestdev(gdev_org);
412 } while (*ep != '\0');
417 pr_err("PCI: The format of the guestdev parameter is illegal. [%s]\n",
423 pr_err("PCI: failed to allocate memory\n");
428 if (gdev_org && (gdev_org != gdev))
429 pci_free_guestdev(gdev_org);
431 pci_free_guestdev(gdev);
435 static int __init pci_make_sbdf_guestdev(char* str, int options)
437 struct guestdev *gdev;
438 int seg, bus, dev, func;
440 if (sscanf(str, "%x:%x:%x.%x", &seg, &bus, &dev, &func) != 4) {
442 if (sscanf(str, "%x:%x.%x", &bus, &dev, &func) != 3)
445 gdev = kmalloc(sizeof(*gdev), GFP_KERNEL);
447 pr_err("PCI: failed to allocate memory\n");
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);
461 static int __init pci_parse_options(const char *str)
468 ep = strchr(str, '+');
470 ep = '\0'; /* Chop */
472 if (!strcmp(str, "iomul"))
473 options |= GUESTDEV_OPT_IOMUL;
480 /* Parse guestdev parameter */
481 static int __init pci_parse_guestdev(void)
486 struct list_head *head;
487 struct guestdev *gdev;
488 char path_str[GUESTDEV_STR_MAX];
491 len = strlen(guestdev_param);
498 ep = strchr(sp, ',');
503 op = strchr(sp, '+');
504 if (op && (!ep || op < ep)) {
505 options = pci_parse_options(op);
506 *op = '\0'; /* Chop */
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(
513 if (ret_val && ret_val != -EINVAL)
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);
528 "PCI: %s has been reserved for guest domain.\n",
534 arch_initcall(pci_parse_guestdev);
536 /* Get command line */
537 static int __init pci_guestdev_setup(char *str)
539 if (strlen(str) >= COMMAND_LINE_SIZE)
541 strlcpy(guestdev_param, str, sizeof(guestdev_param));
545 __setup("guestdev=", pci_guestdev_setup);
547 /* Free sbdf and nodes */
548 static void pci_free_sbdf(struct pcidev_sbdf *sbdf)
550 struct pcidev_sbdf_node *node, *next;
558 /* Skip kfree(sbdf) */
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,
566 static int pci_node_match(const struct devicepath_node *gdev_node,
567 const struct pcidev_sbdf_node *sbdf_node,
570 return (gdev_node->dev == sbdf_node->dev &&
571 gdev_node->func == sbdf_node->func);
574 static int pci_is_in_devicepath_sub_tree(struct guestdev *gdev,
575 struct pcidev_sbdf *sbdf,
576 pci_node_match_t match)
579 struct devicepath_node *gdev_node;
580 struct pcidev_sbdf_node *sbdf_node;
585 BUG_ON(!(gdev->flags & GUESTDEV_FLAG_DEVICEPATH));
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;
598 if (gdev->u.devicepath.seg != sbdf->seg ||
599 gdev->u.devicepath.bbn != sbdf->bus)
602 gdev_node = gdev->u.devicepath.child;
603 sbdf_node = sbdf->child;
605 /* Compare dev and func */
609 if (!match(gdev_node, sbdf_node, gdev->options))
611 gdev_node = gdev_node->child;
612 sbdf_node = sbdf_node->child;
617 /* Get sbdf from device */
618 static int pci_get_sbdf_from_pcidev(
619 struct pci_dev *dev, struct pcidev_sbdf *sbdf)
621 struct pcidev_sbdf_node *node;
627 node = kzalloc(sizeof(*node), GFP_KERNEL);
629 pr_err("PCI: failed to allocate memory\n");
632 node->dev = PCI_SLOT(dev->devfn);
633 node->func = PCI_FUNC(dev->devfn);
638 node->child = sbdf->child;
645 dev = dev->bus->self;
647 if (sscanf(dev_name(&dev->dev), "%04x:%02x", &sbdf->seg, &sbdf->bus) != 2)
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);
660 static int pci_sbdf_match(const struct guestdev *gdev,
661 const struct pci_dev *dev)
665 if (sscanf(dev_name(&dev->dev), "%04x:%02x", &seg, &bus) != 2)
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);
674 static int pci_is_in_sbdf_sub_tree(struct guestdev *gdev, struct pci_dev *dev,
675 pci_sbdf_match_t match)
677 BUG_ON(!(gdev->flags & GUESTDEV_FLAG_SBDF));
679 if (match(gdev, dev))
681 if (!dev->bus || !dev->bus->self)
683 dev = dev->bus->self;
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)
692 struct guestdev *gdev;
693 struct pcidev_sbdf pcidev_sbdf, *sbdf = NULL;
694 struct list_head *head;
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:
706 memset(sbdf, 0 ,sizeof(*sbdf));
707 if (!pci_get_sbdf_from_pcidev(dev, sbdf))
710 if (pci_is_in_devicepath_sub_tree(gdev, sbdf,
716 case GUESTDEV_FLAG_SBDF:
717 if (pci_is_in_sbdf_sub_tree(gdev, dev, sbdf_match)) {
732 int pci_is_guestdev(struct pci_dev *dev)
734 return __pci_is_guestdev(dev, pci_node_match, pci_sbdf_match);
736 EXPORT_SYMBOL_GPL(pci_is_guestdev);
738 static int reassign_resources;
740 static int __init pci_set_reassign_resources(char *str)
742 if (str && !strcmp(str, "all"))
743 reassign_resources = -1;
745 reassign_resources = 1;
749 __setup("reassign_resources", pci_set_reassign_resources);
751 int pci_is_guestdev_to_reassign(struct pci_dev *dev)
753 if (reassign_resources < 0)
755 if (reassign_resources)
756 return pci_is_guestdev(dev);
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,
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));
775 static int pci_iomul_sbdf_match(const struct guestdev *gdev,
776 const struct pci_dev *dev)
780 if (sscanf(dev_name(&dev->dev), "%04x:%02x", &seg, &bus) != 2)
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);
789 int pci_is_iomuldev(struct pci_dev *dev)
791 return __pci_is_guestdev(dev,
792 pci_iomul_node_match, pci_iomul_sbdf_match);
794 #endif /* CONFIG_PCI_IOMULTI */
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)
800 struct devicepath_node *node;
803 BUG_ON(!(gdev->flags & GUESTDEV_FLAG_DEVICEPATH));
805 node = gdev->u.devicepath.child;
809 dev = pci_get_slot(bus, PCI_DEVFN(node->dev, node->func));
812 bus = dev->subordinate;
819 /* Check whether the guestdev exists in the PCI device tree */
820 static int __init pci_check_guestdev_exists(void)
822 struct list_head *head;
823 struct guestdev *gdev;
827 char path_str[GUESTDEV_STR_MAX];
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;
841 pci_make_guestdev_str(gdev,
842 path_str, GUESTDEV_STR_MAX);
844 "device %s does not exist\n",
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,
855 pr_info("PCI: device %s does not exist\n",
859 case GUESTDEV_FLAG_SBDF:
860 bus = pci_find_bus(gdev->u.sbdf.seg, gdev->u.sbdf.bus);
862 dev = pci_get_slot(bus,
863 PCI_DEVFN(gdev->u.sbdf.dev,
870 pci_make_guestdev_str(gdev, path_str, GUESTDEV_STR_MAX);
871 pr_info("PCI: device %s does not exist\n", path_str);
880 fs_initcall(pci_check_guestdev_exists);