1 /* Code to support devices on the DIO (and eventually DIO-II) bus
2 * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
4 * This code has basically these routines at the moment:
5 * int dio_find(u_int deviceid)
6 * Search the list of DIO devices and return the select code
7 * of the next unconfigured device found that matches the given device ID.
8 * Note that the deviceid parameter should be the encoded ID.
9 * This means that framebuffers should pass it as
10 * DIO_ENCODE_ID(DIO_ID_FBUFFER,DIO_ID2_TOPCAT)
11 * (or whatever); everybody else just uses DIO_ID_FOOBAR.
12 * void *dio_scodetoviraddr(int scode)
13 * Return the virtual address corresponding to the given select code.
14 * NB: DIO-II devices will have to be mapped in in this routine!
15 * int dio_scodetoipl(int scode)
16 * Every DIO card has a fixed interrupt priority level. This function
17 * returns it, whatever it is.
18 * const char *dio_scodetoname(int scode)
19 * Return a character string describing this board [might be "" if
20 * not CONFIG_DIO_CONSTANTS]
21 * void dio_config_board(int scode) mark board as configured in the list
22 * void dio_unconfig_board(int scode) mark board as no longer configured
24 * This file is based on the way the Amiga port handles Zorro II cards,
25 * although we aren't so complicated...
27 #include <linux/config.h>
28 #include <linux/kernel.h>
29 #include <linux/types.h>
30 #include <linux/dio.h>
31 #include <linux/malloc.h> /* kmalloc() */
32 #include <linux/init.h>
33 #include <asm/hwtest.h> /* hwreg_present() */
34 #include <asm/io.h> /* readb() */
35 /* not a real config option yet! */
36 #define CONFIG_DIO_CONSTANTS
38 #ifdef CONFIG_DIO_CONSTANTS
39 /* We associate each numeric ID with an appropriate descriptive string
40 * using a constant array of these structs.
41 * FIXME: we should be able to arrange to throw away most of the strings
42 * using the initdata stuff. Then we wouldn't need to worry about
43 * carrying them around...
44 * I think we do this by copying them into newly kmalloc()ed memory and
45 * marking the names[] array as .initdata ?
54 #define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x }
55 #define DIOFBNAME(x) { DIO_ENCODE_ID( DIO_ID_FBUFFER, DIO_ID2_##x), DIO_DESC2_##x }
57 static struct dioname names
[] =
59 DIONAME(DCA0
), DIONAME(DCA0REM
), DIONAME(DCA1
), DIONAME(DCA1REM
),
60 DIONAME(DCM
), DIONAME(DCMREM
),
62 DIONAME(FHPIB
), DIONAME(NHPIB
), DIONAME(IHPIB
),
63 DIONAME(SCSI0
), DIONAME(SCSI1
), DIONAME(SCSI2
), DIONAME(SCSI3
),
65 DIONAME(PARALLEL
), DIONAME(VME
), DIONAME(DCL
), DIONAME(DCLREM
),
66 DIONAME(MISC0
), DIONAME(MISC1
), DIONAME(MISC2
), DIONAME(MISC3
),
67 DIONAME(MISC4
), DIONAME(MISC5
), DIONAME(MISC6
), DIONAME(MISC7
),
68 DIONAME(MISC8
), DIONAME(MISC9
), DIONAME(MISC10
), DIONAME(MISC11
),
69 DIONAME(MISC12
), DIONAME(MISC13
),
70 DIOFBNAME(GATORBOX
), DIOFBNAME(TOPCAT
), DIOFBNAME(RENAISSANCE
),
71 DIOFBNAME(LRCATSEYE
), DIOFBNAME(HRCCATSEYE
), DIOFBNAME(HRMCATSEYE
),
72 DIOFBNAME(DAVINCI
), DIOFBNAME(XXXCATSEYE
), DIOFBNAME(HYPERION
),
73 DIOFBNAME(XGENESIS
), DIOFBNAME(TIGER
), DIOFBNAME(YGENESIS
)
79 #define NUMNAMES (sizeof(names) / sizeof(struct dioname))
81 static const char *unknowndioname
82 = "unknown DIO board -- please email <pmaydell@chiark.greenend.org.uk>!";
84 static const char *dio_getname(int id
)
86 /* return pointer to a constant string describing the board with given ID */
88 for (i
= 0; i
< NUMNAMES
; i
++)
89 if (names
[i
].id
== id
)
92 return unknowndioname
;
97 static char dio_no_name
[] = { 0 };
98 #define dio_getname(_id) (dio_no_name)
100 #endif /* CONFIG_DIO_CONSTANTS */
102 /* We represent all the DIO boards in the system with a linked list of these structs. */
105 struct dioboard
*next
; /* link to next struct in list */
106 int ipl
; /* IPL of this board */
107 int configured
; /* has this board been configured? */
108 int scode
; /* select code of this board */
109 int id
; /* encoded ID */
113 static struct dioboard
*blist
= NULL
;
115 __initfunc(static int dio_find_slow(int deviceid
))
117 /* Called to find a DIO device before the full bus scan has run. Basically
118 only used by the console driver. */
120 for (scode
= 0; scode
< DIO_SCMAX
; scode
++)
124 if (DIO_SCINHOLE(scode
))
127 va
= dio_scodetoviraddr(scode
);
128 if (!va
|| !hwreg_present(va
+ DIO_IDOFF
))
129 continue; /* no board present at that select code */
131 if (DIO_ID(va
) == deviceid
)
137 int dio_find(int deviceid
)
143 for (b
= blist
; b
; b
= b
->next
)
144 if (b
->id
== deviceid
&& b
->configured
== 0)
148 return dio_find_slow(deviceid
);
151 /* This is the function that scans the DIO space and works out what
152 * hardware is actually present.
154 __initfunc(void dio_init(void))
157 struct dioboard
*b
, *bprev
= NULL
;
159 printk("Scanning for DIO devices...\n");
161 for (scode
= 0; scode
< DIO_SCMAX
; ++scode
)
163 u_char prid
, secid
= 0; /* primary, secondary ID bytes */
166 if (DIO_SCINHOLE(scode
))
169 va
= dio_scodetoviraddr(scode
);
170 if (!va
|| !hwreg_present(va
+ DIO_IDOFF
))
171 continue; /* no board present at that select code */
173 /* Found a board, allocate it an entry in the list */
174 b
= kmalloc(sizeof(struct dioboard
), GFP_KERNEL
);
176 /* read the ID byte(s) and encode if necessary. Note workaround
177 * for broken internal HPIB devices...
179 if (!DIO_ISIHPIB(scode
))
184 if (DIO_NEEDSSECID(prid
))
186 secid
= DIO_SECID(va
);
187 b
->id
= DIO_ENCODE_ID(prid
, secid
);
194 b
->ipl
= DIO_IPL(va
);
195 b
->name
= dio_getname(b
->id
);
196 printk("select code %3d: ID %02X", scode
, prid
);
197 if (DIO_NEEDSSECID(b
->id
))
198 printk(":%02X", secid
);
199 printk(" %s\n", b
->name
);
211 /* Bear in mind that this is called in the very early stages of initialisation
212 * in order to get the virtual address of the serial port for the console...
214 void *dio_scodetoviraddr(int scode
)
216 if (scode
> DIOII_SCBASE
)
218 printk("dio_scodetoviraddr: don't support DIO-II yet!\n");
221 else if (scode
> DIO_SCMAX
|| scode
< 0)
223 else if (DIO_SCINHOLE(scode
))
225 else if (scode
== DIO_IHPIBSCODE
) /* this should really be #ifdef CONFIG_IHPIB */
226 return (void*)DIO_IHPIBADDR
; /* or something similar... */
228 return (void*)(DIO_VIRADDRBASE
+ DIO_BASE
+ scode
* 0x10000);
231 int dio_scodetoipl(int scode
)
234 for (b
= blist
; b
; b
= b
->next
)
235 if (b
->scode
== scode
)
240 printk("dio_scodetoipl: bad select code %d\n", scode
);
247 const char *dio_scodetoname(int scode
)
250 for (b
= blist
; b
; b
= b
->next
)
251 if (b
->scode
== scode
)
256 printk("dio_scodetoname: bad select code %d\n", scode
);
263 void dio_config_board(int scode
)
266 for (b
= blist
; b
; b
= b
->next
)
267 if (b
->scode
== scode
)
271 printk("dio_config_board: bad select code %d\n", scode
);
272 else if (b
->configured
)
273 printk("dio_config_board: board at select code %d already configured\n", scode
);
278 void dio_unconfig_board(int scode
)
281 for (b
= blist
; b
; b
= b
->next
)
282 if (b
->scode
== scode
)
286 printk("dio_unconfig_board: bad select code %d\n", scode
);
287 else if (!b
->configured
)
288 printk("dio_unconfig_board: board at select code %d not configured\n",