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