Diff markup
1 /* Code to support devices on the DIO and DIO- 1 /* Code to support devices on the DIO and DIO-II bus
2 * Copyright (C) 05/1998 Peter Maydell <pmayde 2 * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
3 * Copyright (C) 2004 Jochen Friedrich <jochen 3 * Copyright (C) 2004 Jochen Friedrich <jochen@scram.de>
4 * 4 *
5 * This code has basically these routines at t 5 * This code has basically these routines at the moment:
6 * int dio_find(u_int deviceid) 6 * int dio_find(u_int deviceid)
7 * Search the list of DIO devices and retur 7 * Search the list of DIO devices and return the select code
8 * of the next unconfigured device found th 8 * of the next unconfigured device found that matches the given device ID.
9 * Note that the deviceid parameter should 9 * Note that the deviceid parameter should be the encoded ID.
10 * This means that framebuffers should pass 10 * This means that framebuffers should pass it as
11 * DIO_ENCODE_ID(DIO_ID_FBUFFER,DIO_ID2_TOP 11 * DIO_ENCODE_ID(DIO_ID_FBUFFER,DIO_ID2_TOPCAT)
12 * (or whatever); everybody else just uses 12 * (or whatever); everybody else just uses DIO_ID_FOOBAR.
13 * unsigned long dio_scodetophysaddr(int scode 13 * unsigned long dio_scodetophysaddr(int scode)
14 * Return the physical address correspondin 14 * Return the physical address corresponding to the given select code.
15 * int dio_scodetoipl(int scode) 15 * int dio_scodetoipl(int scode)
16 * Every DIO card has a fixed interrupt pri 16 * Every DIO card has a fixed interrupt priority level. This function
17 * returns it, whatever it is. 17 * returns it, whatever it is.
18 * const char *dio_scodetoname(int scode) 18 * const char *dio_scodetoname(int scode)
19 * Return a character string describing thi 19 * Return a character string describing this board [might be "" if
20 * not CONFIG_DIO_CONSTANTS] 20 * not CONFIG_DIO_CONSTANTS]
21 * void dio_config_board(int scode) mark b 21 * void dio_config_board(int scode) mark board as configured in the list
22 * void dio_unconfig_board(int scode) mark b 22 * void dio_unconfig_board(int scode) mark board as no longer configured
23 * 23 *
24 * This file is based on the way the Amiga por 24 * This file is based on the way the Amiga port handles Zorro II cards,
25 * although we aren't so complicated... 25 * although we aren't so complicated...
26 */ 26 */
27 #include <linux/module.h> 27 #include <linux/module.h>
28 #include <linux/string.h> 28 #include <linux/string.h>
29 #include <linux/types.h> 29 #include <linux/types.h>
30 #include <linux/kernel.h> 30 #include <linux/kernel.h>
31 #include <linux/init.h> 31 #include <linux/init.h>
32 #include <linux/dio.h> 32 #include <linux/dio.h>
33 #include <linux/slab.h> 33 #include <linux/slab.h> /* kmalloc() */
34 #include <asm/uaccess.h> 34 #include <asm/uaccess.h>
35 #include <asm/io.h> 35 #include <asm/io.h> /* readb() */
36 36
37 struct dio_bus dio_bus = { 37 struct dio_bus dio_bus = {
38 .resources = { 38 .resources = {
39 /* DIO range */ 39 /* DIO range */
40 { .name = "DIO mem", .start = 40 { .name = "DIO mem", .start = 0x00600000, .end = 0x007fffff },
41 /* DIO-II range */ 41 /* DIO-II range */
42 { .name = "DIO-II mem", .start 42 { .name = "DIO-II mem", .start = 0x01000000, .end = 0x1fffffff }
43 }, 43 },
44 .name = "DIO bus" 44 .name = "DIO bus"
45 }; 45 };
46 46
47 /* not a real config option yet! */ 47 /* not a real config option yet! */
48 #define CONFIG_DIO_CONSTANTS 48 #define CONFIG_DIO_CONSTANTS
49 49
50 #ifdef CONFIG_DIO_CONSTANTS 50 #ifdef CONFIG_DIO_CONSTANTS
51 /* We associate each numeric ID with an approp 51 /* We associate each numeric ID with an appropriate descriptive string
52 * using a constant array of these structs. 52 * using a constant array of these structs.
53 * FIXME: we should be able to arrange to thro 53 * FIXME: we should be able to arrange to throw away most of the strings
54 * using the initdata stuff. Then we wouldn't 54 * using the initdata stuff. Then we wouldn't need to worry about
55 * carrying them around... 55 * carrying them around...
56 * I think we do this by copying them into new 56 * I think we do this by copying them into newly kmalloc()ed memory and
57 * marking the names[] array as .initdata ? 57 * marking the names[] array as .initdata ?
58 */ 58 */
59 struct dioname 59 struct dioname
60 { 60 {
61 int id; 61 int id;
62 const char *name; 62 const char *name;
63 }; 63 };
64 64
65 /* useful macro */ 65 /* useful macro */
66 #define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x 66 #define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x }
67 #define DIOFBNAME(x) { DIO_ENCODE_ID( DIO_ID_F 67 #define DIOFBNAME(x) { DIO_ENCODE_ID( DIO_ID_FBUFFER, DIO_ID2_##x), DIO_DESC2_##x }
68 68
69 static struct dioname names[] = 69 static struct dioname names[] =
70 { 70 {
71 DIONAME(DCA0), DIONAME(DCA0REM), DIONA 71 DIONAME(DCA0), DIONAME(DCA0REM), DIONAME(DCA1), DIONAME(DCA1REM),
72 DIONAME(DCM), DIONAME(DCMREM), 72 DIONAME(DCM), DIONAME(DCMREM),
73 DIONAME(LAN), 73 DIONAME(LAN),
74 DIONAME(FHPIB), DIONAME(NHPIB), 74 DIONAME(FHPIB), DIONAME(NHPIB),
75 DIONAME(SCSI0), DIONAME(SCSI1), DIONAM 75 DIONAME(SCSI0), DIONAME(SCSI1), DIONAME(SCSI2), DIONAME(SCSI3),
76 DIONAME(FBUFFER), 76 DIONAME(FBUFFER),
77 DIONAME(PARALLEL), DIONAME(VME), DIONA 77 DIONAME(PARALLEL), DIONAME(VME), DIONAME(DCL), DIONAME(DCLREM),
78 DIONAME(MISC0), DIONAME(MISC1), DIONAM 78 DIONAME(MISC0), DIONAME(MISC1), DIONAME(MISC2), DIONAME(MISC3),
79 DIONAME(MISC4), DIONAME(MISC5), DIONAM 79 DIONAME(MISC4), DIONAME(MISC5), DIONAME(MISC6), DIONAME(MISC7),
80 DIONAME(MISC8), DIONAME(MISC9), DIONAM 80 DIONAME(MISC8), DIONAME(MISC9), DIONAME(MISC10), DIONAME(MISC11),
81 DIONAME(MISC12), DIONAME(MISC13), 81 DIONAME(MISC12), DIONAME(MISC13),
82 DIOFBNAME(GATORBOX), DIOFBNAME(TOPCAT) 82 DIOFBNAME(GATORBOX), DIOFBNAME(TOPCAT), DIOFBNAME(RENAISSANCE),
83 DIOFBNAME(LRCATSEYE), DIOFBNAME(HRCCAT 83 DIOFBNAME(LRCATSEYE), DIOFBNAME(HRCCATSEYE), DIOFBNAME(HRMCATSEYE),
84 DIOFBNAME(DAVINCI), DIOFBNAME(XXXCATSE 84 DIOFBNAME(DAVINCI), DIOFBNAME(XXXCATSEYE), DIOFBNAME(HYPERION),
85 DIOFBNAME(XGENESIS), DIOFBNAME(TIGER), 85 DIOFBNAME(XGENESIS), DIOFBNAME(TIGER), DIOFBNAME(YGENESIS)
86 }; 86 };
87 87
88 #undef DIONAME 88 #undef DIONAME
89 #undef DIOFBNAME 89 #undef DIOFBNAME
90 90
>> 91 #define NUMNAMES (sizeof(names) / sizeof(struct dioname))
>> 92
91 static const char *unknowndioname 93 static const char *unknowndioname
92 = "unknown DIO board -- please email < 94 = "unknown DIO board -- please email <linux-m68k@lists.linux-m68k.org>!";
93 95
94 static const char *dio_getname(int id) 96 static const char *dio_getname(int id)
95 { 97 {
96 /* return pointer to a constant string 98 /* return pointer to a constant string describing the board with given ID */
97 unsigned int i; 99 unsigned int i;
98 for (i = 0; i < ARRAY_SIZE(names); i++ !! 100 for (i = 0; i < NUMNAMES; i++)
99 if (names[i].id == id) 101 if (names[i].id == id)
100 return names[i].name; 102 return names[i].name;
101 103
102 return unknowndioname; 104 return unknowndioname;
103 } 105 }
104 106
105 #else 107 #else
106 108
107 static char dio_no_name[] = { 0 }; 109 static char dio_no_name[] = { 0 };
108 #define dio_getname(_id) (dio_no_name) 110 #define dio_getname(_id) (dio_no_name)
109 111
110 #endif /* CONFIG_DIO_CONSTANTS */ 112 #endif /* CONFIG_DIO_CONSTANTS */
111 113
112 int __init dio_find(int deviceid) 114 int __init dio_find(int deviceid)
113 { 115 {
114 /* Called to find a DIO device before 116 /* Called to find a DIO device before the full bus scan has run.
115 * Only used by the console driver. 117 * Only used by the console driver.
116 */ 118 */
117 int scode, id; 119 int scode, id;
118 u_char prid, secid, i; 120 u_char prid, secid, i;
119 mm_segment_t fs; 121 mm_segment_t fs;
120 122
121 for (scode = 0; scode < DIO_SCMAX; sco 123 for (scode = 0; scode < DIO_SCMAX; scode++) {
122 void *va; 124 void *va;
123 unsigned long pa; 125 unsigned long pa;
124 126
125 if (DIO_SCINHOLE(scode)) 127 if (DIO_SCINHOLE(scode))
126 continue; 128 continue;
127 129
128 pa = dio_scodetophysaddr(scode 130 pa = dio_scodetophysaddr(scode);
129 131
130 if (!pa) 132 if (!pa)
131 continue; 133 continue;
132 134
133 if (scode < DIOII_SCBASE) 135 if (scode < DIOII_SCBASE)
134 va = (void *)(pa + DIO 136 va = (void *)(pa + DIO_VIRADDRBASE);
135 else 137 else
136 va = ioremap(pa, PAGE_ 138 va = ioremap(pa, PAGE_SIZE);
137 139
138 fs = get_fs(); 140 fs = get_fs();
139 set_fs(KERNEL_DS); 141 set_fs(KERNEL_DS);
140 142
141 if (get_user(i, (unsigned char 143 if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
142 set_fs(fs); 144 set_fs(fs);
143 if (scode >= DIOII_SCB 145 if (scode >= DIOII_SCBASE)
144 iounmap(va); 146 iounmap(va);
145 continue; 147 continue; /* no board present at that select code */
146 } 148 }
147 149
148 set_fs(fs); 150 set_fs(fs);
149 prid = DIO_ID(va); 151 prid = DIO_ID(va);
150 152
151 if (DIO_NEEDSSECID(prid)) { 153 if (DIO_NEEDSSECID(prid)) {
152 secid = DIO_SECID(va); 154 secid = DIO_SECID(va);
153 id = DIO_ENCODE_ID(pri 155 id = DIO_ENCODE_ID(prid, secid);
154 } else 156 } else
155 id = prid; 157 id = prid;
156 158
157 if (id == deviceid) { 159 if (id == deviceid) {
158 if (scode >= DIOII_SCB 160 if (scode >= DIOII_SCBASE)
159 iounmap(va); 161 iounmap(va);
160 return scode; 162 return scode;
161 } 163 }
162 } 164 }
163 165
164 return -1; 166 return -1;
165 } 167 }
166 168
167 /* This is the function that scans the DIO spa 169 /* This is the function that scans the DIO space and works out what
168 * hardware is actually present. 170 * hardware is actually present.
169 */ 171 */
170 static int __init dio_init(void) 172 static int __init dio_init(void)
171 { 173 {
172 int scode; 174 int scode;
173 mm_segment_t fs; 175 mm_segment_t fs;
174 int i; 176 int i;
175 struct dio_dev *dev; 177 struct dio_dev *dev;
176 int error; <<
177 178
178 if (!MACH_IS_HP300) 179 if (!MACH_IS_HP300)
179 return 0; 180 return 0;
180 181
181 printk(KERN_INFO "Scanning for DIO dev 182 printk(KERN_INFO "Scanning for DIO devices...\n");
182 183
183 /* Initialize the DIO bus */ 184 /* Initialize the DIO bus */
184 INIT_LIST_HEAD(&dio_bus.devices); 185 INIT_LIST_HEAD(&dio_bus.devices);
185 dev_set_name(&dio_bus.dev, "dio"); !! 186 strcpy(dio_bus.dev.bus_id, "dio");
186 error = device_register(&dio_bus.dev); !! 187 device_register(&dio_bus.dev);
187 if (error) { <<
188 pr_err("DIO: Error registering <<
189 return error; <<
190 } <<
191 188
192 /* Request all resources */ 189 /* Request all resources */
193 dio_bus.num_resources = (hp300_model = 190 dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
194 for (i = 0; i < dio_bus.num_resources; 191 for (i = 0; i < dio_bus.num_resources; i++)
195 request_resource(&iomem_resour 192 request_resource(&iomem_resource, &dio_bus.resources[i]);
196 193
197 /* Register all devices */ 194 /* Register all devices */
198 for (scode = 0; scode < DIO_SCMAX; ++s 195 for (scode = 0; scode < DIO_SCMAX; ++scode)
199 { 196 {
200 u_char prid, secid = 0; 197 u_char prid, secid = 0; /* primary, secondary ID bytes */
201 u_char *va; 198 u_char *va;
202 unsigned long pa; 199 unsigned long pa;
203 200
204 if (DIO_SCINHOLE(scode)) 201 if (DIO_SCINHOLE(scode))
205 continue; 202 continue;
206 203
207 pa = dio_scodetophysaddr(scode 204 pa = dio_scodetophysaddr(scode);
208 205
209 if (!pa) 206 if (!pa)
210 continue; 207 continue;
211 208
212 if (scode < DIOII_SCBASE) 209 if (scode < DIOII_SCBASE)
213 va = (void *)(pa + DIO 210 va = (void *)(pa + DIO_VIRADDRBASE);
214 else 211 else
215 va = ioremap(pa, PAGE_ 212 va = ioremap(pa, PAGE_SIZE);
216 213
217 fs = get_fs(); 214 fs = get_fs();
218 set_fs(KERNEL_DS); 215 set_fs(KERNEL_DS);
219 216
220 if (get_user(i, (unsigned char 217 if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
221 set_fs(fs); 218 set_fs(fs);
222 if (scode >= DIOII_SCB 219 if (scode >= DIOII_SCBASE)
223 iounmap(va); 220 iounmap(va);
224 continue; 221 continue; /* no board present at that select code */
225 } 222 }
226 223
227 set_fs(fs); 224 set_fs(fs);
228 225
229 /* Found a board, allocate it 226 /* Found a board, allocate it an entry in the list */
230 dev = kzalloc(sizeof(struct di !! 227 dev = kmalloc(sizeof(struct dio_dev), GFP_KERNEL);
231 if (!dev) 228 if (!dev)
232 return 0; 229 return 0;
233 230
>> 231 memset(dev, 0, sizeof(struct dio_dev));
234 dev->bus = &dio_bus; 232 dev->bus = &dio_bus;
235 dev->dev.parent = &dio_bus.dev 233 dev->dev.parent = &dio_bus.dev;
236 dev->dev.bus = &dio_bus_type; 234 dev->dev.bus = &dio_bus_type;
237 dev->scode = scode; 235 dev->scode = scode;
238 dev->resource.start = pa; 236 dev->resource.start = pa;
239 dev->resource.end = pa + DIO_S 237 dev->resource.end = pa + DIO_SIZE(scode, va);
240 dev_set_name(&dev->dev, "%02x" !! 238 sprintf(dev->dev.bus_id,"%02x", scode);
241 239
242 /* read the ID byte(s) and enc 240 /* read the ID byte(s) and encode if necessary. */
243 prid = DIO_ID(va); 241 prid = DIO_ID(va);
244 242
245 if (DIO_NEEDSSECID(prid)) { 243 if (DIO_NEEDSSECID(prid)) {
246 secid = DIO_SECID(va); 244 secid = DIO_SECID(va);
247 dev->id = DIO_ENCODE_I 245 dev->id = DIO_ENCODE_ID(prid, secid);
248 } else 246 } else
249 dev->id = prid; 247 dev->id = prid;
250 248
251 dev->ipl = DIO_IPL(va); 249 dev->ipl = DIO_IPL(va);
252 strcpy(dev->name,dio_getname(d 250 strcpy(dev->name,dio_getname(dev->id));
253 printk(KERN_INFO "select code 251 printk(KERN_INFO "select code %3d: ipl %d: ID %02X", dev->scode, dev->ipl, prid);
254 if (DIO_NEEDSSECID(prid)) 252 if (DIO_NEEDSSECID(prid))
255 printk(":%02X", secid) 253 printk(":%02X", secid);
256 printk(": %s\n", dev->name); 254 printk(": %s\n", dev->name);
257 255
258 if (scode >= DIOII_SCBASE) 256 if (scode >= DIOII_SCBASE)
259 iounmap(va); 257 iounmap(va);
260 error = device_register(&dev-> !! 258 device_register(&dev->dev);
261 if (error) { !! 259 dio_create_sysfs_dev_files(dev);
262 pr_err("DIO: Error reg <<
263 dev->name); <<
264 continue; <<
265 } <<
266 error = dio_create_sysfs_dev_f <<
267 if (error) <<
268 dev_err(&dev->dev, "Er <<
269 } 260 }
270 return 0; 261 return 0;
271 } 262 }
272 263
273 subsys_initcall(dio_init); 264 subsys_initcall(dio_init);
274 265
275 /* Bear in mind that this is called in the ver 266 /* Bear in mind that this is called in the very early stages of initialisation
276 * in order to get the address of the serial p 267 * in order to get the address of the serial port for the console...
277 */ 268 */
278 unsigned long dio_scodetophysaddr(int scode) 269 unsigned long dio_scodetophysaddr(int scode)
279 { 270 {
280 if (scode >= DIOII_SCBASE) { 271 if (scode >= DIOII_SCBASE) {
281 return (DIOII_BASE + (scode - 272 return (DIOII_BASE + (scode - 132) * DIOII_DEVSIZE);
282 } else if (scode > DIO_SCMAX || scode 273 } else if (scode > DIO_SCMAX || scode < 0)
283 return 0; 274 return 0;
284 else if (DIO_SCINHOLE(scode)) 275 else if (DIO_SCINHOLE(scode))
285 return 0; 276 return 0;
286 277
287 return (DIO_BASE + scode * DIO_DEVSIZE 278 return (DIO_BASE + scode * DIO_DEVSIZE);
288 } 279 }
289 280
|
This page was automatically generated by the
LXR engine.
|