ia64/linux-2.6.18-xen.hg

view drivers/pci/reserve.c @ 895:20be7f6d414a

pci/guestdev, iomul: use strlcpy()

use strlcpy() to make them robust.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 04 10:45:49 2009 +0100 (2009-06-04)
parents c7c92f868aa1
children
line source
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright (c) 2009 Isaku Yamahata
17 * VA Linux Systems Japan K.K.
18 *
19 */
21 #include <linux/kernel.h>
22 #include <linux/pci.h>
24 #include <asm/setup.h>
26 static char pci_reserve_param[COMMAND_LINE_SIZE];
28 /* pci_reserve= [PCI]
29 * Format: [<sbdf>[+IO<size>][+MEM<size>]][,<sbdf>...]
30 * Format of sbdf: [<segment>:]<bus>:<dev>.<func>
31 */
32 static int pci_reserve_parse_size(const char *str,
33 unsigned long *io_size,
34 unsigned long *mem_size)
35 {
36 if (sscanf(str, "io%lx", io_size) == 1 ||
37 sscanf(str, "IO%lx", io_size) == 1)
38 return 0;
40 if (sscanf(str, "mem%lx", mem_size) == 1 ||
41 sscanf(str, "MEM%lx", mem_size) == 1)
42 return 0;
44 return -EINVAL;
45 }
47 static int pci_reserve_parse_one(const char *str,
48 int *seg, int *bus, int *dev, int *func,
49 unsigned long *io_size,
50 unsigned long *mem_size)
51 {
52 char *p;
54 *io_size = 0;
55 *mem_size = 0;
57 if (sscanf(str, "%x:%x:%x.%x", seg, bus, dev, func) != 4) {
58 *seg = 0;
59 if (sscanf(str, "%x:%x.%x", bus, dev, func) != 3) {
60 return -EINVAL;
61 }
62 }
64 p = strchr(str, '+');
65 if (p == NULL)
66 return -EINVAL;
67 p++;
68 if (pci_reserve_parse_size(p, io_size, mem_size))
69 return -EINVAL;
71 p = strchr(str, '+');
72 if (p != NULL) {
73 p++;
74 pci_reserve_parse_size(p, io_size, mem_size);
75 }
76 return 0;
77 }
79 static unsigned long pci_reserve_size(struct pci_bus *pbus, int flags)
80 {
81 char *sp;
82 char *ep;
84 int seg;
85 int bus;
86 int dev;
87 int func;
89 unsigned long io_size;
90 unsigned long mem_size;
92 sp = pci_reserve_param;
94 do {
95 ep = strchr(sp, ',');
96 if (ep)
97 *ep = '\0'; /* chomp */
99 if (pci_reserve_parse_one(sp, &seg, &bus, &dev, &func,
100 &io_size, &mem_size) == 0) {
101 if (pci_domain_nr(pbus) == seg &&
102 pbus->number == bus &&
103 PCI_SLOT(pbus->self->devfn) == dev &&
104 PCI_FUNC(pbus->self->devfn) == func) {
105 switch (flags) {
106 case IORESOURCE_IO:
107 return io_size;
108 case IORESOURCE_MEM:
109 return mem_size;
110 default:
111 break;
112 }
113 }
114 }
116 if (ep) {
117 *ep = ','; /* restore chomp'ed ',' for later */
118 ep++;
119 }
120 sp = ep;
121 } while (ep);
123 return 0;
124 }
126 unsigned long pci_reserve_size_io(struct pci_bus *pbus)
127 {
128 return pci_reserve_size(pbus, IORESOURCE_IO);
129 }
131 unsigned long pci_reserve_size_mem(struct pci_bus *pbus)
132 {
133 return pci_reserve_size(pbus, IORESOURCE_MEM);
134 }
136 static int __init pci_reserve_setup(char *str)
137 {
138 if (strlen(str) >= sizeof(pci_reserve_param))
139 return 0;
140 strlcpy(pci_reserve_param, str, sizeof(pci_reserve_param));
141 return 1;
142 }
143 __setup("pci_reserve=", pci_reserve_setup);