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 * ----------------------------------------------------------------------------
9 * $FreeBSD: src/sys/contrib/dev/fla/fla.c,v 1.16 1999/12/08 04:45:16 ken Exp $
10 * $DragonFly: src/sys/contrib/dev/fla/Attic/fla.c,v 1.18 2007/05/15 00:01:03 dillon Exp $
16 #include <sys/param.h>
17 #include <sys/systm.h>
18 #include <sys/sysctl.h>
19 #include <sys/kernel.h>
22 #include <sys/malloc.h>
25 #include <sys/devicestat.h>
26 #include <sys/module.h>
27 #include <machine/clock.h>
31 #include <vm/vm_param.h>
33 #include <sys/thread2.h>
36 #include <bus/isa/isavar.h>
39 #include <machine/smp.h>
40 #define LEAVE() rel_mplock();
41 #define ENTER() get_mplock();
47 #include <contrib/dev/fla/msysosak.h>
49 MALLOC_DEFINE(M_FLA, "fla driver", "fla driver storage");
51 static int fla_debug = 0;
52 SYSCTL_INT(_debug, OID_AUTO, fladebug, CTLFLAG_RW, &fla_debug, 0, "");
54 #define CDEV_MAJOR 102
57 static d_strategy_t flastrategy;
58 static d_open_t flaopen;
59 static d_close_t flaclose;
60 static d_ioctl_t flaioctl;
62 static struct dev_ops fla_ops = {
63 { "fla", CDEV_MAJOR, D_DISK | D_CANFREE },
69 .d_strategy = flastrategy,
73 doc2k_malloc(int bytes)
75 return kmalloc(bytes, M_FLA, M_WAITOK);
85 doc2k_delay(unsigned msec)
91 doc2k_memcpy(void *dst, const void *src, unsigned len)
97 doc2k_memcmp(const void *dst, const void *src, unsigned len)
99 return (bcmp(src, dst, len));
103 doc2k_memset(void *dst, int c, unsigned len)
110 static struct fla_s {
114 struct doc2k_stat ds;
115 struct bio_queue_head bio_queue;
116 struct devstat stats;
122 flaopen(struct dev_open_args *ap)
124 cdev_t dev = ap->a_head.a_dev;
127 struct disk_info info;
128 u_int secperunit = 0;
129 u_int secpertrack = 0;
130 u_int ncylinders = 0;
134 kprintf("flaopen(%s %x %x)\n",
135 devtoname(dev), ap->a_oflags, ap->a_devtype);
139 error = doc2k_open(sc->unit);
142 kprintf("doc2k_open(%d) -> err %d\n", sc->unit, error);
146 bzero(&info, sizeof(info));
147 error = doc2k_size(sc->unit, &secperunit, &ncylinders,
148 &nheads, &secpertrack);
149 info.d_media_blksize = DEV_BSIZE;
151 info.d_media_blocks = secperunit;
152 info.d_media_size = 0;
153 info.d_nheads = nheads;
154 info.d_ncylinders = ncylinders;
155 info.d_secpertrack = secpertrack;
156 info.d_secpercyl = nheads * secpertrack; /* XXX */
158 disk_setdiskinfo(&sc->disk, &info);
163 flaclose(struct dev_close_args *ap)
165 cdev_t dev = ap->a_head.a_dev;
170 kprintf("flaclose(%s %x %x)\n",
171 devtoname(dev), ap->a_fflag, ap->a_devtype);
175 error = doc2k_close(sc->unit);
177 kprintf("doc2k_close(%d) -> err %d\n", sc->unit, error);
184 flaioctl(struct dev_ioctl_args *ap)
186 cdev_t dev = ap->a_head.a_dev;
189 kprintf("flaioctl(%s %lx %p %x)\n",
190 devtoname(dev), ap->a_cmd, ap->a_data, ap->a_fflag);
196 flastrategy(struct dev_strategy_args *ap)
198 cdev_t dev = ap->a_head.a_dev;
199 struct bio *bio = ap->a_bio;
200 struct buf *bp = bio->bio_buf;
203 enum doc2k_work what;
206 kprintf("flastrategy(%p) %s %x, %lld, %d, %p)\n",
207 bp, devtoname(dev), bp->b_flags, bio->bio_offset,
208 bp->b_bcount, bp->b_data);
212 bio->bio_driver_info = dev;
214 bioqdisksort(&sc->bio_queue, bio);
222 bio = bioq_first(&sc->bio_queue);
227 bioq_remove(&sc->bio_queue, bio);
229 dev = bio->bio_driver_info;
231 devstat_start_transaction(&sc->stats);
232 bp->b_resid = bp->b_bcount;
236 case BUF_CMD_FREEBLKS:
246 panic("fla: bad b_cmd %d", bp->b_cmd);
251 error = doc2k_rwe(unit, what,
252 (unsigned)(bio->bio_offset >> DEV_BSHIFT),
253 bp->b_bcount / DEV_BSIZE, bp->b_data);
257 if (fla_debug > 1 || error) {
258 kprintf("fla%d: %d = rwe(%p, %d, %d, %lld, %d, %p)\n",
259 unit, error, bp, unit, what, bio->bio_offset,
260 bp->b_bcount, bp->b_data);
264 bp->b_flags |= B_ERROR;
268 devstat_end_transaction_buf(&sc->stats, bp);
278 flaprobe (device_t dev)
284 unit = device_get_unit(dev);
287 /* This is slightly ugly */
288 i = doc2k_probe(unit, KERNBASE + 0xc0000, KERNBASE + 0xe0000);
292 i = doc2k_info(unit, &sc->ds);
296 bus_set_resource(dev, SYS_RES_MEMORY, 0,
297 sc->ds.window - KERNBASE, 8192);
303 flaattach (device_t dev)
306 int i, j, k, l, m, error;
309 unit = device_get_unit(dev);
312 error = doc2k_open(unit);
314 kprintf("doc2k_open(%d) -> err %d\n", unit, error);
318 error = doc2k_size(unit, &sc->nsect, &i, &j, &k );
320 kprintf("doc2k_size(%d) -> err %d\n", unit, error);
324 kprintf("fla%d: <%s %s>\n", unit, sc->ds.product, sc->ds.model);
326 error = doc2k_close(unit);
328 kprintf("doc2k_close(%d) -> err %d\n", unit, error);
332 m = 1024L * 1024L / DEV_BSIZE;
333 l = (sc->nsect * 10 + m/2) / m;
334 kprintf("fla%d: %d.%01dMB (%u sectors),"
335 " %d cyls, %d heads, %d S/T, 512 B/S\n",
336 unit, l / 10, l % 10, sc->nsect, i, j, k);
339 kprintf("fla%d: JEDEC=0x%x unitsize=%ld mediasize=%ld"
340 " chipsize=%ld interleave=%d window=%lx\n",
341 unit, sc->ds.type, sc->ds.unitSize, sc->ds.mediaSize,
342 sc->ds.chipSize, sc->ds.interleaving, sc->ds.window);
344 bioq_init(&sc->bio_queue);
346 devstat_add_entry(&softc[unit].stats, "fla", unit, DEV_BSIZE,
347 DEVSTAT_NO_ORDERED_TAGS,
348 DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER,
349 DEVSTAT_PRIORITY_DISK);
351 sc->dev = disk_create(unit, &sc->disk, &fla_ops);
352 sc->dev->si_drv1 = sc;
358 static device_method_t fla_methods[] = {
359 /* Device interface */
360 DEVMETHOD(device_probe, flaprobe),
361 DEVMETHOD(device_attach, flaattach),
365 static driver_t fladriver = {
368 sizeof(struct fla_s),
371 static devclass_t fla_devclass;
373 DRIVER_MODULE(fla, isa, fladriver, fla_devclass, 0, 0);