⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_hotplug_core.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * PCI HotPlug Controller Core * * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2001-2002 IBM Corp. * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or * NON INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Send feedback to <greg@kroah.com> * * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs * */#include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/list.h>#include <linux/pagemap.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/init.h>#include <linux/mount.h>#include <linux/namei.h>#include <linux/pci.h>#include <asm/uaccess.h>#include <linux/kobject.h>#include <linux/sysfs.h>#include "pci_hotplug.h"#define MY_NAME	"pci_hotplug"#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)/* local variables */static int debug;#define DRIVER_VERSION	"0.5"#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"#define DRIVER_DESC	"PCI Hot Plug PCI Core"//////////////////////////////////////////////////////////////////static LIST_HEAD(pci_hotplug_slot_list);struct subsystem pci_hotplug_slots_subsys;static ssize_t hotplug_slot_attr_show(struct kobject *kobj,		struct attribute *attr, char *buf){	struct hotplug_slot *slot = to_hotplug_slot(kobj);	struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);	return attribute->show ? attribute->show(slot, buf) : -EIO;}static ssize_t hotplug_slot_attr_store(struct kobject *kobj,		struct attribute *attr, const char *buf, size_t len){	struct hotplug_slot *slot = to_hotplug_slot(kobj);	struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);	return attribute->store ? attribute->store(slot, buf, len) : -EIO;}static struct sysfs_ops hotplug_slot_sysfs_ops = {	.show = hotplug_slot_attr_show,	.store = hotplug_slot_attr_store,};static void hotplug_slot_release(struct kobject *kobj){	struct hotplug_slot *slot = to_hotplug_slot(kobj);	if (slot->release)		slot->release(slot);}static struct kobj_type hotplug_slot_ktype = {	.sysfs_ops = &hotplug_slot_sysfs_ops,	.release = &hotplug_slot_release,};decl_subsys_name(pci_hotplug_slots, slots, &hotplug_slot_ktype, NULL);/* these strings match up with the values in pci_bus_speed */static char *pci_bus_speed_strings[] = {	"33 MHz PCI",		/* 0x00 */	"66 MHz PCI",		/* 0x01 */	"66 MHz PCIX", 		/* 0x02 */	"100 MHz PCIX",		/* 0x03 */	"133 MHz PCIX",		/* 0x04 */	NULL,			/* 0x05 */	NULL,			/* 0x06 */	NULL,			/* 0x07 */	NULL,			/* 0x08 */	"66 MHz PCIX 266",	/* 0x09 */	"100 MHz PCIX 266",	/* 0x0a */	"133 MHz PCIX 266",	/* 0x0b */	NULL,			/* 0x0c */	NULL,			/* 0x0d */	NULL,			/* 0x0e */	NULL,			/* 0x0f */	NULL,			/* 0x10 */	"66 MHz PCIX 533",	/* 0x11 */	"100 MHz PCIX 533",	/* 0x12 */	"133 MHz PCIX 533",	/* 0x13 */	"25 GBps PCI-E",	/* 0x14 */};#ifdef CONFIG_HOTPLUG_PCI_CPCIextern int cpci_hotplug_init(int debug);extern void cpci_hotplug_exit(void);#elsestatic inline int cpci_hotplug_init(int debug) { return 0; }static inline void cpci_hotplug_exit(void) { }#endif/* Weee, fun with macros... */#define GET_STATUS(name,type)	\static int get_##name (struct hotplug_slot *slot, type *value)		\{									\	struct hotplug_slot_ops *ops = slot->ops;			\	int retval = 0;							\	if (try_module_get(ops->owner)) {				\		if (ops->get_##name)					\			retval = ops->get_##name (slot, value);		\		else							\			*value = slot->info->name;			\		module_put(ops->owner);					\	}								\	return retval;							\}GET_STATUS(power_status, u8)GET_STATUS(attention_status, u8)GET_STATUS(latch_status, u8)GET_STATUS(adapter_status, u8)GET_STATUS(address, u32)GET_STATUS(max_bus_speed, enum pci_bus_speed)GET_STATUS(cur_bus_speed, enum pci_bus_speed)static ssize_t power_read_file (struct hotplug_slot *slot, char *buf){	int retval;	u8 value;	retval = get_power_status (slot, &value);	if (retval)		goto exit;	retval = sprintf (buf, "%d\n", value);exit:	return retval;}static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,		size_t count){	unsigned long lpower;	u8 power;	int retval = 0;	lpower = simple_strtoul (buf, NULL, 10);	power = (u8)(lpower & 0xff);	dbg ("power = %d\n", power);	if (!try_module_get(slot->ops->owner)) {		retval = -ENODEV;		goto exit;	}	switch (power) {		case 0:			if (slot->ops->disable_slot)				retval = slot->ops->disable_slot(slot);			break;		case 1:			if (slot->ops->enable_slot)				retval = slot->ops->enable_slot(slot);			break;		default:			err ("Illegal value specified for power\n");			retval = -EINVAL;	}	module_put(slot->ops->owner);exit:		if (retval)		return retval;	return count;}static struct hotplug_slot_attribute hotplug_slot_attr_power = {	.attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},	.show = power_read_file,	.store = power_write_file};static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf){	int retval;	u8 value;	retval = get_attention_status (slot, &value);	if (retval)		goto exit;	retval = sprintf (buf, "%d\n", value);exit:	return retval;}static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,		size_t count){	unsigned long lattention;	u8 attention;	int retval = 0;	lattention = simple_strtoul (buf, NULL, 10);	attention = (u8)(lattention & 0xff);	dbg (" - attention = %d\n", attention);	if (!try_module_get(slot->ops->owner)) {		retval = -ENODEV;		goto exit;	}	if (slot->ops->set_attention_status)		retval = slot->ops->set_attention_status(slot, attention);	module_put(slot->ops->owner);exit:		if (retval)		return retval;	return count;}static struct hotplug_slot_attribute hotplug_slot_attr_attention = {	.attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},	.show = attention_read_file,	.store = attention_write_file};static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf){	int retval;	u8 value;	retval = get_latch_status (slot, &value);	if (retval)		goto exit;	retval = sprintf (buf, "%d\n", value);exit:	return retval;}static struct hotplug_slot_attribute hotplug_slot_attr_latch = {	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO},	.show = latch_read_file,};static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf){	int retval;	u8 value;	retval = get_adapter_status (slot, &value);	if (retval)		goto exit;	retval = sprintf (buf, "%d\n", value);exit:	return retval;}static struct hotplug_slot_attribute hotplug_slot_attr_presence = {	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO},	.show = presence_read_file,};static ssize_t address_read_file (struct hotplug_slot *slot, char *buf){	int retval;	u32 address;	retval = get_address (slot, &address);	if (retval)		goto exit;	retval = sprintf (buf, "%04x:%02x:%02x\n",			  (address >> 16) & 0xffff,			  (address >> 8) & 0xff,			  address & 0xff);exit:	return retval;}static struct hotplug_slot_attribute hotplug_slot_attr_address = {	.attr = {.name = "address", .mode = S_IFREG | S_IRUGO},	.show = address_read_file,};static char *unknown_speed = "Unknown bus speed";static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf){	char *speed_string;	int retval;	enum pci_bus_speed value;		retval = get_max_bus_speed (slot, &value);	if (retval)		goto exit;	if (value == PCI_SPEED_UNKNOWN)		speed_string = unknown_speed;	else		speed_string = pci_bus_speed_strings[value];		retval = sprintf (buf, "%s\n", speed_string);exit:	return retval;}static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO},	.show = max_bus_speed_read_file,};static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf){	char *speed_string;	int retval;	enum pci_bus_speed value;

⌨️ 快捷键说明

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