Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb6edad3 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Linus Torvalds
Browse files

mpt fusion: convert to seq_file



Convert everything except ->proc_info() stuff, it is done within separate
->proc_info path series.

Problem with ->read_proc et al is described here commit
786d7e16 "Fix rmmod/read/write races in
/proc entries"

Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Cc: Eric Moore <Eric.Moore@lsi.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d2367006
Loading
Loading
Loading
Loading
+119 −117
Original line number Original line Diff line number Diff line
@@ -50,6 +50,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/pci.h>
@@ -200,12 +201,9 @@ static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_valu
static int	mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
static int	mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);


#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
static int	procmpt_summary_read(char *buf, char **start, off_t offset,
static const struct file_operations mpt_summary_proc_fops;
				int request, int *eof, void *data);
static const struct file_operations mpt_version_proc_fops;
static int	procmpt_version_read(char *buf, char **start, off_t offset,
static const struct file_operations mpt_iocinfo_proc_fops;
				int request, int *eof, void *data);
static int	procmpt_iocinfo_read(char *buf, char **start, off_t offset,
				int request, int *eof, void *data);
#endif
#endif
static void	mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
static void	mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);


@@ -1725,7 +1723,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
	u8		 pcixcmd;
	u8		 pcixcmd;
	static int	 mpt_ids = 0;
	static int	 mpt_ids = 0;
#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
	struct proc_dir_entry *dent, *ent;
	struct proc_dir_entry *dent;
#endif
#endif


	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
@@ -1980,16 +1978,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
	 */
	 */
	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
	if (dent) {
	if (dent) {
		ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
		proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
		if (ent) {
		proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
			ent->read_proc = procmpt_iocinfo_read;
			ent->data = ioc;
		}
		ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
		if (ent) {
			ent->read_proc = procmpt_summary_read;
			ent->data = ioc;
		}
	}
	}
#endif
#endif


@@ -6546,20 +6536,12 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
static int
static int
procmpt_create(void)
procmpt_create(void)
{
{
	struct proc_dir_entry	*ent;

	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
	if (mpt_proc_root_dir == NULL)
	if (mpt_proc_root_dir == NULL)
		return -ENOTDIR;
		return -ENOTDIR;


	ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
	proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
	if (ent)
	proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
		ent->read_proc = procmpt_summary_read;

	ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
	if (ent)
		ent->read_proc = procmpt_version_read;

	return 0;
	return 0;
}
}


@@ -6579,70 +6561,46 @@ procmpt_destroy(void)


/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
/**
 *	procmpt_summary_read - Handle read request of a summary file
 *	@buf: Pointer to area to write information
 *	@start: Pointer to start pointer
 *	@offset: Offset to start writing
 *	@request: Amount of read data requested
 *	@eof: Pointer to EOF integer
 *	@data: Pointer
 *
 *	Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
 *	Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
 *	Returns number of characters written to process performing the read.
 */
 */
static int
static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
{
	MPT_ADAPTER *ioc;
	char *out = buf;
	int len;


	if (data) {
static int mpt_summary_proc_show(struct seq_file *m, void *v)
		int more = 0;
{

	MPT_ADAPTER *ioc = m->private;
		ioc = data;
		mpt_print_ioc_summary(ioc, out, &more, 0, 1);


		out += more;
	if (ioc) {
		seq_mpt_print_ioc_summary(ioc, m, 1);
	} else {
	} else {
		list_for_each_entry(ioc, &ioc_list, list) {
		list_for_each_entry(ioc, &ioc_list, list) {
			int	more = 0;
			seq_mpt_print_ioc_summary(ioc, m, 1);

			mpt_print_ioc_summary(ioc, out, &more, 0, 1);

			out += more;
			if ((out-buf) >= request)
				break;
		}
		}
	}
	}


	len = out - buf;
	return 0;
}


	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
static int mpt_summary_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, mpt_summary_proc_show, PDE(inode)->data);
}
}


