brintos

brintos / linux-shallow public Read only

0
0
Text · 4.8 KiB · fed1360 Raw
209 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Compaq Hot Plug Controller Driver4 *5 * Copyright (C) 1995,2001 Compaq Computer Corporation6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)7 * Copyright (C) 2001 IBM Corp.8 *9 * All rights reserved.10 *11 * Send feedback to <greg@kroah.com>12 *13 */14 15#include <linux/module.h>16#include <linux/kernel.h>17#include <linux/slab.h>18#include <linux/types.h>19#include <linux/proc_fs.h>20#include <linux/workqueue.h>21#include <linux/pci.h>22#include <linux/pci_hotplug.h>23#include <linux/mutex.h>24#include <linux/debugfs.h>25#include "cpqphp.h"26 27static DEFINE_MUTEX(cpqphp_mutex);28static int show_ctrl(struct controller *ctrl, char *buf)29{30	char *out = buf;31	int index;32	struct pci_resource *res;33 34	out += sprintf(buf, "Free resources: memory\n");35	index = 11;36	res = ctrl->mem_head;37	while (res && index--) {38		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);39		res = res->next;40	}41	out += sprintf(out, "Free resources: prefetchable memory\n");42	index = 11;43	res = ctrl->p_mem_head;44	while (res && index--) {45		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);46		res = res->next;47	}48	out += sprintf(out, "Free resources: IO\n");49	index = 11;50	res = ctrl->io_head;51	while (res && index--) {52		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);53		res = res->next;54	}55	out += sprintf(out, "Free resources: bus numbers\n");56	index = 11;57	res = ctrl->bus_head;58	while (res && index--) {59		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);60		res = res->next;61	}62 63	return out - buf;64}65 66static int show_dev(struct controller *ctrl, char *buf)67{68	char *out = buf;69	int index;70	struct pci_resource *res;71	struct pci_func *new_slot;72	struct slot *slot;73 74	slot = ctrl->slot;75 76	while (slot) {77		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);78		if (!new_slot)79			break;80		out += sprintf(out, "assigned resources: memory\n");81		index = 11;82		res = new_slot->mem_head;83		while (res && index--) {84			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);85			res = res->next;86		}87		out += sprintf(out, "assigned resources: prefetchable memory\n");88		index = 11;89		res = new_slot->p_mem_head;90		while (res && index--) {91			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);92			res = res->next;93		}94		out += sprintf(out, "assigned resources: IO\n");95		index = 11;96		res = new_slot->io_head;97		while (res && index--) {98			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);99			res = res->next;100		}101		out += sprintf(out, "assigned resources: bus numbers\n");102		index = 11;103		res = new_slot->bus_head;104		while (res && index--) {105			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);106			res = res->next;107		}108		slot = slot->next;109	}110 111	return out - buf;112}113 114static int spew_debug_info(struct controller *ctrl, char *data, int size)115{116	int used;117 118	used = size - show_ctrl(ctrl, data);119	used = (size - used) - show_dev(ctrl, &data[used]);120	return used;121}122 123struct ctrl_dbg {124	int size;125	char *data;126	struct controller *ctrl;127};128 129#define MAX_OUTPUT	(4*PAGE_SIZE)130 131static int open(struct inode *inode, struct file *file)132{133	struct controller *ctrl = inode->i_private;134	struct ctrl_dbg *dbg;135	int retval = -ENOMEM;136 137	mutex_lock(&cpqphp_mutex);138	dbg = kmalloc(sizeof(*dbg), GFP_KERNEL);139	if (!dbg)140		goto exit;141	dbg->data = kmalloc(MAX_OUTPUT, GFP_KERNEL);142	if (!dbg->data) {143		kfree(dbg);144		goto exit;145	}146	dbg->size = spew_debug_info(ctrl, dbg->data, MAX_OUTPUT);147	file->private_data = dbg;148	retval = 0;149exit:150	mutex_unlock(&cpqphp_mutex);151	return retval;152}153 154static loff_t lseek(struct file *file, loff_t off, int whence)155{156	struct ctrl_dbg *dbg = file->private_data;157	return fixed_size_llseek(file, off, whence, dbg->size);158}159 160static ssize_t read(struct file *file, char __user *buf,161		    size_t nbytes, loff_t *ppos)162{163	struct ctrl_dbg *dbg = file->private_data;164	return simple_read_from_buffer(buf, nbytes, ppos, dbg->data, dbg->size);165}166 167static int release(struct inode *inode, struct file *file)168{169	struct ctrl_dbg *dbg = file->private_data;170 171	kfree(dbg->data);172	kfree(dbg);173	return 0;174}175 176static const struct file_operations debug_ops = {177	.owner = THIS_MODULE,178	.open = open,179	.llseek = lseek,180	.read = read,181	.release = release,182};183 184static struct dentry *root;185 186void cpqhp_initialize_debugfs(void)187{188	if (!root)189		root = debugfs_create_dir("cpqhp", NULL);190}191 192void cpqhp_shutdown_debugfs(void)193{194	debugfs_remove(root);195}196 197void cpqhp_create_debugfs_files(struct controller *ctrl)198{199	ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev),200					   S_IRUGO, root, ctrl, &debug_ops);201}202 203void cpqhp_remove_debugfs_files(struct controller *ctrl)204{205	debugfs_remove(ctrl->dentry);206	ctrl->dentry = NULL;207}208 209