// SPDX-License-Identifier: GPL-2.0
/* drivers/nubus/proc.c: Proc FS interface for NuBus.

   By David Huggins-Daines <dhd@debian.org>

   Much code and many ideas from drivers/pci/proc.c:
   Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>

   This is initially based on the Zorro and PCI interfaces.  However,
   it works somewhat differently.  The intent is to provide a
   structure in /proc analogous to the structure of the NuBus ROM
   resources.

   Therefore each board function gets a directory, which may in turn
   contain subdirectories.  Each slot resource is a file.  Unrecognized
   resources are empty files, since every resource ID requires a special
   case (e.g. if the resource ID implies a directory or block, then its
   value has to be interpreted as a slot ROM pointer etc.).
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/nubus.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <asm/byteorder.h>

/*
 * /proc/bus/nubus/devices stuff
 */

static int
nubus_devices_proc_show(struct seq_file *m, void *v)
{
	struct nubus_rsrc *fres;

	for_each_func_rsrc(fres)
		seq_printf(m, "%x\t%04x %04x %04x %04x\t%08lx\n",
			   fres->board->slot, fres->category, fres->type,
			   fres->dr_sw, fres->dr_hw, fres->board->slot_addr);
	return 0;
}

static struct proc_dir_entry *proc_bus_nubus_dir;

/*
 * /proc/bus/nubus/x/ stuff
 */

struct proc_dir_entry *nubus_proc_add_board(struct nubus_board *board)
{
	char name[2];

	if (!proc_bus_nubus_dir)
		return NULL;
	snprintf(name, sizeof(name), "%x", board->slot);
	return proc_mkdir(name, proc_bus_nubus_dir);
}

/* The PDE private data for any directory under /proc/bus/nubus/x/
 * is the bytelanes value for the board in slot x.
 */

struct proc_dir_entry *nubus_proc_add_rsrc_dir(struct proc_dir_entry *procdir,
					       const struct nubus_dirent *ent,
					       struct nubus_board *board)
{
	char name[9];
	int lanes = board->lanes;

	if (!procdir)
		return NULL;
	snprintf(name, sizeof(name), "%x", ent->type);
	return proc_mkdir_data(name, 0555, procdir, (void *)lanes);
}

/* The PDE private data for a file under /proc/bus/nubus/x/ is a pointer to
 * an instance of the following structure, which gives the location and size
 * of the resource data in the slot ROM. For slot resources which hold only a
 * small integer, this integer value is stored directly and size is set to 0.
 * A NULL private data pointer indicates an unrecognized resource.
 */

struct nubus_proc_pde_data {
	unsigned char *res_ptr;
	unsigned int res_size;
};

static struct nubus_proc_pde_data *
nubus_proc_alloc_pde_data(unsigned char *ptr, unsigned int size)
{
	struct nubus_proc_pde_data *pded;

	pded = kmalloc(sizeof(*pded), GFP_KERNEL);
	if (!pded)
		return NULL;

	pded->res_ptr = ptr;
	pded->res_size = size;
	return pded;
}

static int nubus_proc_rsrc_show(struct seq_file *m, void *v)
{
	struct inode *inode = m->private;
	struct nubus_proc_pde_data *pded;

	pded = pde_data(inode);
	if (!pded)
		return 0;

	if (pded->res_size > m->size)
		return -EFBIG;

	if (pded->res_size) {
		int lanes = (int)proc_get_parent_data(inode);
		struct nubus_dirent ent;

		if (!lanes)
			return 0;

		ent.mask = lanes;
		ent.base = pded->res_ptr;
		ent.data = 0;
		nubus_seq_write_rsrc_mem(m, &ent, pded->res_size);
	} else {
		unsigned int data = (unsigned int)pded->res_ptr;

		seq_putc(m, data >> 16);
		seq_putc(m, data >> 8);
		seq_putc(m, data >> 0);
	}
	return 0;
}

void nubus_proc_add_rsrc_mem(struct proc_dir_entry *procdir,
			     const struct nubus_dirent *ent,
			     unsigned int size)
{
	char name[9];
	struct nubus_proc_pde_data *pded;

	if (!procdir)
		return;

	snprintf(name, sizeof(name), "%x", ent->type);
	if (size)
		pded = nubus_proc_alloc_pde_data(nubus_dirptr(ent), size);
	else
		pded = NULL;
	proc_create_single_data(name, S_IFREG | 0444, procdir,
			nubus_proc_rsrc_show, pded);
}

void nubus_proc_add_rsrc(struct proc_dir_entry *procdir,
			 const struct nubus_dirent *ent)
{
	char name[9];
	unsigned char *data = (unsigned char *)ent->data;

	if (!procdir)
		return;

	snprintf(name, sizeof(name), "%x", ent->type);
	proc_create_single_data(name, S_IFREG | 0444, procdir,
			nubus_proc_rsrc_show,
			nubus_proc_alloc_pde_data(data, 0));
}

/*
 * /proc/nubus stuff
 */

void __init nubus_proc_init(void)
{
	proc_create_single("nubus", 0, NULL, nubus_proc_show);
	proc_bus_nubus_dir = proc_mkdir("bus/nubus", NULL);
	if (!proc_bus_nubus_dir)
		return;
	proc_create_single("devices", 0, proc_bus_nubus_dir,
			nubus_devices_proc_show);
}