/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static const struct file_operations mpt_summary_proc_fops = {
/**
	.owner		= THIS_MODULE,
 *	procmpt_version_read - Handle read request from /proc/mpt/version.
	.open		= mpt_summary_proc_open,
 *	@buf: Pointer to area to write information
	.read		= seq_read,
 *	@start: Pointer to start pointer
	.llseek		= seq_lseek,
 *	@offset: Offset to start writing
	.release	= single_release,
 *	@request: Amount of read data requested
};
 *	@eof: Pointer to EOF integer

 *	@data: Pointer
static int mpt_version_proc_show(struct seq_file *m, void *v)
 *
 *	Returns number of characters written to process performing the read.
 */
static int
procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
{
{
	u8	 cb_idx;
	u8	 cb_idx;
	int	 scsi, fc, sas, lan, ctl, targ, dmp;
	int	 scsi, fc, sas, lan, ctl, targ, dmp;
	char	*drvname;
	char	*drvname;
	int	 len;


	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
	seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
	len += sprintf(buf+len, "  Fusion MPT base driver\n");
	seq_printf(m, "  Fusion MPT base driver\n");


	scsi = fc = sas = lan = ctl = targ = dmp = 0;
	scsi = fc = sas = lan = ctl = targ = dmp = 0;
	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
@@ -6670,98 +6628,97 @@ procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eo
			}
			}


			if (drvname)
			if (drvname)
				len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
				seq_printf(m, "  Fusion MPT %s driver\n", drvname);
		}
		}
	}
	}


	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
	return 0;
}
}


/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int mpt_version_proc_open(struct inode *inode, struct file *file)
/**
{
 *	procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
	return single_open(file, mpt_version_proc_show, NULL);
 *	@buf: Pointer to area to write information
}
 *	@start: Pointer to start pointer

 *	@offset: Offset to start writing
static const struct file_operations mpt_version_proc_fops = {
 *	@request: Amount of read data requested
	.owner		= THIS_MODULE,
 *	@eof: Pointer to EOF integer
	.open		= mpt_version_proc_open,
 *	@data: Pointer
	.read		= seq_read,
 *
	.llseek		= seq_lseek,
 *	Returns number of characters written to process performing the read.
	.release	= single_release,
 */
};
static int

procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
{
{
	MPT_ADAPTER	*ioc = data;
	MPT_ADAPTER	*ioc = m->private;
	int		 len;
	char		 expVer[32];
	char		 expVer[32];
	int		 sz;
	int		 sz;
	int		 p;
	int		 p;


	mpt_get_fw_exp_ver(expVer, ioc);
	mpt_get_fw_exp_ver(expVer, ioc);


	len = sprintf(buf, "%s:", ioc->name);
	seq_printf(m, "%s:", ioc->name);
	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
		len += sprintf(buf+len, "  (f/w download boot flag set)");
		seq_printf(m, "  (f/w download boot flag set)");
//	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
//	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
//		len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
//		seq_printf(m, "  CONFIG_CHECKSUM_FAIL!");


	len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
	seq_printf(m, "\n  ProductID = 0x%04x (%s)\n",
			ioc->facts.ProductID,
			ioc->facts.ProductID,
			ioc->prod_name);
			ioc->prod_name);
	len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
	seq_printf(m, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
	if (ioc->facts.FWImageSize)
	if (ioc->facts.FWImageSize)
		len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
		seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
	len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
	seq_printf(m, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
	len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
	seq_printf(m, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
	len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
	seq_printf(m, "  EventState = 0x%02x\n", ioc->facts.EventState);


	len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
	seq_printf(m, "  CurrentHostMfaHighAddr = 0x%08x\n",
			ioc->facts.CurrentHostMfaHighAddr);
			ioc->facts.CurrentHostMfaHighAddr);
	len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
	seq_printf(m, "  CurrentSenseBufferHighAddr = 0x%08x\n",
			ioc->facts.CurrentSenseBufferHighAddr);
			ioc->facts.CurrentSenseBufferHighAddr);


	len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
	seq_printf(m, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
	len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
	seq_printf(m, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);


	len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
	seq_printf(m, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
	/*
	/*
	 *  Rounding UP to nearest 4-kB boundary here...
	 *  Rounding UP to nearest 4-kB boundary here...
	 */
	 */
	sz = (ioc->req_sz * ioc->req_depth) + 128;
	sz = (ioc->req_sz * ioc->req_depth) + 128;
	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
	len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
	seq_printf(m, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
	len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
	seq_printf(m, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
					4*ioc->facts.RequestFrameSize,
					4*ioc->facts.RequestFrameSize,
					ioc->facts.GlobalCredits);
					ioc->facts.GlobalCredits);


	len += sprintf(buf+len, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
	seq_printf(m, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
	len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
	seq_printf(m, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
	len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
	seq_printf(m, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
					ioc->facts.CurReplyFrameSize,
					ioc->facts.CurReplyFrameSize,
					ioc->facts.ReplyQueueDepth);
					ioc->facts.ReplyQueueDepth);


	len += sprintf(buf+len, "  MaxDevices = %d\n",
	seq_printf(m, "  MaxDevices = %d\n",
			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
	len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
	seq_printf(m, "  MaxBuses = %d\n", ioc->facts.MaxBuses);


	/* per-port info */
	/* per-port info */
	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
		len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
		seq_printf(m, "  PortNumber = %d (of %d)\n",
				p+1,
				p+1,
				ioc->facts.NumberOfPorts);
				ioc->facts.NumberOfPorts);
		if (ioc->bus_type == FC) {
		if (ioc->bus_type == FC) {
			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
				len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
				seq_printf(m, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
						a[5], a[4], a[3], a[2], a[1], a[0]);
						a[5], a[4], a[3], a[2], a[1], a[0]);
			}
			}
			len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
			seq_printf(m, "    WWN = %08X%08X:%08X%08X\n",
					ioc->fc_port_page0[p].WWNN.High,
					ioc->fc_port_page0[p].WWNN.High,
					ioc->fc_port_page0[p].WWNN.Low,
					ioc->fc_port_page0[p].WWNN.Low,
					ioc->fc_port_page0[p].WWPN.High,
					ioc->fc_port_page0[p].WWPN.High,
@@ -6769,9 +6726,21 @@ procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eo
		}
		}
	}
	}


	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
	return 0;
}
}


static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, mpt_iocinfo_proc_show, PDE(inode)->data);
}

