|
|
1.1 root 1: /* pci-scan.c: Linux PCI network adapter support code. */
2: /*
3: Originally written 1999-2003 by Donald Becker.
4:
5: This software may be used and distributed according to the terms
6: of the GNU General Public License (GPL), incorporated herein by
7: reference. Drivers interacting with these functions are derivative
8: works and thus also must be licensed under the GPL and include an explicit
9: GPL notice.
10:
11: This code provides common scan and activate functions for PCI network
12: interfaces.
13:
14: The author may be reached as [email protected], or
15: Donald Becker
16: Scyld Computing Corporation
17: 914 Bay Ridge Road, Suite 220
18: Annapolis MD 21403
19:
20: Other contributers:
21: */
22: static const char version[] =
23: "pci-scan.c:v1.12 7/30/2003 Donald Becker <[email protected]>"
24: " http://www.scyld.com/linux/drivers.html\n";
25:
26: /* A few user-configurable values that may be modified when a module. */
27:
28: static int msg_level = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
29: static int min_pci_latency = 32;
30:
31: #if ! defined(__KERNEL__)
32: #define __KERNEL__ 1
33: #endif
1.1.1.2 ! root 34: #if !defined(__OPTIMIZE__) && /* Mach glue, we think this is ok now: */ 0
1.1 root 35: #warning You must compile this file with the correct options!
36: #warning See the last lines of the source file.
37: #error You must compile this driver with the proper options, including "-O".
38: #endif
39:
40: #if defined(MODULE) && ! defined(EXPORT_SYMTAB)
41: #define EXPORT_SYMTAB
42: #endif
43:
44: #include <linux/config.h>
45: #if defined(CONFIG_SMP) && ! defined(__SMP__)
46: #define __SMP__
47: #endif
48: #if defined(MODULE) && defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
49: #define MODVERSIONS
50: #endif
51:
52: #include <linux/version.h>
53: #if defined(MODVERSIONS)
54: #include <linux/modversions.h>
55: #endif
56: #if LINUX_VERSION_CODE < 0x20500 && defined(MODVERSIONS)
57: /* Another interface semantics screw-up. */
58: #include <linux/module.h>
59: #include <linux/modversions.h>
60: #else
61: #include <linux/module.h>
62: #endif
63:
64: #include <linux/kernel.h>
65: #include <linux/mm.h>
66: #include <linux/errno.h>
67: #include <linux/types.h>
68: #include <linux/pci.h>
69: #include <linux/ioport.h>
70: #if LINUX_VERSION_CODE >= 0x20300
71: /* Bogus change in the middle of a "stable" kernel series.
72: Also, in 2.4.7+ slab must come before interrupt.h to avoid breakage. */
73: #include <linux/slab.h>
74: #else
75: #include <linux/malloc.h>
76: #endif
77: #include <asm/io.h>
78: #include "pci-scan.h"
79: #include "kern_compat.h"
80: #if defined(CONFIG_APM) && LINUX_VERSION_CODE < 0x20400
81: #include <linux/apm_bios.h>
82: #endif
83: #ifdef CONFIG_PM
84: /* New in 2.4 kernels, pointlessly incompatible with earlier APM. */
85: #include <linux/pm.h>
86: #endif
87:
88: #if (LINUX_VERSION_CODE >= 0x20100) && defined(MODULE)
89: char kernel_version[] = UTS_RELEASE;
90: #endif
91: #if (LINUX_VERSION_CODE < 0x20100)
92: #define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
93: #define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
94: #define PCI_CAP_ID_PM 0x01 /* Power Management */
95: #endif
96:
97: int (*register_hotswap_hook)(struct drv_id_info *did);
98: void (*unregister_hotswap_hook)(struct drv_id_info *did);
99:
100: #if LINUX_VERSION_CODE > 0x20118 && defined(MODULE)
101: MODULE_LICENSE("GPL");
102: MODULE_PARM(msg_level, "i");
103: MODULE_PARM(min_pci_latency, "i");
104: MODULE_PARM_DESC(msg_level, "Enable additional status messages (0-7)");
105: MODULE_PARM_DESC(min_pci_latency,
106: "Minimum value for the PCI Latency Timer settings");
107: #if defined(EXPORT_SYMTAB)
108: EXPORT_SYMBOL_NOVERS(pci_drv_register);
109: EXPORT_SYMBOL_NOVERS(pci_drv_unregister);
110: EXPORT_SYMBOL_NOVERS(acpi_wake);
111: EXPORT_SYMBOL_NOVERS(acpi_set_pwr_state);
112: EXPORT_SYMBOL_NOVERS(register_hotswap_hook);
113: EXPORT_SYMBOL_NOVERS(unregister_hotswap_hook);
114: #endif
115: #endif
116:
117: /* List of registered drivers. */
118: static struct drv_id_info *drv_list;
119: /* List of detected PCI devices, for APM events. */
120: static struct dev_info {
121: struct dev_info *next;
122: void *dev;
123: struct drv_id_info *drv_id;
124: int flags;
125: } *dev_list;
126:
127: /*
128: This code is not intended to support every configuration.
129: It is intended to minimize duplicated code by providing the functions
130: needed in almost every PCI driver.
131:
132: The "no kitchen sink" policy:
133: Additional features and code will be added to this module only if more
134: than half of the drivers for common hardware would benefit from the feature.
135: */
136:
137: /*
138: Ideally we would detect and number all cards of a type (e.g. network) in
139: PCI slot order.
140: But that does not work with hot-swap card, CardBus cards and added drivers.
141: So instead we detect just the each chip table in slot order.
142:
143: This routine takes a PCI ID table, scans the PCI bus, and calls the
144: associated attach/probe1 routine with the hardware already activated and
145: single I/O or memory address already mapped.
146:
147: This routine will later be supplemented with CardBus and hot-swap PCI
148: support using the same table. Thus the pci_chip_tbl[] should not be
149: marked as __initdata.
150: */
151:
152: #if LINUX_VERSION_CODE >= 0x20200
153: /* Grrrr.. complex abstaction layers with negative benefit. */
154: int pci_drv_register(struct drv_id_info *drv_id, void *initial_device)
155: {
156: int chip_idx, cards_found = 0;
157: struct pci_dev *pdev = NULL;
158: struct pci_id_info *pci_tbl = drv_id->pci_dev_tbl;
159: struct drv_id_info *drv;
160: void *newdev;
161:
162:
163: /* Ignore a double-register attempt. */
164: for (drv = drv_list; drv; drv = drv->next)
165: if (drv == drv_id)
166: return -EBUSY;
167:
168: while ((pdev = pci_find_class(drv_id->pci_class, pdev)) != 0) {
169: u32 pci_id, pci_subsys_id, pci_class_rev;
170: u16 pci_command, new_command;
171: int pci_flags;
172: long pciaddr; /* Bus address. */
173: long ioaddr; /* Mapped address for this processor. */
174:
175: pci_read_config_dword(pdev, PCI_VENDOR_ID, &pci_id);
176: /* Offset 0x2c is PCI_SUBSYSTEM_ID aka PCI_SUBSYSTEM_VENDOR_ID. */
177: pci_read_config_dword(pdev, 0x2c, &pci_subsys_id);
178: pci_read_config_dword(pdev, PCI_REVISION_ID, &pci_class_rev);
179:
180: if (msg_level > 3)
181: printk(KERN_DEBUG "PCI ID %8.8x subsystem ID is %8.8x.\n",
182: pci_id, pci_subsys_id);
183: for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
184: struct pci_id_info *chip = &pci_tbl[chip_idx];
185: if ((pci_id & chip->id.pci_mask) == chip->id.pci
186: && (pci_subsys_id&chip->id.subsystem_mask) == chip->id.subsystem
187: && (pci_class_rev&chip->id.revision_mask) == chip->id.revision)
188: break;
189: }
190: if (pci_tbl[chip_idx].name == 0) /* Compiled out! */
191: continue;
192:
193: pci_flags = pci_tbl[chip_idx].pci_flags;
194: #if LINUX_VERSION_CODE >= 0x2030C
195: /* Wow. A oversized, hard-to-use abstraction. Bogus. */
196: pciaddr = pdev->resource[(pci_flags >> 4) & 7].start;
197: #else
198: pciaddr = pdev->base_address[(pci_flags >> 4) & 7];
199: #if defined(__alpha__) /* Really any machine with 64 bit addressing. */
200: if (pci_flags & PCI_ADDR_64BITS)
201: pciaddr |= ((long)pdev->base_address[((pci_flags>>4)&7)+ 1]) << 32;
202: #endif
203: #endif
204: if (msg_level > 2)
205: printk(KERN_INFO "Found %s at PCI address %#lx, mapped IRQ %d.\n",
206: pci_tbl[chip_idx].name, pciaddr, pdev->irq);
207:
208: if ( ! (pci_flags & PCI_UNUSED_IRQ) &&
209: (pdev->irq == 0 || pdev->irq == 255)) {
210: if (pdev->bus->number == 32) /* Broken CardBus activation. */
211: printk(KERN_WARNING "Resources for CardBus device '%s' have"
212: " not been allocated.\n"
213: KERN_WARNING "Activation has been delayed.\n",
214: pci_tbl[chip_idx].name);
215: else
216: printk(KERN_WARNING "PCI device '%s' was not assigned an "
217: "IRQ.\n"
218: KERN_WARNING "It will not be activated.\n",
219: pci_tbl[chip_idx].name);
220: continue;
221: }
222: if ((pci_flags & PCI_BASE_ADDRESS_SPACE_IO)) {
223: ioaddr = pciaddr & PCI_BASE_ADDRESS_IO_MASK;
224: if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
225: continue;
226: } else if ((ioaddr = (long)ioremap(pciaddr & PCI_BASE_ADDRESS_MEM_MASK,
227: pci_tbl[chip_idx].io_size)) == 0) {
228: printk(KERN_INFO "Failed to map PCI address %#lx for device "
229: "'%s'.\n", pciaddr, pci_tbl[chip_idx].name);
230: continue;
231: }
232: if ( ! (pci_flags & PCI_NO_ACPI_WAKE))
233: acpi_wake(pdev);
234: pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
235: new_command = pci_command | (pci_flags & 7);
236: if (pci_command != new_command) {
237: printk(KERN_INFO " The PCI BIOS has not enabled the"
238: " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n",
239: pdev->bus->number, pdev->devfn, pci_command, new_command);
240: pci_write_config_word(pdev, PCI_COMMAND, new_command);
241: }
242:
243: newdev = drv_id->probe1(pdev, initial_device,
244: ioaddr, pdev->irq, chip_idx, cards_found);
245: if (newdev == NULL)
246: continue;
247: initial_device = 0;
248: cards_found++;
249: if (pci_flags & PCI_COMMAND_MASTER) {
250: pci_set_master(pdev);
251: if ( ! (pci_flags & PCI_NO_MIN_LATENCY)) {
252: u8 pci_latency;
253: pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
254: if (pci_latency < min_pci_latency) {
255: printk(KERN_INFO " PCI latency timer (CFLT) is "
256: "unreasonably low at %d. Setting to %d clocks.\n",
257: pci_latency, min_pci_latency);
258: pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
259: min_pci_latency);
260: }
261: }
262: }
263: {
264: struct dev_info *devp =
265: kmalloc(sizeof(struct dev_info), GFP_KERNEL);
266: if (devp == 0)
267: continue;
268: devp->next = dev_list;
269: devp->dev = newdev;
270: devp->drv_id = drv_id;
271: dev_list = devp;
272: }
273: }
274:
275: if (((drv_id->flags & PCI_HOTSWAP)
276: && register_hotswap_hook && (*register_hotswap_hook)(drv_id) == 0)
277: || cards_found) {
278: MOD_INC_USE_COUNT;
279: drv_id->next = drv_list;
280: drv_list = drv_id;
281: return 0;
282: } else
283: return -ENODEV;
284: }
285: #else
286: int pci_drv_register(struct drv_id_info *drv_id, void *initial_device)
287: {
288: int pci_index, cards_found = 0;
289: unsigned char pci_bus, pci_device_fn;
290: struct pci_dev *pdev;
291: struct pci_id_info *pci_tbl = drv_id->pci_dev_tbl;
292: void *newdev;
293:
294: if ( ! pcibios_present())
295: return -ENODEV;
296:
297: for (pci_index = 0; pci_index < 0xff; pci_index++) {
298: u32 pci_id, subsys_id, pci_class_rev;
299: u16 pci_command, new_command;
300: int chip_idx, irq, pci_flags;
301: long pciaddr;
302: long ioaddr;
303: u32 pci_busaddr;
304: u8 pci_irq_line;
305:
306: if (pcibios_find_class (drv_id->pci_class, pci_index,
307: &pci_bus, &pci_device_fn)
308: != PCIBIOS_SUCCESSFUL)
309: break;
310: pcibios_read_config_dword(pci_bus, pci_device_fn,
311: PCI_VENDOR_ID, &pci_id);
312: /* Offset 0x2c is PCI_SUBSYSTEM_ID aka PCI_SUBSYSTEM_VENDOR_ID. */
313: pcibios_read_config_dword(pci_bus, pci_device_fn, 0x2c, &subsys_id);
314: pcibios_read_config_dword(pci_bus, pci_device_fn,
315: PCI_REVISION_ID, &pci_class_rev);
316:
317: for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
318: struct pci_id_info *chip = &pci_tbl[chip_idx];
319: if ((pci_id & chip->id.pci_mask) == chip->id.pci
320: && (subsys_id & chip->id.subsystem_mask) == chip->id.subsystem
321: && (pci_class_rev&chip->id.revision_mask) == chip->id.revision)
322: break;
323: }
324: if (pci_tbl[chip_idx].name == 0) /* Compiled out! */
325: continue;
326:
327: pci_flags = pci_tbl[chip_idx].pci_flags;
328: pdev = pci_find_slot(pci_bus, pci_device_fn);
329: pcibios_read_config_byte(pci_bus, pci_device_fn,
330: PCI_INTERRUPT_LINE, &pci_irq_line);
331: irq = pci_irq_line;
332: pcibios_read_config_dword(pci_bus, pci_device_fn,
333: ((pci_flags >> 2) & 0x1C) + 0x10,
334: &pci_busaddr);
335: pciaddr = pci_busaddr;
336: #if defined(__alpha__)
337: if (pci_flags & PCI_ADDR_64BITS) {
338: pcibios_read_config_dword(pci_bus, pci_device_fn,
339: ((pci_flags >> 2) & 0x1C) + 0x14,
340: &pci_busaddr);
341: pciaddr |= ((long)pci_busaddr)<<32;
342: }
343: #endif
344:
345: if (msg_level > 2)
346: printk(KERN_INFO "Found %s at PCI address %#lx, IRQ %d.\n",
347: pci_tbl[chip_idx].name, pciaddr, irq);
348:
349: if ( ! (pci_flags & PCI_UNUSED_IRQ) &&
350: (irq == 0 || irq >= 16)) {
351: if (pci_bus == 32) /* Broken CardBus activation. */
352: printk(KERN_WARNING "Resources for CardBus device '%s' have"
353: " not been allocated.\n"
354: KERN_WARNING "It will not be activated.\n",
355: pci_tbl[chip_idx].name);
356: else
357: printk(KERN_WARNING "PCI device '%s' was not assigned an "
358: "IRQ.\n"
359: KERN_WARNING "It will not be activated.\n",
360: pci_tbl[chip_idx].name);
361: continue;
362: }
363:
364: if ((pciaddr & PCI_BASE_ADDRESS_SPACE_IO)) {
365: ioaddr = pciaddr & PCI_BASE_ADDRESS_IO_MASK;
366: if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
367: continue;
368: } else if ((ioaddr = (long)ioremap(pciaddr & PCI_BASE_ADDRESS_MEM_MASK,
369: pci_tbl[chip_idx].io_size)) == 0) {
370: printk(KERN_INFO "Failed to map PCI address %#lx.\n",
371: pciaddr);
372: continue;
373: }
374:
375: if ( ! (pci_flags & PCI_NO_ACPI_WAKE))
376: acpi_wake(pdev);
377: pcibios_read_config_word(pci_bus, pci_device_fn,
378: PCI_COMMAND, &pci_command);
379: new_command = pci_command | (pci_flags & 7);
380: if (pci_command != new_command) {
381: printk(KERN_INFO " The PCI BIOS has not enabled the"
382: " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n",
383: pci_bus, pci_device_fn, pci_command, new_command);
384: pcibios_write_config_word(pci_bus, pci_device_fn,
385: PCI_COMMAND, new_command);
386: }
387:
388: newdev = drv_id->probe1(pdev, initial_device,
389: ioaddr, irq, chip_idx, cards_found);
390:
391: if (newdev && (pci_flags & PCI_COMMAND_MASTER) &&
392: ! (pci_flags & PCI_NO_MIN_LATENCY)) {
393: u8 pci_latency;
394: pcibios_read_config_byte(pci_bus, pci_device_fn,
395: PCI_LATENCY_TIMER, &pci_latency);
396: if (pci_latency < min_pci_latency) {
397: printk(KERN_INFO " PCI latency timer (CFLT) is "
398: "unreasonably low at %d. Setting to %d clocks.\n",
399: pci_latency, min_pci_latency);
400: pcibios_write_config_byte(pci_bus, pci_device_fn,
401: PCI_LATENCY_TIMER, min_pci_latency);
402: }
403: }
404: if (newdev) {
405: struct dev_info *devp =
406: kmalloc(sizeof(struct dev_info), GFP_KERNEL);
407: if (devp) {
408: devp->next = dev_list;
409: devp->dev = newdev;
410: devp->drv_id = drv_id;
411: dev_list = devp;
412: }
413: }
414: initial_device = 0;
415: cards_found++;
416: }
417:
418: if (((drv_id->flags & PCI_HOTSWAP)
419: && register_hotswap_hook && (*register_hotswap_hook)(drv_id) == 0)
420: || cards_found) {
421: MOD_INC_USE_COUNT;
422: drv_id->next = drv_list;
423: drv_list = drv_id;
424: return 0;
425: } else
426: return cards_found ? 0 : -ENODEV;
427: }
428: #endif
429:
430: void pci_drv_unregister(struct drv_id_info *drv_id)
431: {
432: struct drv_id_info **drvp;
433: struct dev_info **devip = &dev_list;
434:
435: if (unregister_hotswap_hook)
436: (*unregister_hotswap_hook)(drv_id);
437:
438: for (drvp = &drv_list; *drvp; drvp = &(*drvp)->next)
439: if (*drvp == drv_id) {
440: *drvp = (*drvp)->next;
441: MOD_DEC_USE_COUNT;
442: break;
443: }
444: while (*devip) {
445: struct dev_info *thisdevi = *devip;
446: if (thisdevi->drv_id == drv_id) {
447: *devip = thisdevi->next;
448: kfree(thisdevi);
449: } else
450: devip = &(*devip)->next;
451: }
452:
453: return;
454: }
455:
456: #if LINUX_VERSION_CODE < 0x20400
457: /*
458: Search PCI configuration space for the specified capability registers.
459: Return the index, or 0 on failure.
460: The 2.4 kernel now includes this function.
461: */
462: int pci_find_capability(struct pci_dev *pdev, int findtype)
463: {
464: u16 pci_status, cap_type;
465: u8 pci_cap_idx;
466: int cap_idx;
467:
468: pci_read_config_word(pdev, PCI_STATUS, &pci_status);
469: if ( ! (pci_status & PCI_STATUS_CAP_LIST))
470: return 0;
471: pci_read_config_byte(pdev, PCI_CAPABILITY_LIST, &pci_cap_idx);
472: cap_idx = pci_cap_idx;
473: for (cap_idx = pci_cap_idx; cap_idx; cap_idx = (cap_type >> 8) & 0xff) {
474: pci_read_config_word(pdev, cap_idx, &cap_type);
475: if ((cap_type & 0xff) == findtype)
476: return cap_idx;
477: }
478: return 0;
479: }
480: #endif
481:
482: /* Change a device from D3 (sleep) to D0 (active).
483: Return the old power state.
484: This is more complicated than you might first expect since most cards
485: forget all PCI config info during the transition! */
486: int acpi_wake(struct pci_dev *pdev)
487: {
488: u32 base[5], romaddr;
489: u16 pci_command, pwr_command;
490: u8 pci_latency, pci_cacheline, irq;
491: int i, pwr_cmd_idx = pci_find_capability(pdev, PCI_CAP_ID_PM);
492:
493: if (pwr_cmd_idx == 0)
494: return 0;
495: pci_read_config_word(pdev, pwr_cmd_idx + 4, &pwr_command);
496: if ((pwr_command & 3) == 0)
497: return 0;
498: pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
499: for (i = 0; i < 5; i++)
500: pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + i*4,
501: &base[i]);
502: pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &romaddr);
503: pci_read_config_byte( pdev, PCI_LATENCY_TIMER, &pci_latency);
504: pci_read_config_byte( pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
505: pci_read_config_byte( pdev, PCI_INTERRUPT_LINE, &irq);
506:
507: pci_write_config_word(pdev, pwr_cmd_idx + 4, 0x0000);
508: for (i = 0; i < 5; i++)
509: if (base[i])
510: pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0 + i*4,
511: base[i]);
512: pci_write_config_dword(pdev, PCI_ROM_ADDRESS, romaddr);
513: pci_write_config_byte( pdev, PCI_INTERRUPT_LINE, irq);
514: pci_write_config_byte( pdev, PCI_CACHE_LINE_SIZE, pci_cacheline);
515: pci_write_config_byte( pdev, PCI_LATENCY_TIMER, pci_latency);
516: pci_write_config_word( pdev, PCI_COMMAND, pci_command | 5);
517: return pwr_command & 3;
518: }
519:
520: int acpi_set_pwr_state(struct pci_dev *pdev, enum acpi_pwr_state new_state)
521: {
522: u16 pwr_command;
523: int pwr_cmd_idx = pci_find_capability(pdev, PCI_CAP_ID_PM);
524:
525: if (pwr_cmd_idx == 0)
526: return 0;
527: pci_read_config_word(pdev, pwr_cmd_idx + 4, &pwr_command);
528: if ((pwr_command & 3) == ACPI_D3 && new_state != ACPI_D3)
529: acpi_wake(pdev); /* The complicated sequence. */
530: pci_write_config_word(pdev, pwr_cmd_idx + 4,
531: (pwr_command & ~3) | new_state);
532: return pwr_command & 3;
533: }
534:
535: #if defined(CONFIG_PM)
536: static int handle_pm_event(struct pm_dev *dev, int event, void *data)
537: {
538: static int down = 0;
539: struct dev_info *devi;
540: int pwr_cmd = -1;
541:
542: if (msg_level > 1)
543: printk(KERN_DEBUG "pci-scan: Handling power event %d for driver "
544: "list %s...\n",
545: event, drv_list->name);
546: switch (event) {
547: case PM_SUSPEND:
548: if (down) {
549: printk(KERN_DEBUG "pci-scan: Received extra suspend event\n");
550: break;
551: }
552: down = 1;
553: for (devi = dev_list; devi; devi = devi->next)
554: if (devi->drv_id->pwr_event)
555: devi->drv_id->pwr_event(devi->dev, DRV_SUSPEND);
556: break;
557: case PM_RESUME:
558: if (!down) {
559: printk(KERN_DEBUG "pci-scan: Received bogus resume event\n");
560: break;
561: }
562: for (devi = dev_list; devi; devi = devi->next) {
563: if (devi->drv_id->pwr_event) {
564: if (msg_level > 3)
565: printk(KERN_DEBUG "pci-scan: Calling resume for %s "
566: "device.\n", devi->drv_id->name);
567: devi->drv_id->pwr_event(devi->dev, DRV_RESUME);
568: }
569: }
570: down = 0;
571: break;
572: case PM_SET_WAKEUP: pwr_cmd = DRV_PWR_WakeOn; break;
573: case PM_EJECT: pwr_cmd = DRV_DETACH; break;
574: default:
575: printk(KERN_DEBUG "pci-scan: Unknown power management event %d.\n",
576: event);
577: }
578: if (pwr_cmd >= 0)
579: for (devi = dev_list; devi; devi = devi->next)
580: if (devi->drv_id->pwr_event)
581: devi->drv_id->pwr_event(devi->dev, pwr_cmd);
582:
583: return 0;
584: }
585:
586: #elif defined(CONFIG_APM) && LINUX_VERSION_CODE < 0x20400
587: static int handle_apm_event(apm_event_t event)
588: {
589: static int down = 0;
590: struct dev_info *devi;
591:
592: if (msg_level > 1)
593: printk(KERN_DEBUG "pci-scan: Handling APM event %d for driver "
594: "list %s...\n",
595: event, drv_list->name);
596: return 0;
597: switch (event) {
598: case APM_SYS_SUSPEND:
599: case APM_USER_SUSPEND:
600: if (down) {
601: printk(KERN_DEBUG "pci-scan: Received extra suspend event\n");
602: break;
603: }
604: down = 1;
605: for (devi = dev_list; devi; devi = devi->next)
606: if (devi->drv_id->pwr_event)
607: devi->drv_id->pwr_event(devi->dev, DRV_SUSPEND);
608: break;
609: case APM_NORMAL_RESUME:
610: case APM_CRITICAL_RESUME:
611: if (!down) {
612: printk(KERN_DEBUG "pci-scan: Received bogus resume event\n");
613: break;
614: }
615: for (devi = dev_list; devi; devi = devi->next)
616: if (devi->drv_id->pwr_event)
617: devi->drv_id->pwr_event(devi->dev, DRV_RESUME);
618: down = 0;
619: break;
620: }
621: return 0;
622: }
623: #endif /* CONFIG_APM */
624:
625: #ifdef MODULE
626: int init_module(void)
627: {
628: if (msg_level) /* Emit version even if no cards detected. */
629: printk(KERN_INFO "%s", version);
630:
631: #if defined(CONFIG_PM)
632: pm_register(PM_PCI_DEV, 0, &handle_pm_event);
633: #elif defined(CONFIG_APM) && LINUX_VERSION_CODE < 0x20400
634: apm_register_callback(&handle_apm_event);
635: #endif
636: return 0;
637: }
638: void cleanup_module(void)
639: {
640: #if defined(CONFIG_PM)
641: pm_unregister_all(&handle_pm_event);
642: #elif defined(CONFIG_APM) && LINUX_VERSION_CODE < 0x20400
643: apm_unregister_callback(&handle_apm_event);
644: #endif
645: if (dev_list != NULL)
646: printk(KERN_WARNING "pci-scan: Unfreed device references.\n");
647: return;
648: }
649: #endif
650:
651:
652: /*
653: * Local variables:
654: * compile-command: "gcc -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -Wall -Wstrict-prototypes -O6 -c pci-scan.c"
655: * c-indent-level: 4
656: * c-basic-offset: 4
657: * tab-width: 4
658: * End:
659: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.