diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-14 20:07:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-14 20:07:57 -0400 |
commit | 754a264c42178b85125a071299bb900b615c853b (patch) | |
tree | 8cfc6d85e6725f90672b75314064ead9fd62e3c6 /drivers | |
parent | f9814802dfec8feaf51ba873d7eac1a05ee65842 (diff) | |
parent | 4f705ae3e94ffaafe8d35f71ff4d5c499bb06814 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (158 commits)
commit 4f705ae3e94ffaafe8d35f71ff4d5c499bb06814
Author: Bjorn Helgaas <bjorn.helgaas@hp.com>
Date: Mon Apr 3 17:09:22 2006 -0700
[PATCH] DMI: move dmi_scan.c from arch/i386 to drivers/firmware/
dmi_scan.c is arch-independent and is used by i386, x86_64, and ia64.
Currently all three arches compile it from arch/i386, which means that ia64
and x86_64 depend on things in arch/i386 that they wouldn't otherwise care
about.
This is simply "mv arch/i386/kernel/dmi_scan.c drivers/firmware/" (removing
trailing whitespace) and the associated Makefile changes. All three
architectures already set CONFIG_DMI in their top-level Kconfig files.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Andi Kleen <ak@muc.de>
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Andrey Panin <pazke@orbita1.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/bus.c | 5 | ||||
-rw-r--r-- | drivers/base/class.c | 13 | ||||
-rw-r--r-- | drivers/base/dd.c | 2 | ||||
-rw-r--r-- | drivers/base/power/suspend.c | 12 | ||||
-rw-r--r-- | drivers/firmware/Makefile | 3 | ||||
-rw-r--r-- | drivers/firmware/dmi_scan.c | 358 | ||||
-rw-r--r-- | drivers/md/md.c | 1 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 6 | ||||
-rw-r--r-- | drivers/pci/pci.c | 6 | ||||
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 7 |
10 files changed, 396 insertions, 17 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 48718b7f4fa0..76656acd00d4 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
188 | up(&dev->sem); | 188 | up(&dev->sem); |
189 | if (dev->parent) | 189 | if (dev->parent) |
190 | up(&dev->parent->sem); | 190 | up(&dev->parent->sem); |
191 | |||
192 | if (err > 0) /* success */ | ||
193 | err = count; | ||
194 | else if (err == 0) /* driver didn't accept device */ | ||
195 | err = -ENODEV; | ||
191 | } | 196 | } |
192 | put_device(dev); | 197 | put_device(dev); |
193 | put_bus(bus); | 198 | put_bus(bus); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index df7fdabd0730..0e71dff327cd 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -562,14 +562,13 @@ int class_device_add(struct class_device *class_dev) | |||
562 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 562 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); |
563 | 563 | ||
564 | /* notify any interfaces this device is now here */ | 564 | /* notify any interfaces this device is now here */ |
565 | if (parent_class) { | 565 | down(&parent_class->sem); |
566 | down(&parent_class->sem); | 566 | list_add_tail(&class_dev->node, &parent_class->children); |
567 | list_add_tail(&class_dev->node, &parent_class->children); | 567 | list_for_each_entry(class_intf, &parent_class->interfaces, node) { |
568 | list_for_each_entry(class_intf, &parent_class->interfaces, node) | 568 | if (class_intf->add) |
569 | if (class_intf->add) | 569 | class_intf->add(class_dev, class_intf); |
570 | class_intf->add(class_dev, class_intf); | ||
571 | up(&parent_class->sem); | ||
572 | } | 570 | } |
571 | up(&parent_class->sem); | ||
573 | 572 | ||
574 | register_done: | 573 | register_done: |
575 | if (error) { | 574 | if (error) { |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 730a9ce0a14a..889c71111239 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -209,7 +209,7 @@ static void __device_release_driver(struct device * dev) | |||
209 | sysfs_remove_link(&dev->kobj, "driver"); | 209 | sysfs_remove_link(&dev->kobj, "driver"); |
210 | klist_remove(&dev->knode_driver); | 210 | klist_remove(&dev->knode_driver); |
211 | 211 | ||
212 | if (dev->bus->remove) | 212 | if (dev->bus && dev->bus->remove) |
213 | dev->bus->remove(dev); | 213 | dev->bus->remove(dev); |
214 | else if (drv->remove) | 214 | else if (drv->remove) |
215 | drv->remove(dev); | 215 | drv->remove(dev); |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index bdb60663f2ef..662209d3f42d 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -10,6 +10,8 @@ | |||
10 | 10 | ||
11 | #include <linux/vt_kern.h> | 11 | #include <linux/vt_kern.h> |
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/kallsyms.h> | ||
14 | #include <linux/pm.h> | ||
13 | #include "../base.h" | 15 | #include "../base.h" |
14 | #include "power.h" | 16 | #include "power.h" |
15 | 17 | ||
@@ -58,6 +60,7 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
58 | if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { | 60 | if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { |
59 | dev_dbg(dev, "suspending\n"); | 61 | dev_dbg(dev, "suspending\n"); |
60 | error = dev->bus->suspend(dev, state); | 62 | error = dev->bus->suspend(dev, state); |
63 | suspend_report_result(dev->bus->suspend, error); | ||
61 | } | 64 | } |
62 | up(&dev->sem); | 65 | up(&dev->sem); |
63 | return error; | 66 | return error; |
@@ -169,3 +172,12 @@ int device_power_down(pm_message_t state) | |||
169 | 172 | ||
170 | EXPORT_SYMBOL_GPL(device_power_down); | 173 | EXPORT_SYMBOL_GPL(device_power_down); |
171 | 174 | ||
175 | void __suspend_report_result(const char *function, void *fn, int ret) | ||
176 | { | ||
177 | if (ret) { | ||
178 | printk(KERN_ERR "%s(): ", function); | ||
179 | print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn); | ||
180 | printk("%d\n", ret); | ||
181 | } | ||
182 | } | ||
183 | EXPORT_SYMBOL_GPL(__suspend_report_result); | ||
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 85429979d0db..98e395f4bb29 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | obj-$(CONFIG_EDD) += edd.o | 4 | obj-$(CONFIG_DMI) += dmi_scan.o |
5 | obj-$(CONFIG_EDD) += edd.o | ||
5 | obj-$(CONFIG_EFI_VARS) += efivars.o | 6 | obj-$(CONFIG_EFI_VARS) += efivars.o |
6 | obj-$(CONFIG_EFI_PCDP) += pcdp.o | 7 | obj-$(CONFIG_EFI_PCDP) += pcdp.o |
7 | obj-$(CONFIG_DELL_RBU) += dell_rbu.o | 8 | obj-$(CONFIG_DELL_RBU) += dell_rbu.o |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c new file mode 100644 index 000000000000..948bd7e1445a --- /dev/null +++ b/drivers/firmware/dmi_scan.c | |||
@@ -0,0 +1,358 @@ | |||
1 | #include <linux/types.h> | ||
2 | #include <linux/string.h> | ||
3 | #include <linux/init.h> | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/dmi.h> | ||
6 | #include <linux/efi.h> | ||
7 | #include <linux/bootmem.h> | ||
8 | #include <linux/slab.h> | ||
9 | #include <asm/dmi.h> | ||
10 | |||
11 | static char * __init dmi_string(struct dmi_header *dm, u8 s) | ||
12 | { | ||
13 | u8 *bp = ((u8 *) dm) + dm->length; | ||
14 | char *str = ""; | ||
15 | |||
16 | if (s) { | ||
17 | s--; | ||
18 | while (s > 0 && *bp) { | ||
19 | bp += strlen(bp) + 1; | ||
20 | s--; | ||
21 | } | ||
22 | |||
23 | if (*bp != 0) { | ||
24 | str = dmi_alloc(strlen(bp) + 1); | ||
25 | if (str != NULL) | ||
26 | strcpy(str, bp); | ||
27 | else | ||
28 | printk(KERN_ERR "dmi_string: out of memory.\n"); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | return str; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * We have to be cautious here. We have seen BIOSes with DMI pointers | ||
37 | * pointing to completely the wrong place for example | ||
38 | */ | ||
39 | static int __init dmi_table(u32 base, int len, int num, | ||
40 | void (*decode)(struct dmi_header *)) | ||
41 | { | ||
42 | u8 *buf, *data; | ||
43 | int i = 0; | ||
44 | |||
45 | buf = dmi_ioremap(base, len); | ||
46 | if (buf == NULL) | ||
47 | return -1; | ||
48 | |||
49 | data = buf; | ||
50 | |||
51 | /* | ||
52 | * Stop when we see all the items the table claimed to have | ||
53 | * OR we run off the end of the table (also happens) | ||
54 | */ | ||
55 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { | ||
56 | struct dmi_header *dm = (struct dmi_header *)data; | ||
57 | /* | ||
58 | * We want to know the total length (formated area and strings) | ||
59 | * before decoding to make sure we won't run off the table in | ||
60 | * dmi_decode or dmi_string | ||
61 | */ | ||
62 | data += dm->length; | ||
63 | while ((data - buf < len - 1) && (data[0] || data[1])) | ||
64 | data++; | ||
65 | if (data - buf < len - 1) | ||
66 | decode(dm); | ||
67 | data += 2; | ||
68 | i++; | ||
69 | } | ||
70 | dmi_iounmap(buf, len); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int __init dmi_checksum(u8 *buf) | ||
75 | { | ||
76 | u8 sum = 0; | ||
77 | int a; | ||
78 | |||
79 | for (a = 0; a < 15; a++) | ||
80 | sum += buf[a]; | ||
81 | |||
82 | return sum == 0; | ||
83 | } | ||
84 | |||
85 | static char *dmi_ident[DMI_STRING_MAX]; | ||
86 | static LIST_HEAD(dmi_devices); | ||
87 | |||
88 | /* | ||
89 | * Save a DMI string | ||
90 | */ | ||
91 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | ||
92 | { | ||
93 | char *p, *d = (char*) dm; | ||
94 | |||
95 | if (dmi_ident[slot]) | ||
96 | return; | ||
97 | |||
98 | p = dmi_string(dm, d[string]); | ||
99 | if (p == NULL) | ||
100 | return; | ||
101 | |||
102 | dmi_ident[slot] = p; | ||
103 | } | ||
104 | |||
105 | static void __init dmi_save_devices(struct dmi_header *dm) | ||
106 | { | ||
107 | int i, count = (dm->length - sizeof(struct dmi_header)) / 2; | ||
108 | struct dmi_device *dev; | ||
109 | |||
110 | for (i = 0; i < count; i++) { | ||
111 | char *d = (char *)(dm + 1) + (i * 2); | ||
112 | |||
113 | /* Skip disabled device */ | ||
114 | if ((*d & 0x80) == 0) | ||
115 | continue; | ||
116 | |||
117 | dev = dmi_alloc(sizeof(*dev)); | ||
118 | if (!dev) { | ||
119 | printk(KERN_ERR "dmi_save_devices: out of memory.\n"); | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | dev->type = *d++ & 0x7f; | ||
124 | dev->name = dmi_string(dm, *d); | ||
125 | dev->device_data = NULL; | ||
126 | |||
127 | list_add(&dev->list, &dmi_devices); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void __init dmi_save_ipmi_device(struct dmi_header *dm) | ||
132 | { | ||
133 | struct dmi_device *dev; | ||
134 | void * data; | ||
135 | |||
136 | data = dmi_alloc(dm->length); | ||
137 | if (data == NULL) { | ||
138 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | memcpy(data, dm, dm->length); | ||
143 | |||
144 | dev = dmi_alloc(sizeof(*dev)); | ||
145 | if (!dev) { | ||
146 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | dev->type = DMI_DEV_TYPE_IPMI; | ||
151 | dev->name = "IPMI controller"; | ||
152 | dev->device_data = data; | ||
153 | |||
154 | list_add(&dev->list, &dmi_devices); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Process a DMI table entry. Right now all we care about are the BIOS | ||
159 | * and machine entries. For 2.5 we should pull the smbus controller info | ||
160 | * out of here. | ||
161 | */ | ||
162 | static void __init dmi_decode(struct dmi_header *dm) | ||
163 | { | ||
164 | switch(dm->type) { | ||
165 | case 0: /* BIOS Information */ | ||
166 | dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); | ||
167 | dmi_save_ident(dm, DMI_BIOS_VERSION, 5); | ||
168 | dmi_save_ident(dm, DMI_BIOS_DATE, 8); | ||
169 | break; | ||
170 | case 1: /* System Information */ | ||
171 | dmi_save_ident(dm, DMI_SYS_VENDOR, 4); | ||
172 | dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); | ||
173 | dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); | ||
174 | dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); | ||
175 | break; | ||
176 | case 2: /* Base Board Information */ | ||
177 | dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); | ||
178 | dmi_save_ident(dm, DMI_BOARD_NAME, 5); | ||
179 | dmi_save_ident(dm, DMI_BOARD_VERSION, 6); | ||
180 | break; | ||
181 | case 10: /* Onboard Devices Information */ | ||
182 | dmi_save_devices(dm); | ||
183 | break; | ||
184 | case 38: /* IPMI Device Information */ | ||
185 | dmi_save_ipmi_device(dm); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | static int __init dmi_present(char __iomem *p) | ||
190 | { | ||
191 | u8 buf[15]; | ||
192 | memcpy_fromio(buf, p, 15); | ||
193 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | ||
194 | u16 num = (buf[13] << 8) | buf[12]; | ||
195 | u16 len = (buf[7] << 8) | buf[6]; | ||
196 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | ||
197 | (buf[9] << 8) | buf[8]; | ||
198 | |||
199 | /* | ||
200 | * DMI version 0.0 means that the real version is taken from | ||
201 | * the SMBIOS version, which we don't know at this point. | ||
202 | */ | ||
203 | if (buf[14] != 0) | ||
204 | printk(KERN_INFO "DMI %d.%d present.\n", | ||
205 | buf[14] >> 4, buf[14] & 0xF); | ||
206 | else | ||
207 | printk(KERN_INFO "DMI present.\n"); | ||
208 | if (dmi_table(base,len, num, dmi_decode) == 0) | ||
209 | return 0; | ||
210 | } | ||
211 | return 1; | ||
212 | } | ||
213 | |||
214 | void __init dmi_scan_machine(void) | ||
215 | { | ||
216 | char __iomem *p, *q; | ||
217 | int rc; | ||
218 | |||
219 | if (efi_enabled) { | ||
220 | if (efi.smbios == EFI_INVALID_TABLE_ADDR) | ||
221 | goto out; | ||
222 | |||
223 | /* This is called as a core_initcall() because it isn't | ||
224 | * needed during early boot. This also means we can | ||
225 | * iounmap the space when we're done with it. | ||
226 | */ | ||
227 | p = dmi_ioremap(efi.smbios, 32); | ||
228 | if (p == NULL) | ||
229 | goto out; | ||
230 | |||
231 | rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ | ||
232 | dmi_iounmap(p, 32); | ||
233 | if (!rc) | ||
234 | return; | ||
235 | } | ||
236 | else { | ||
237 | /* | ||
238 | * no iounmap() for that ioremap(); it would be a no-op, but | ||
239 | * it's so early in setup that sucker gets confused into doing | ||
240 | * what it shouldn't if we actually call it. | ||
241 | */ | ||
242 | p = dmi_ioremap(0xF0000, 0x10000); | ||
243 | if (p == NULL) | ||
244 | goto out; | ||
245 | |||
246 | for (q = p; q < p + 0x10000; q += 16) { | ||
247 | rc = dmi_present(q); | ||
248 | if (!rc) | ||
249 | return; | ||
250 | } | ||
251 | } | ||
252 | out: printk(KERN_INFO "DMI not present or invalid.\n"); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * dmi_check_system - check system DMI data | ||
257 | * @list: array of dmi_system_id structures to match against | ||
258 | * | ||
259 | * Walk the blacklist table running matching functions until someone | ||
260 | * returns non zero or we hit the end. Callback function is called for | ||
261 | * each successfull match. Returns the number of matches. | ||
262 | */ | ||
263 | int dmi_check_system(struct dmi_system_id *list) | ||
264 | { | ||
265 | int i, count = 0; | ||
266 | struct dmi_system_id *d = list; | ||
267 | |||
268 | while (d->ident) { | ||
269 | for (i = 0; i < ARRAY_SIZE(d->matches); i++) { | ||
270 | int s = d->matches[i].slot; | ||
271 | if (s == DMI_NONE) | ||
272 | continue; | ||
273 | if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) | ||
274 | continue; | ||
275 | /* No match */ | ||
276 | goto fail; | ||
277 | } | ||
278 | count++; | ||
279 | if (d->callback && d->callback(d)) | ||
280 | break; | ||
281 | fail: d++; | ||
282 | } | ||
283 | |||
284 | return count; | ||
285 | } | ||
286 | EXPORT_SYMBOL(dmi_check_system); | ||
287 | |||
288 | /** | ||
289 | * dmi_get_system_info - return DMI data value | ||
290 | * @field: data index (see enum dmi_filed) | ||
291 | * | ||
292 | * Returns one DMI data value, can be used to perform | ||
293 | * complex DMI data checks. | ||
294 | */ | ||
295 | char *dmi_get_system_info(int field) | ||
296 | { | ||
297 | return dmi_ident[field]; | ||
298 | } | ||
299 | EXPORT_SYMBOL(dmi_get_system_info); | ||
300 | |||
301 | /** | ||
302 | * dmi_find_device - find onboard device by type/name | ||
303 | * @type: device type or %DMI_DEV_TYPE_ANY to match all device types | ||
304 | * @desc: device name string or %NULL to match all | ||
305 | * @from: previous device found in search, or %NULL for new search. | ||
306 | * | ||
307 | * Iterates through the list of known onboard devices. If a device is | ||
308 | * found with a matching @vendor and @device, a pointer to its device | ||
309 | * structure is returned. Otherwise, %NULL is returned. | ||
310 | * A new search is initiated by passing %NULL to the @from argument. | ||
311 | * If @from is not %NULL, searches continue from next device. | ||
312 | */ | ||
313 | struct dmi_device * dmi_find_device(int type, const char *name, | ||
314 | struct dmi_device *from) | ||
315 | { | ||
316 | struct list_head *d, *head = from ? &from->list : &dmi_devices; | ||
317 | |||
318 | for(d = head->next; d != &dmi_devices; d = d->next) { | ||
319 | struct dmi_device *dev = list_entry(d, struct dmi_device, list); | ||
320 | |||
321 | if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) && | ||
322 | ((name == NULL) || (strcmp(dev->name, name) == 0))) | ||
323 | return dev; | ||
324 | } | ||
325 | |||
326 | return NULL; | ||
327 | } | ||
328 | EXPORT_SYMBOL(dmi_find_device); | ||
329 | |||
330 | /** | ||
331 | * dmi_get_year - Return year of a DMI date | ||
332 | * @field: data index (like dmi_get_system_info) | ||
333 | * | ||
334 | * Returns -1 when the field doesn't exist. 0 when it is broken. | ||
335 | */ | ||
336 | int dmi_get_year(int field) | ||
337 | { | ||
338 | int year; | ||
339 | char *s = dmi_get_system_info(field); | ||
340 | |||
341 | if (!s) | ||
342 | return -1; | ||
343 | if (*s == '\0') | ||
344 | return 0; | ||
345 | s = strrchr(s, '/'); | ||
346 | if (!s) | ||
347 | return 0; | ||
348 | |||
349 | s += 1; | ||
350 | year = simple_strtoul(s, NULL, 0); | ||
351 | if (year && year < 100) { /* 2-digit year */ | ||
352 | year += 1900; | ||
353 | if (year < 1996) /* no dates < spec 1.0 */ | ||
354 | year += 100; | ||
355 | } | ||
356 | |||
357 | return year; | ||
358 | } | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 1ed5152db450..434ca39d19c1 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -163,6 +163,7 @@ void md_new_event(mddev_t *mddev) | |||
163 | { | 163 | { |
164 | atomic_inc(&md_event_count); | 164 | atomic_inc(&md_event_count); |
165 | wake_up(&md_event_waiters); | 165 | wake_up(&md_event_waiters); |
166 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
166 | } | 167 | } |
167 | EXPORT_SYMBOL_GPL(md_new_event); | 168 | EXPORT_SYMBOL_GPL(md_new_event); |
168 | 169 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index f22f69ac6445..1456759936c5 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -271,10 +271,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) | |||
271 | struct pci_driver * drv = pci_dev->driver; | 271 | struct pci_driver * drv = pci_dev->driver; |
272 | int i = 0; | 272 | int i = 0; |
273 | 273 | ||
274 | if (drv && drv->suspend) | 274 | if (drv && drv->suspend) { |
275 | i = drv->suspend(pci_dev, state); | 275 | i = drv->suspend(pci_dev, state); |
276 | else | 276 | suspend_report_result(drv->suspend, i); |
277 | } else { | ||
277 | pci_save_state(pci_dev); | 278 | pci_save_state(pci_dev); |
279 | } | ||
278 | return i; | 280 | return i; |
279 | } | 281 | } |
280 | 282 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index bea1ad1ad5ba..042fa5265cf6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -307,9 +307,11 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
307 | * Can enter D0 from any state, but if we can only go deeper | 307 | * Can enter D0 from any state, but if we can only go deeper |
308 | * to sleep if we're already in a low power state | 308 | * to sleep if we're already in a low power state |
309 | */ | 309 | */ |
310 | if (state != PCI_D0 && dev->current_state > state) | 310 | if (state != PCI_D0 && dev->current_state > state) { |
311 | printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n", | ||
312 | __FUNCTION__, pci_name(dev), state, dev->current_state); | ||
311 | return -EINVAL; | 313 | return -EINVAL; |
312 | else if (dev->current_state == state) | 314 | } else if (dev->current_state == state) |
313 | return 0; /* we're already there */ | 315 | return 0; /* we're already there */ |
314 | 316 | ||
315 | /* find PCI PM capability in list */ | 317 | /* find PCI PM capability in list */ |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 0d2193b69235..66b78404ab34 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -213,11 +213,9 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
213 | 213 | ||
214 | if (hcd->driver->suspend) { | 214 | if (hcd->driver->suspend) { |
215 | retval = hcd->driver->suspend(hcd, message); | 215 | retval = hcd->driver->suspend(hcd, message); |
216 | if (retval) { | 216 | suspend_report_result(hcd->driver->suspend, retval); |
217 | dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n", | 217 | if (retval) |
218 | retval); | ||
219 | goto done; | 218 | goto done; |
220 | } | ||
221 | } | 219 | } |
222 | synchronize_irq(dev->irq); | 220 | synchronize_irq(dev->irq); |
223 | 221 | ||
@@ -263,6 +261,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
263 | * some device state (e.g. as part of clock reinit). | 261 | * some device state (e.g. as part of clock reinit). |
264 | */ | 262 | */ |
265 | retval = pci_set_power_state (dev, PCI_D3hot); | 263 | retval = pci_set_power_state (dev, PCI_D3hot); |
264 | suspend_report_result(pci_set_power_state, retval); | ||
266 | if (retval == 0) { | 265 | if (retval == 0) { |
267 | int wake = device_can_wakeup(&hcd->self.root_hub->dev); | 266 | int wake = device_can_wakeup(&hcd->self.root_hub->dev); |
268 | 267 | ||