static const struct file_operations mpt_iocinfo_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= mpt_iocinfo_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
#endif		/* CONFIG_PROC_FS } */
#endif		/* CONFIG_PROC_FS } */


/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6837,6 +6806,39 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh


	*size = y;
	*size = y;
}
}

static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
{
	char expVer[32];

	mpt_get_fw_exp_ver(expVer, ioc);

	/*
	 *  Shorter summary of attached ioc's...
	 */
	seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
			ioc->name,
			ioc->prod_name,
			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
			ioc->facts.FWVersion.Word,
			expVer,
			ioc->facts.NumberOfPorts,
			ioc->req_depth);

	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
		seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
			a[5], a[4], a[3], a[2], a[1], a[0]);
	}

	seq_printf(m, ", IRQ=%d", ioc->pci_irq);

	if (!ioc->active)
		seq_printf(m, " (disabled)");

	seq_putc(m, '\n');
}

/**
/**
 *	mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
 *	mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
 *	@ioc: Pointer to MPT_ADAPTER structure
 *	@ioc: Pointer to MPT_ADAPTER structure
+0 −25
Original line number Original line Diff line number Diff line
@@ -419,31 +419,6 @@ typedef struct _VirtDevice {
#define MPT_TARGET_FLAGS_RAID_COMPONENT	0x40
#define MPT_TARGET_FLAGS_RAID_COMPONENT	0x40
#define MPT_TARGET_FLAGS_LED_ON		0x80
#define MPT_TARGET_FLAGS_LED_ON		0x80


/*
 *	/proc/mpt interface
 */
typedef struct {
	const char	*name;
	mode_t		 mode;
	int		 pad;
	read_proc_t	*read_proc;
	write_proc_t	*write_proc;
} mpt_proc_entry_t;

#define MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len) \
do { \
	len -= offset;			\
	if (len < request) {		\
		*eof = 1;		\
		if (len <= 0)		\
			return 0;	\
	} else				\
		len = request;		\
	*start = buf + offset;		\
	return len;			\
} while (0)


/*
/*
 *	IOCTL structure and associated defines
 *	IOCTL structure and associated defines
 */
 */