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