hotplug.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 173 行

C
173
字号
#include <linux/pci.h>#include <linux/module.h>#include "pci.h"#undef DEBUG#ifdef DEBUG#define DBG(x...) printk(x)#else#define DBG(x...)#endifint pci_hotplug (struct device *dev, char **envp, int num_envp,		 char *buffer, int buffer_size){	struct pci_dev *pdev;	char *scratch;	int i = 0;	int length = 0;	if (!dev)		return -ENODEV;	pdev = to_pci_dev(dev);	if (!pdev)		return -ENODEV;	scratch = buffer;	/* stuff we want to pass to /sbin/hotplug */	envp[i++] = scratch;	length += scnprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",			    pdev->class);	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	++length;	scratch += length;	envp[i++] = scratch;	length += scnprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",			    pdev->vendor, pdev->device);	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	++length;	scratch += length;	envp[i++] = scratch;	length += scnprintf (scratch, buffer_size - length,			    "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,			    pdev->subsystem_device);	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	++length;	scratch += length;	envp[i++] = scratch;	length += scnprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",			    pci_name(pdev));	if ((buffer_size - length <= 0) || (i >= num_envp))		return -ENOMEM;	envp[i] = NULL;	return 0;}static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent){	struct list_head *ln;	struct pci_dev *dev;	struct pci_dev_wrapped wrapped_dev;	int result = 0;	DBG("scanning bus %02x\n", wrapped_bus->bus->number);	if (fn->pre_visit_pci_bus) {		result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);		if (result)			return result;	}	ln = wrapped_bus->bus->devices.next; 	while (ln != &wrapped_bus->bus->devices) {		dev = pci_dev_b(ln);		ln = ln->next;		memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));		wrapped_dev.dev = dev;		result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);		if (result)			return result;	}	if (fn->post_visit_pci_bus)		result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);	return result;}static int pci_visit_bridge (struct pci_visit * fn,			     struct pci_dev_wrapped *wrapped_dev,			     struct pci_bus_wrapped *wrapped_parent){	struct pci_bus *bus;	struct pci_bus_wrapped wrapped_bus;	int result = 0;	DBG("scanning bridge %02x, %02x\n", PCI_SLOT(wrapped_dev->dev->devfn),	    PCI_FUNC(wrapped_dev->dev->devfn));	if (fn->visit_pci_dev) {		result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);		if (result)			return result;	}	bus = wrapped_dev->dev->subordinate;	if (bus) {		memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));		wrapped_bus.bus = bus;		result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);	}	return result;}/** * pci_visit_dev - scans the pci buses. * Every bus and every function is presented to a custom * function that can act upon it. */int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,		  struct pci_bus_wrapped *wrapped_parent){	struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;	int result = 0;	if (!dev)		return 0;	if (fn->pre_visit_pci_dev) {		result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);		if (result)			return result;	}	switch (dev->class >> 8) {		case PCI_CLASS_BRIDGE_PCI:			result = pci_visit_bridge(fn, wrapped_dev,						  wrapped_parent);			if (result)				return result;			break;		default:			DBG("scanning device %02x, %02x\n",			    PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));			if (fn->visit_pci_dev) {				result = fn->visit_pci_dev (wrapped_dev,							    wrapped_parent);				if (result)					return result;			}	}	if (fn->post_visit_pci_dev)		result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);	return result;}EXPORT_SYMBOL(pci_visit_dev);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?