Do a major clean-up of the BUSDMA architecture. A large number of
[dragonfly.git] / sys / contrib / dev / fla / fla.c
CommitLineData
984263bc
MD
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 *
9 * $FreeBSD: src/sys/contrib/dev/fla/fla.c,v 1.16 1999/12/08 04:45:16 ken Exp $
1f7ab7c9 10 * $DragonFly: src/sys/contrib/dev/fla/Attic/fla.c,v 1.16 2006/10/25 20:55:52 dillon Exp $
984263bc
MD
11 *
12 */
13
1f2de5d4
MD
14#include "use_fla.h"
15
984263bc
MD
16#include <sys/param.h>
17#include <sys/systm.h>
18#include <sys/sysctl.h>
19#include <sys/kernel.h>
7b95be2a 20#include <sys/proc.h>
984263bc
MD
21#include <sys/buf.h>
22#include <sys/malloc.h>
23#include <sys/conf.h>
24#include <sys/disk.h>
25#include <sys/devicestat.h>
26#include <sys/module.h>
27#include <machine/clock.h>
984263bc
MD
28
29#include <vm/vm.h>
30#include <vm/pmap.h>
31#include <vm/vm_param.h>
7b95be2a 32#include <sys/buf2.h>
831f78e5 33#include <sys/thread2.h>
984263bc
MD
34
35#include <sys/bus.h>
1f2de5d4 36#include <bus/isa/isavar.h>
984263bc
MD
37
38#ifdef SMP
39#include <machine/smp.h>
40#define LEAVE() rel_mplock();
41#define ENTER() get_mplock();
42#else
43#define LEAVE()
44#define ENTER()
45#endif
46
47#include <contrib/dev/fla/msysosak.h>
48
49MALLOC_DEFINE(M_FLA, "fla driver", "fla driver storage");
50
51static int fla_debug = 0;
52SYSCTL_INT(_debug, OID_AUTO, fladebug, CTLFLAG_RW, &fla_debug, 0, "");
53
54#define CDEV_MAJOR 102
55#define BDEV_MAJOR 28
56
57static d_strategy_t flastrategy;
58static d_open_t flaopen;
59static d_close_t flaclose;
60static d_ioctl_t flaioctl;
61
fef8985e
MD
62static struct dev_ops fla_ops = {
63 { "fla", CDEV_MAJOR, D_DISK | D_CANFREE },
64 .d_open = flaopen,
65 .d_close = flaclose,
66 .d_read = physread,
67 .d_write = physwrite,
68 .d_ioctl = flaioctl,
69 .d_strategy = flastrategy,
984263bc 70};
984263bc
MD
71
72void *
73doc2k_malloc(int bytes)
74{
efda3bd0 75 return kmalloc(bytes, M_FLA, M_WAITOK);
984263bc
MD
76}
77
78void
79doc2k_free(void *ptr)
80{
efda3bd0 81 kfree(ptr, M_FLA);
984263bc
MD
82}
83
84void
85doc2k_delay(unsigned msec)
86{
87 DELAY(1000 * msec);
88}
89
90void
91doc2k_memcpy(void *dst, const void *src, unsigned len)
92{
93 bcopy(src, dst, len);
94}
95
96int
97doc2k_memcmp(const void *dst, const void *src, unsigned len)
98{
99 return (bcmp(src, dst, len));
100}
101
102void
103doc2k_memset(void *dst, int c, unsigned len)
104{
105 u_char *p = dst;
106 while (len--)
107 *p++ = c;
108}
109
110static struct fla_s {
111 int busy;
112 int unit;
113 unsigned nsect;
114 struct doc2k_stat ds;
81b5c339 115 struct bio_queue_head bio_queue;
984263bc
MD
116 struct devstat stats;
117 struct disk disk;
b13267a5 118 cdev_t dev;
984263bc
MD
119} softc[NFLA];
120
121static int
fef8985e 122flaopen(struct dev_open_args *ap)
984263bc 123{
b13267a5 124 cdev_t dev = ap->a_head.a_dev;
984263bc
MD
125 struct fla_s *sc;
126 int error;
127 struct disklabel *dl;
128
129 if (fla_debug)
fef8985e
MD
130 printf("flaopen(%s %x %x)\n",
131 devtoname(dev), ap->a_oflags, ap->a_devtype);
984263bc
MD
132
133 sc = dev->si_drv1;
134
135 error = doc2k_open(sc->unit);
136
137 if (error) {
138 printf("doc2k_open(%d) -> err %d\n", sc->unit, error);
139 return (EIO);
140 }
141
142 dl = &sc->disk.d_label;
143 bzero(dl, sizeof(*dl));
144 error = doc2k_size(sc->unit, &dl->d_secperunit,
145 &dl->d_ncylinders, &dl->d_ntracks, &dl->d_nsectors);
146 dl->d_secsize = DEV_BSIZE;
147 dl->d_secpercyl = dl->d_ntracks * dl->d_nsectors; /* XXX */
148
149 return (0);
150}
151
152static int
fef8985e 153flaclose(struct dev_close_args *ap)
984263bc 154{
b13267a5 155 cdev_t dev = ap->a_head.a_dev;
984263bc
MD
156 int error;
157 struct fla_s *sc;
158
159 if (fla_debug)
fef8985e
MD
160 printf("flaclose(%s %x %x)\n",
161 devtoname(dev), ap->a_fflag, ap->a_devtype);
984263bc
MD
162
163 sc = dev->si_drv1;
164
165 error = doc2k_close(sc->unit);
166 if (error) {
167 printf("doc2k_close(%d) -> err %d\n", sc->unit, error);
168 return (EIO);
169 }
170 return (0);
171}
172
173static int
fef8985e 174flaioctl(struct dev_ioctl_args *ap)
984263bc 175{
b13267a5 176 cdev_t dev = ap->a_head.a_dev;
984263bc
MD
177
178 if (fla_debug)
fef8985e
MD
179 printf("flaioctl(%s %lx %p %x)\n",
180 devtoname(dev), ap->a_cmd, ap->a_data, ap->a_fflag);
984263bc
MD
181
182 return (ENOIOCTL);
183}
184
fef8985e
MD
185static int
186flastrategy(struct dev_strategy_args *ap)
984263bc 187{
b13267a5 188 cdev_t dev = ap->a_head.a_dev;
fef8985e 189 struct bio *bio = ap->a_bio;
81b5c339 190 struct buf *bp = bio->bio_buf;
984263bc 191 int unit, error;
984263bc
MD
192 struct fla_s *sc;
193 enum doc2k_work what;
194
81b5c339 195 if (fla_debug > 1) {
fef8985e
MD
196 printf("flastrategy(%p) %s %x, %lld, %d, %p)\n",
197 bp, devtoname(dev), bp->b_flags, bio->bio_offset,
198 bp->b_bcount, bp->b_data);
81b5c339 199 }
984263bc 200
81b5c339
MD
201 sc = dev->si_drv1;
202 bio->bio_driver_info = dev;
1a5f156c 203 crit_enter();
81b5c339 204 bioqdisksort(&sc->bio_queue, bio);
984263bc 205 if (sc->busy) {
1a5f156c 206 crit_exit();
fef8985e 207 return(0);
984263bc 208 }
984263bc
MD
209 sc->busy++;
210
211 while (1) {
81b5c339
MD
212 bio = bioq_first(&sc->bio_queue);
213 if (bio == NULL) {
214 crit_exit();
984263bc 215 break;
81b5c339
MD
216 }
217 bioq_remove(&sc->bio_queue, bio);
218 bp = bio->bio_buf;
219 dev = bio->bio_driver_info;
984263bc
MD
220
221 devstat_start_transaction(&sc->stats);
222 bp->b_resid = bp->b_bcount;
81b5c339 223 unit = dkunit(dev);
984263bc 224
10f3fee5
MD
225 switch(bp->b_cmd) {
226 case BUF_CMD_FREEBLKS:
984263bc 227 what = DOC2K_ERASE;
10f3fee5
MD
228 break;
229 case BUF_CMD_READ:
984263bc 230 what = DOC2K_READ;
10f3fee5
MD
231 break;
232 case BUF_CMD_WRITE:
984263bc 233 what = DOC2K_WRITE;
10f3fee5
MD
234 break;
235 default:
236 panic("fla: bad b_cmd %d", bp->b_cmd);
237 }
984263bc
MD
238
239 LEAVE();
240
54078292
MD
241 error = doc2k_rwe(unit, what,
242 (unsigned)(bio->bio_offset >> DEV_BSHIFT),
81b5c339 243 bp->b_bcount / DEV_BSIZE, bp->b_data);
984263bc
MD
244
245 ENTER();
246
247 if (fla_debug > 1 || error) {
fef8985e 248 printf("fla%d: %d = rwe(%p, %d, %d, %lld, %d, %p)\n",
54078292
MD
249 unit, error, bp, unit, what, bio->bio_offset,
250 bp->b_bcount, bp->b_data);
984263bc
MD
251 }
252 if (error) {
253 bp->b_error = EIO;
254 bp->b_flags |= B_ERROR;
255 } else {
256 bp->b_resid = 0;
257 }
258 devstat_end_transaction_buf(&sc->stats, bp);
81b5c339 259 biodone(bio);
984263bc 260
1a5f156c 261 crit_enter();
984263bc
MD
262 }
263 sc->busy = 0;
fef8985e 264 return(0);
984263bc
MD
265}
266
267static int
268flaprobe (device_t dev)
269{
270 int unit;
271 struct fla_s *sc;
272 int i;
273
274 unit = device_get_unit(dev);
275 sc = &softc[unit];
276
277 /* This is slightly ugly */
278 i = doc2k_probe(unit, KERNBASE + 0xc0000, KERNBASE + 0xe0000);
279 if (i)
280 return (ENXIO);
281
282 i = doc2k_info(unit, &sc->ds);
283 if (i)
284 return (ENXIO);
285
286 bus_set_resource(dev, SYS_RES_MEMORY, 0,
287 sc->ds.window - KERNBASE, 8192);
288
289 return (0);
290}
291
292static int
293flaattach (device_t dev)
294{
295 int unit;
296 int i, j, k, l, m, error;
297 struct fla_s *sc;
298
299 unit = device_get_unit(dev);
300 sc = &softc[unit];
301
302 error = doc2k_open(unit);
303 if (error) {
304 printf("doc2k_open(%d) -> err %d\n", unit, error);
305 return (EIO);
306 }
307
308 error = doc2k_size(unit, &sc->nsect, &i, &j, &k );
309 if (error) {
310 printf("doc2k_size(%d) -> err %d\n", unit, error);
311 return (EIO);
312 }
313
314 printf("fla%d: <%s %s>\n", unit, sc->ds.product, sc->ds.model);
315
316 error = doc2k_close(unit);
317 if (error) {
318 printf("doc2k_close(%d) -> err %d\n", unit, error);
319 return (EIO);
320 }
321
322 m = 1024L * 1024L / DEV_BSIZE;
323 l = (sc->nsect * 10 + m/2) / m;
324 printf("fla%d: %d.%01dMB (%u sectors),"
325 " %d cyls, %d heads, %d S/T, 512 B/S\n",
326 unit, l / 10, l % 10, sc->nsect, i, j, k);
327
328 if (bootverbose)
329 printf("fla%d: JEDEC=0x%x unitsize=%ld mediasize=%ld"
330 " chipsize=%ld interleave=%d window=%lx\n",
331 unit, sc->ds.type, sc->ds.unitSize, sc->ds.mediaSize,
332 sc->ds.chipSize, sc->ds.interleaving, sc->ds.window);
333
81b5c339 334 bioq_init(&sc->bio_queue);
984263bc
MD
335
336 devstat_add_entry(&softc[unit].stats, "fla", unit, DEV_BSIZE,
337 DEVSTAT_NO_ORDERED_TAGS,
338 DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER,
339 DEVSTAT_PRIORITY_DISK);
340
fef8985e 341 sc->dev = disk_create(unit, &sc->disk, 0, &fla_ops);
984263bc
MD
342 sc->dev->si_drv1 = sc;
343 sc->unit = unit;
344
345 return (0);
346}
347
348static device_method_t fla_methods[] = {
349 /* Device interface */
350 DEVMETHOD(device_probe, flaprobe),
351 DEVMETHOD(device_attach, flaattach),
352 {0, 0}
353};
354
355static driver_t fladriver = {
356 "fla",
357 fla_methods,
358 sizeof(struct fla_s),
359};
360
361static devclass_t fla_devclass;
362
363DRIVER_MODULE(fla, isa, fladriver, fla_devclass, 0, 0);