1 // SPDX-License-Identifier: GPL-2.0
2 /* drivers/nubus/proc.c: Proc FS interface for NuBus.
4 By David Huggins-Daines <dhd@debian.org>
6 Much code and many ideas from drivers/pci/proc.c:
7 Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
9 This is initially based on the Zorro and PCI interfaces. However,
10 it works somewhat differently. The intent is to provide a
11 structure in /proc analogous to the structure of the NuBus ROM
14 Therefore each board function gets a directory, which may in turn
15 contain subdirectories. Each slot resource is a file. Unrecognized
16 resources are empty files, since every resource ID requires a special
17 case (e.g. if the resource ID implies a directory or block, then its
18 value has to be interpreted as a slot ROM pointer etc.).
21 #include <linux/types.h>
22 #include <linux/kernel.h>
23 #include <linux/nubus.h>
24 #include <linux/proc_fs.h>
25 #include <linux/seq_file.h>
26 #include <linux/slab.h>
27 #include <linux/init.h>
28 #include <linux/module.h>
29 #include <linux/uaccess.h>
30 #include <asm/byteorder.h>
33 * /proc/bus/nubus/devices stuff
37 nubus_devices_proc_show(struct seq_file
*m
, void *v
)
39 struct nubus_rsrc
*fres
;
41 for_each_func_rsrc(fres
)
42 seq_printf(m
, "%x\t%04x %04x %04x %04x\t%08lx\n",
43 fres
->board
->slot
, fres
->category
, fres
->type
,
44 fres
->dr_sw
, fres
->dr_hw
, fres
->board
->slot_addr
);
48 static struct proc_dir_entry
*proc_bus_nubus_dir
;
51 * /proc/bus/nubus/x/ stuff
54 struct proc_dir_entry
*nubus_proc_add_board(struct nubus_board
*board
)
58 if (!proc_bus_nubus_dir
|| !nubus_populate_procfs
)
60 snprintf(name
, sizeof(name
), "%x", board
->slot
);
61 return proc_mkdir(name
, proc_bus_nubus_dir
);
64 /* The PDE private data for any directory under /proc/bus/nubus/x/
65 * is the bytelanes value for the board in slot x.
68 struct proc_dir_entry
*nubus_proc_add_rsrc_dir(struct proc_dir_entry
*procdir
,
69 const struct nubus_dirent
*ent
,
70 struct nubus_board
*board
)
73 int lanes
= board
->lanes
;
75 if (!procdir
|| !nubus_populate_procfs
)
77 snprintf(name
, sizeof(name
), "%x", ent
->type
);
78 remove_proc_subtree(name
, procdir
);
79 return proc_mkdir_data(name
, 0555, procdir
, (void *)lanes
);
82 /* The PDE private data for a file under /proc/bus/nubus/x/ is a pointer to
83 * an instance of the following structure, which gives the location and size
84 * of the resource data in the slot ROM. For slot resources which hold only a
85 * small integer, this integer value is stored directly and size is set to 0.
86 * A NULL private data pointer indicates an unrecognized resource.
89 struct nubus_proc_pde_data
{
90 unsigned char *res_ptr
;
91 unsigned int res_size
;
94 static struct nubus_proc_pde_data
*
95 nubus_proc_alloc_pde_data(unsigned char *ptr
, unsigned int size
)
97 struct nubus_proc_pde_data
*pded
;
99 pded
= kmalloc(sizeof(*pded
), GFP_KERNEL
);
104 pded
->res_size
= size
;
108 static int nubus_proc_rsrc_show(struct seq_file
*m
, void *v
)
110 struct inode
*inode
= m
->private;
111 struct nubus_proc_pde_data
*pded
;
113 pded
= pde_data(inode
);
117 if (pded
->res_size
> m
->size
)
120 if (pded
->res_size
) {
121 int lanes
= (int)proc_get_parent_data(inode
);
122 struct nubus_dirent ent
;
128 ent
.base
= pded
->res_ptr
;
130 nubus_seq_write_rsrc_mem(m
, &ent
, pded
->res_size
);
132 unsigned int data
= (unsigned int)pded
->res_ptr
;
134 seq_putc(m
, data
>> 16);
135 seq_putc(m
, data
>> 8);
136 seq_putc(m
, data
>> 0);
141 static int nubus_rsrc_proc_open(struct inode
*inode
, struct file
*file
)
143 return single_open(file
, nubus_proc_rsrc_show
, inode
);
146 static const struct proc_ops nubus_rsrc_proc_ops
= {
147 .proc_open
= nubus_rsrc_proc_open
,
148 .proc_read
= seq_read
,
149 .proc_lseek
= seq_lseek
,
150 .proc_release
= single_release
,
153 void nubus_proc_add_rsrc_mem(struct proc_dir_entry
*procdir
,
154 const struct nubus_dirent
*ent
,
158 struct nubus_proc_pde_data
*pded
;
160 if (!procdir
|| !nubus_populate_procfs
)
163 snprintf(name
, sizeof(name
), "%x", ent
->type
);
165 pded
= nubus_proc_alloc_pde_data(nubus_dirptr(ent
), size
);
168 remove_proc_subtree(name
, procdir
);
169 proc_create_data(name
, S_IFREG
| 0444, procdir
,
170 &nubus_rsrc_proc_ops
, pded
);
173 void nubus_proc_add_rsrc(struct proc_dir_entry
*procdir
,
174 const struct nubus_dirent
*ent
)
177 unsigned char *data
= (unsigned char *)ent
->data
;
179 if (!procdir
|| !nubus_populate_procfs
)
182 snprintf(name
, sizeof(name
), "%x", ent
->type
);
183 remove_proc_subtree(name
, procdir
);
184 proc_create_data(name
, S_IFREG
| 0444, procdir
,
185 &nubus_rsrc_proc_ops
,
186 nubus_proc_alloc_pde_data(data
, 0));
193 void __init
nubus_proc_init(void)
195 proc_create_single("nubus", 0, NULL
, nubus_proc_show
);
196 proc_bus_nubus_dir
= proc_mkdir("bus/nubus", NULL
);
197 if (!proc_bus_nubus_dir
)
199 proc_create_single("devices", 0, proc_bus_nubus_dir
,
200 nubus_devices_proc_show
);