~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/dio/dio.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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>
  3  * 
  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
 23  *
 24  * This file is based on the way the Amiga port handles Zorro II cards, 
 25  * although we aren't so complicated...
 26  */
 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
 37 
 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 ?
 46  */
 47 struct dioname
 48 {
 49         int id;
 50         const char *name;
 51 };
 52 
 53 /* useful macro */
 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 }
 56 
 57 static struct dioname names[] = 
 58 {
 59         DIONAME(DCA0), DIONAME(DCA0REM), DIONAME(DCA1), DIONAME(DCA1REM),
 60         DIONAME(DCM), DIONAME(DCMREM),
 61         DIONAME(LAN),
 62         DIONAME(FHPIB), DIONAME(NHPIB), DIONAME(IHPIB),
 63         DIONAME(SCSI0), DIONAME(SCSI1), DIONAME(SCSI2), DIONAME(SCSI3),
 64         DIONAME(FBUFFER),
 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)   
 74 };
 75 
 76 #undef DIONAME
 77 #undef DIOFBNAME
 78 
 79 #define NUMNAMES (sizeof(names) / sizeof(struct dioname))
 80 
 81 static const char *unknowndioname 
 82         = "unknown DIO board -- please email <pmaydell@chiark.greenend.org.uk>!";
 83 
 84 static const char *dio_getname(int id)
 85 {
 86         /* return pointer to a constant string describing the board with given ID */
 87         unsigned int i;
 88         for (i = 0; i < NUMNAMES; i++)
 89                 if (names[i].id == id) 
 90                         return names[i].name;
 91         
 92         return unknowndioname;
 93 }
 94 
 95 #else
 96 
 97 static char dio_no_name[] = { 0 };
 98 #define dio_getname(_id)        (dio_no_name)
 99 
100 #endif /* CONFIG_DIO_CONSTANTS */
101 
102 /* We represent all the DIO boards in the system with a linked list of these structs. */
103 struct dioboard
104 {
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 */
110         const char *name;
111 };
112 
113 static struct dioboard *blist = NULL;
114 
115 static int __init dio_find_slow(int deviceid)
116 {
117         /* Called to find a DIO device before the full bus scan has run.  Basically
118            only used by the console driver.  */
119         int scode;
120         for (scode = 0; scode < DIO_SCMAX; scode++)
121         {
122                 void *va;
123 
124                 if (DIO_SCINHOLE(scode))
125                         continue;
126                 
127                 va = dio_scodetoviraddr(scode);
128                 if (!va || !hwreg_present(va + DIO_IDOFF))
129                         continue;             /* no board present at that select code */
130 
131                 if (DIO_ID(va) == deviceid)
132                         return scode;
133         }
134         return 0;
135 }
136 
137 int dio_find(int deviceid)
138 {
139         if (blist) 
140         {
141                 /* fast way */
142                 struct dioboard *b;
143                 for (b = blist; b; b = b->next)
144                         if (b->id == deviceid && b->configured == 0)
145                                 return b->scode;
146                 return 0;
147         }
148         return dio_find_slow(deviceid);
149 }
150 
151 /* This is the function that scans the DIO space and works out what
152  * hardware is actually present.
153  */
154 void __init dio_init(void)
155 {
156         int scode;
157         struct dioboard *b, *bprev = NULL;
158    
159         printk("Scanning for DIO devices...\n");
160         
161         for (scode = 0; scode < DIO_SCMAX; ++scode)
162         {
163                 u_char prid, secid = 0;        /* primary, secondary ID bytes */
164                 u_char *va;
165                 
166                 if (DIO_SCINHOLE(scode))
167                         continue;
168                 
169                 va = dio_scodetoviraddr(scode);
170                 if (!va || !hwreg_present(va + DIO_IDOFF))
171                         continue;              /* no board present at that select code */
172 
173                 /* Found a board, allocate it an entry in the list */
174                 b = kmalloc(sizeof(struct dioboard), GFP_KERNEL);
175                 
176                 /* read the ID byte(s) and encode if necessary. Note workaround 
177                  * for broken internal HPIB devices...
178                  */
179                 if (!DIO_ISIHPIB(scode))
180                         prid = DIO_ID(va);
181                 else 
182                         prid = DIO_ID_IHPIB;
183                 
184                 if (DIO_NEEDSSECID(prid))
185                 {
186                         secid = DIO_SECID(va);
187                         b->id = DIO_ENCODE_ID(prid, secid);
188                 }
189                 else
190                         b->id = prid;
191       
192                 b->configured = 0;
193                 b->scode = scode;
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);
200                 
201                 b->next = NULL;
202 
203                 if (bprev)
204                         bprev->next = b;
205                 else
206                         blist = b;
207                 bprev = b;
208         }
209 }
210 
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...
213  */
214 void *dio_scodetoviraddr(int scode)
215 {
216         if (scode > DIOII_SCBASE)
217         {
218                 printk("dio_scodetoviraddr: don't support DIO-II yet!\n");
219                 return 0;
220         }
221         else if (scode > DIO_SCMAX || scode < 0)
222                 return 0;
223         else if (DIO_SCINHOLE(scode))
224                 return 0;
225         else if (scode == DIO_IHPIBSCODE) /* this should really be #ifdef CONFIG_IHPIB */
226                 return (void*)DIO_IHPIBADDR;   /* or something similar... */
227         
228         return (void*)(DIO_VIRADDRBASE + DIO_BASE + scode * 0x10000);
229 }
230 
231 int dio_scodetoipl(int scode)
232 {
233         struct dioboard *b;
234         for (b = blist; b; b = b->next)
235                 if (b->scode == scode) 
236                         break;
237         
238         if (!b)
239         {
240                 printk("dio_scodetoipl: bad select code %d\n", scode);
241                 return 0;
242         }
243         else
244                 return b->ipl;
245 }
246 
247 const char *dio_scodetoname(int scode)
248 {
249         struct dioboard *b;
250         for (b = blist; b; b = b->next)
251                 if (b->scode == scode) 
252                         break;
253         
254         if (!b)
255         {
256                 printk("dio_scodetoname: bad select code %d\n", scode);
257                 return NULL;
258         }
259         else
260                 return b->name;
261 }
262 
263 void dio_config_board(int scode)
264 {
265         struct dioboard *b;
266         for (b = blist; b; b = b->next)
267                 if (b->scode == scode)
268                         break;
269    
270         if (!b) 
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);
274         else
275                 b->configured = 1;
276 }
277 
278 void dio_unconfig_board(int scode)
279 {
280         struct dioboard *b;
281         for (b = blist; b; b = b->next)
282                 if (b->scode == scode) 
283                         break;
284    
285         if (!b) 
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", 
289                        scode);
290         else 
291                 b->configured = 0;
292 }
293 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.