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

📄 pci_hotplug_core.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (ops->owner)							\		__MOD_DEC_USE_COUNT(ops->owner);			\	return retval;							\}GET_STATUS(power)GET_STATUS(attention)GET_STATUS(latch)GET_STATUS(adapter)static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset){	struct hotplug_slot *slot = file->private_data;	unsigned char *page;	int retval;	int len;	u8 value;	dbg(" count = %d, offset = %lld\n", count, *offset);	if (*offset < 0)		return -EINVAL;	if (count <= 0)		return 0;	if (*offset != 0)		return 0;	if (slot == NULL) {		dbg("slot == NULL???\n");		return -ENODEV;	}	page = (unsigned char *)__get_free_page(GFP_KERNEL);	if (!page)		return -ENOMEM;	retval = get_power_status (slot, &value);	if (retval)		goto exit;	len = sprintf (page, "%d\n", value);	if (copy_to_user (buf, page, len)) {		retval = -EFAULT;		goto exit;	}	*offset += len;	retval = len;exit:	free_page((unsigned long)page);	return retval;}static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset){	struct hotplug_slot *slot = file->private_data;	char *buff;	unsigned long lpower;	u8 power;	int retval = 0;	if (*offset < 0)		return -EINVAL;	if (count <= 0)		return 0;	if (*offset != 0)		return 0;	if (slot == NULL) {		dbg("slot == NULL???\n");		return -ENODEV;	}	buff = kmalloc (count + 1, GFP_KERNEL);	if (!buff)		return -ENOMEM;	memset (buff, 0x00, count + 1); 	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {		retval = -EFAULT;		goto exit;	}		lpower = simple_strtoul (buff, NULL, 10);	power = (u8)(lpower & 0xff);	dbg ("power = %d\n", power);	switch (power) {		case 0:			if (!slot->ops->disable_slot)				break;			if (slot->ops->owner)				__MOD_INC_USE_COUNT(slot->ops->owner);			retval = slot->ops->disable_slot(slot);			if (slot->ops->owner)				__MOD_DEC_USE_COUNT(slot->ops->owner);			break;		case 1:			if (!slot->ops->enable_slot)				break;			if (slot->ops->owner)				__MOD_INC_USE_COUNT(slot->ops->owner);			retval = slot->ops->enable_slot(slot);			if (slot->ops->owner)				__MOD_DEC_USE_COUNT(slot->ops->owner);			break;		default:			err ("Illegal value specified for power\n");			retval = -EFAULT;	}exit:		kfree (buff);	if (retval)		return retval;	return count;}static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset){	struct hotplug_slot *slot = file->private_data;	unsigned char *page;	int retval;	int len;	u8 value;	dbg("count = %d, offset = %lld\n", count, *offset);	if (*offset < 0)		return -EINVAL;	if (count <= 0)		return 0;	if (*offset != 0)		return 0;	if (slot == NULL) {		dbg("slot == NULL???\n");		return -ENODEV;	}	page = (unsigned char *)__get_free_page(GFP_KERNEL);	if (!page)		return -ENOMEM;	retval = get_attention_status (slot, &value);	if (retval)		goto exit;	len = sprintf (page, "%d\n", value);	if (copy_to_user (buf, page, len)) {		retval = -EFAULT;		goto exit;	}	*offset += len;	retval = len;exit:	free_page((unsigned long)page);	return retval;}static ssize_t attention_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset){	struct hotplug_slot *slot = file->private_data;	char *buff;	unsigned long lattention;	u8 attention;	int retval = 0;	if (*offset < 0)		return -EINVAL;	if (count <= 0)		return 0;	if (*offset != 0)		return 0;	if (slot == NULL) {		dbg("slot == NULL???\n");		return -ENODEV;	}	buff = kmalloc (count + 1, GFP_KERNEL);	if (!buff)		return -ENOMEM;	memset (buff, 0x00, count + 1);	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {		retval = -EFAULT;		goto exit;	}		lattention = simple_strtoul (buff, NULL, 10);	attention = (u8)(lattention & 0xff);	dbg (" - attention = %d\n", attention);	if (slot->ops->set_attention_status) {		if (slot->ops->owner)			__MOD_INC_USE_COUNT(slot->ops->owner);		retval = slot->ops->set_attention_status(slot, attention);		if (slot->ops->owner)			__MOD_DEC_USE_COUNT(slot->ops->owner);	}exit:		kfree (buff);	if (retval)		return retval;	return count;}static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset){	struct hotplug_slot *slot = file->private_data;	unsigned char *page;	int retval;	int len;	u8 value;	dbg("count = %d, offset = %lld\n", count, *offset);	if (*offset < 0)		return -EINVAL;	if (count <= 0)		return 0;	if (*offset != 0)		return 0;	if (slot == NULL) {		dbg("slot == NULL???\n");		return -ENODEV;	}	page = (unsigned char *)__get_free_page(GFP_KERNEL);	if (!page)		return -ENOMEM;	retval = get_latch_status (slot, &value);	if (retval)		goto exit;	len = sprintf (page, "%d\n", value);	if (copy_to_user (buf, page, len)) {		retval = -EFAULT;		goto exit;	}	*offset += len;	retval = len;exit:	free_page((unsigned long)page);	return retval;}static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset){	struct hotplug_slot *slot = file->private_data;	unsigned char *page;	int retval;	int len;	u8 value;	dbg("count = %d, offset = %lld\n", count, *offset);	if (*offset < 0)		return -EINVAL;	if (count <= 0)		return 0;	if (*offset != 0)		return 0;	if (slot == NULL) {		dbg("slot == NULL???\n");		return -ENODEV;	}	page = (unsigned char *)__get_free_page(GFP_KERNEL);	if (!page)		return -ENOMEM;	retval = get_adapter_status (slot, &value);	if (retval)		goto exit;	len = sprintf (page, "%d\n", value);	if (copy_to_user (buf, page, len)) {		retval = -EFAULT;		goto exit;	}	*offset += len;	retval = len;exit:	free_page((unsigned long)page);	return retval;}static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset){	struct hotplug_slot *slot = file->private_data;	char *buff;	unsigned long ltest;	u32 test;	int retval = 0;	if (*offset < 0)		return -EINVAL;	if (count <= 0)		return 0;	if (*offset != 0)		return 0;	if (slot == NULL) {		dbg("slot == NULL???\n");		return -ENODEV;	}	buff = kmalloc (count + 1, GFP_KERNEL);	if (!buff)		return -ENOMEM;	memset (buff, 0x00, count + 1);	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {		retval = -EFAULT;		goto exit;	}		ltest = simple_strtoul (buff, NULL, 10);	test = (u32)(ltest & 0xffffffff);	dbg ("test = %d\n", test);	if (slot->ops->hardware_test) {		if (slot->ops->owner)			__MOD_INC_USE_COUNT(slot->ops->owner);		retval = slot->ops->hardware_test(slot, test);		if (slot->ops->owner)			__MOD_DEC_USE_COUNT(slot->ops->owner);	}exit:		kfree (buff);	if (retval)		return retval;	return count;}static int fs_add_slot (struct hotplug_slot *slot){	struct hotplug_slot_core *core = slot->core_priv;	int result;	result = get_mount();	if (result)		return result;	core->dir_dentry = fs_create_file (slot->name,					   S_IFDIR | S_IXUGO | S_IRUGO,					   NULL, NULL, NULL);	if (core->dir_dentry != NULL) {		core->power_dentry = fs_create_file ("power",						     S_IFREG | S_IRUGO | S_IWUSR,						     core->dir_dentry, slot,						     &power_file_operations);		core->attention_dentry = fs_create_file ("attention",							 S_IFREG | S_IRUGO | S_IWUSR,							 core->dir_dentry, slot,							 &attention_file_operations);		core->latch_dentry = fs_create_file ("latch",						     S_IFREG | S_IRUGO,						     core->dir_dentry, slot,						     &latch_file_operations);		core->adapter_dentry = fs_create_file ("adapter",						       S_IFREG | S_IRUGO,						       core->dir_dentry, slot,						       &presence_file_operations);		core->test_dentry = fs_create_file ("test",						    S_IFREG | S_IRUGO | S_IWUSR,						    core->dir_dentry, slot,						    &test_file_operations);	}	return 0;}static void fs_remove_slot (struct hotplug_slot *slot){	struct hotplug_slot_core *core = slot->core_priv;	if (core->dir_dentry) {		if (core->power_dentry)			fs_remove_file (core->power_dentry);		if (core->attention_dentry)			fs_remove_file (core->attention_dentry);		if (core->latch_dentry)			fs_remove_file (core->latch_dentry);		if (core->adapter_dentry)			fs_remove_file (core->adapter_dentry);		if (core->test_dentry)			fs_remove_file (core->test_dentry);		fs_remove_file (core->dir_dentry);	}	remove_mount();}static struct hotplug_slot *get_slot_from_name (const char *name){	struct hotplug_slot *slot;	struct list_head *tmp;	list_for_each (tmp, &pci_hotplug_slot_list) {		slot = list_entry (tmp, struct hotplug_slot, slot_list);		if (strcmp(slot->name, name) == 0)			return slot;	}	return NULL;}/** * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem * @slot: pointer to the &struct hotplug_slot to register * * Registers a hotplug slot with the pci hotplug subsystem, which will allow * userspace interaction to the slot. * * Returns 0 if successful, anything else for an error. */int pci_hp_register (struct hotplug_slot *slot){	struct hotplug_slot_core *core;	int result;	if (slot == NULL)		return -ENODEV;	if ((slot->info == NULL) || (slot->ops == NULL))		return -EFAULT;	core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL);	if (!core)		return -ENOMEM;	/* make sure we have not already registered this slot */	spin_lock (&list_lock);	if (get_slot_from_name (slot->name) != NULL) {		spin_unlock (&list_lock);		kfree (core);		return -EFAULT;	}	slot->core_priv = core;	list_add (&slot->slot_list, &pci_hotplug_slot_list);	spin_unlock (&list_lock);	result = fs_add_slot (slot);	dbg ("Added slot %s to the list\n", slot->name);	return result;}/** * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem * @slot: pointer to the &struct hotplug_slot to deregister * * The @slot must have been registered with the pci hotplug subsystem * previously with a call to pci_hp_register(). * * Returns 0 if successful, anything else for an error. */int pci_hp_deregister (struct hotplug_slot *slot){	struct hotplug_slot *temp;	if (slot == NULL)		return -ENODEV;	/* make sure we have this slot in our list before trying to delete it */	spin_lock (&list_lock);	temp = get_slot_from_name (slot->name);	if (temp != slot) {		spin_unlock (&list_lock);		return -ENODEV;	}	list_del (&slot->slot_list);	spin_unlock (&list_lock);	fs_remove_slot (slot);	kfree(slot->core_priv);	dbg ("Removed slot %s from the list\n", slot->name);	return 0;}/** * pci_hp_change_slot_info - changes the slot's information structure in the core * @name: the name of the slot whose info has changed * @info: pointer to the info copy into the slot's info structure * * A slot with @name must have been registered with the pci  * hotplug subsystem previously with a call to pci_hp_register(). * * Returns 0 if successful, anything else for an error. */int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info){	struct hotplug_slot *temp;	if (info == NULL)		return -ENODEV;	spin_lock (&list_lock);	temp = get_slot_from_name (name);	if (temp == NULL) {		spin_unlock (&list_lock);		return -ENODEV;	}	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));	spin_unlock (&list_lock);	return 0;}static int __init pci_hotplug_init (void){	int result;	spin_lock_init(&mount_lock);	spin_lock_init(&list_lock);	dbg("registering filesystem.\n");	result = register_filesystem(&pcihpfs_fs_type);	if (result) {		err("register_filesystem failed with %d\n", result);		goto exit;	}	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");exit:	return result;}static void __exit pci_hotplug_exit (void){	unregister_filesystem(&pcihpfs_fs_type);}module_init(pci_hotplug_init);module_exit(pci_hotplug_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debugging mode enabled or not");EXPORT_SYMBOL_GPL(pci_hp_register);EXPORT_SYMBOL_GPL(pci_hp_deregister);EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);

⌨️ 快捷键说明

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