summaryrefslogtreecommitdiff
path: root/include/linux/nubus.h
blob: 4d103ac8f5c7a90d609825de3f7fc348bf5fd5c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/* SPDX-License-Identifier: GPL-2.0 */
/*
  nubus.h: various definitions and prototypes for NuBus drivers to use.

  Originally written by Alan Cox.

  Hacked to death by C. Scott Ananian and David Huggins-Daines.
*/

#ifndef LINUX_NUBUS_H
#define LINUX_NUBUS_H

#include <linux/device.h>
#include <asm/nubus.h>
#include <uapi/linux/nubus.h>

struct proc_dir_entry;
struct seq_file;

struct nubus_dir {
	unsigned char *base;
	unsigned char *ptr;
	int done;
	int mask;
	struct proc_dir_entry *procdir;
};

struct nubus_dirent {
	unsigned char *base;
	unsigned char type;
	__u32 data;	/* Actually 24 bits used */
	int mask;
};

struct nubus_board {
	struct device dev;

	/* Only 9-E actually exist, though 0-8 are also theoretically
	   possible, and 0 is a special case which represents the
	   motherboard and onboard peripherals (Ethernet, video) */
	int slot;
	/* For slot 0, this is bogus. */
	char name[64];

	/* Format block */
	unsigned char *fblock;
	/* Root directory (does *not* always equal fblock + doffset!) */
	unsigned char *directory;

	unsigned long slot_addr;
	/* Offset to root directory (sometimes) */
	unsigned long doffset;
	/* Length over which to compute the crc */
	unsigned long rom_length;
	/* Completely useless most of the time */
	unsigned long crc;
	unsigned char rev;
	unsigned char format;
	unsigned char lanes;

	/* Directory entry in /proc/bus/nubus */
	struct proc_dir_entry *procdir;
};

struct nubus_rsrc {
	struct list_head list;

	/* The functional resource ID */
	unsigned char resid;
	/* These are mostly here for convenience; we could always read
	   them from the ROMs if we wanted to */
	unsigned short category;
	unsigned short type;
	unsigned short dr_sw;
	unsigned short dr_hw;

	/* Functional directory */
	unsigned char *directory;
	/* Much of our info comes from here */
	struct nubus_board *board;
};

/* This is all NuBus functional resources (used to find devices later on) */
extern struct list_head nubus_func_rsrcs;

struct nubus_driver {
	struct device_driver driver;
	int (*probe)(struct nubus_board *board);
	void (*remove)(struct nubus_board *board);
};

/* Generic NuBus interface functions, modelled after the PCI interface */
#ifdef CONFIG_PROC_FS
extern bool nubus_populate_procfs;
void nubus_proc_init(void);
struct proc_dir_entry *nubus_proc_add_board(struct nubus_board *board);
struct proc_dir_entry *nubus_proc_add_rsrc_dir(struct proc_dir_entry *procdir,
					       const struct nubus_dirent *ent,
					       struct nubus_board *board);
void nubus_proc_add_rsrc_mem(struct proc_dir_entry *procdir,
			     const struct nubus_dirent *ent,
			     unsigned int size);
void nubus_proc_add_rsrc(struct proc_dir_entry *procdir,
			 const struct nubus_dirent *ent);
#else
static inline void nubus_proc_init(void) {}
static inline
struct proc_dir_entry *nubus_proc_add_board(struct nubus_board *board)
{ return NULL; }
static inline
struct proc_dir_entry *nubus_proc_add_rsrc_dir(struct proc_dir_entry *procdir,
					       const struct nubus_dirent *ent,
					       struct nubus_board *board)
{ return NULL; }
static inline void nubus_proc_add_rsrc_mem(struct proc_dir_entry *procdir,
					   const struct nubus_dirent *ent,
					   unsigned int size) {}
static inline void nubus_proc_add_rsrc(struct proc_dir_entry *procdir,
				       const struct nubus_dirent *ent) {}
#endif

struct nubus_rsrc *nubus_first_rsrc_or_null(void);
struct nubus_rsrc *nubus_next_rsrc_or_null(struct nubus_rsrc *from);

#define for_each_func_rsrc(f) \
	for (f = nubus_first_rsrc_or_null(); f; f = nubus_next_rsrc_or_null(f))

#define for_each_board_func_rsrc(b, f) \
	for_each_func_rsrc(f) if (f->board != b) {} else

/* These are somewhat more NuBus-specific.  They all return 0 for
   success and -1 for failure, as you'd expect. */

/* The root directory which contains the board and functional
   directories */
int nubus_get_root_dir(const struct nubus_board *board,
		       struct nubus_dir *dir);
/* The board directory */
int nubus_get_board_dir(const struct nubus_board *board,
			struct nubus_dir *dir);
/* The functional directory */
int nubus_get_func_dir(const struct nubus_rsrc *fres, struct nubus_dir *dir);

/* These work on any directory gotten via the above */
int nubus_readdir(struct nubus_dir *dir,
		  struct nubus_dirent *ent);
int nubus_find_rsrc(struct nubus_dir *dir,
		    unsigned char rsrc_type,
		    struct nubus_dirent *ent);
int nubus_rewinddir(struct nubus_dir *dir);

/* Things to do with directory entries */
int nubus_get_subdir(const struct nubus_dirent *ent,
		     struct nubus_dir *dir);
void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
			unsigned int len);
unsigned int nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
				unsigned int len);
void nubus_seq_write_rsrc_mem(struct seq_file *m,
			      const struct nubus_dirent *dirent,
			      unsigned int len);
unsigned char *nubus_dirptr(const struct nubus_dirent *nd);

/* Declarations relating to driver model objects */
int nubus_parent_device_register(void);
int nubus_device_register(struct nubus_board *board);
int nubus_driver_register(struct nubus_driver *ndrv);
void nubus_driver_unregister(struct nubus_driver *ndrv);
int nubus_proc_show(struct seq_file *m, void *data);

static inline void nubus_set_drvdata(struct nubus_board *board, void *data)
{
	dev_set_drvdata(&board->dev, data);
}

static inline void *nubus_get_drvdata(struct nubus_board *board)
{
	return dev_get_drvdata(&board->dev);
}

/* Returns a pointer to the "standard" slot space. */
static inline void *nubus_slot_addr(int slot)
{
	return (void *)(0xF0000000 | (slot << 24));
}

#endif /* LINUX_NUBUS_H */