1 /* $NetBSD: md_root.c,v 1.32 2009/07/07 15:15:35 tsutsui Exp $ */
4 * Copyright (c) 1996 Leo Weppelman.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: md_root.c,v 1.32 2009/07/07 15:15:35 tsutsui Exp $");
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/malloc.h>
37 #include <sys/device.h>
38 #include <sys/ioctl.h>
39 #include <sys/fcntl.h>
41 #include <sys/disklabel.h>
43 #include <sys/dkbad.h>
48 #include <atari/atari/device.h>
53 #define RAMD_CHUNK (9 * 512) /* Chunk-size for auto-load */
54 #define RAMD_NDEV 3 /* Number of devices configured */
57 u_long ramd_size
; /* Size of disk in bytes */
58 u_long ramd_flag
; /* see defs below */
59 dev_t ramd_dev
; /* device to load from */
65 #define RAMD_LOAD 0x01 /* Auto load when first opened */
66 #define RAMD_LCOMP 0x02 /* Input is compressed */
68 struct ramd_info rd_info
[RAMD_NDEV
] = {
70 1105920, /* 1Mb in 2160 sectors */
71 RAMD_LOAD
, /* auto-load this device */
72 MAKEDISKDEV(2, 0, 2), /* XXX: This is crap! (720Kb flop) */
75 1474560, /* 1.44Mb in 2880 sectors */
76 RAMD_LOAD
, /* auto-load this device */
77 MAKEDISKDEV(2, 0, 2), /* XXX: This is crap! (720Kb flop) */
80 1474560, /* 1.44Mb in 2880 sectors */
81 RAMD_LOAD
, /* auto-load this device */
82 MAKEDISKDEV(2, 0, 3), /* XXX: This is crap! (1.44Mb flop) */
87 struct buf
*bp
; /* buffer for strategy function */
88 long nbytes
; /* total number of bytes to read */
89 long offset
; /* offset in input medium */
90 char *bufp
; /* current output buffer */
91 char *ebufp
; /* absolute maximum for bufp */
92 int chunk
; /* chunk size on input medium */
93 int media_sz
; /* size of input medium */
94 void (*strat
)(struct buf
*); /* strategy function for read */
98 static int loaddisk(struct md_conf
*, dev_t ld_dev
, struct lwp
*);
99 static int ramd_norm_read(struct read_info
*);
101 #ifdef support_compression
102 static int cpy_uncompressed(void *, int, struct read_info
*);
103 static int md_compressed(void *, int, struct read_info
*);
107 * This is called during autoconfig.
110 md_attach_hook(int unit
, struct md_conf
*md
)
113 if (atari_realconfig
&& (unit
< RAMD_NDEV
) && rd_info
[unit
].ramd_flag
) {
114 printf ("md%d: %sauto-load on open. Size %ld bytes.\n", unit
,
115 rd_info
[unit
].ramd_flag
& RAMD_LCOMP
? "decompress/" : "",
116 rd_info
[unit
].ramd_size
);
117 md
->md_type
= MD_UNCONFIGURED
; /* Paranoia... */
122 md_open_hook(int unit
, struct md_conf
*md
)
124 struct ramd_info
*ri
;
126 if (unit
>= RAMD_NDEV
)
130 if (md
->md_type
!= MD_UNCONFIGURED
)
131 return; /* Only configure once */
132 md
->md_addr
= malloc(ri
->ramd_size
, M_DEVBUF
, M_WAITOK
);
133 md
->md_size
= ri
->ramd_size
;
134 if (md
->md_addr
== NULL
)
136 if (ri
->ramd_flag
& RAMD_LOAD
) {
137 if (loaddisk(md
, ri
->ramd_dev
, curlwp
)) {
138 free(md
->md_addr
, M_DEVBUF
);
143 md
->md_type
= MD_KMEM_ALLOCATED
;
147 loaddisk(struct md_conf
*md
, dev_t ld_dev
, struct lwp
*lwp
)
151 const struct bdevsw
*bdp
;
155 bdp
= bdevsw_lookup(ld_dev
);
160 * Initialize our buffer header:
162 buf
= getiobuf(NULL
, false);
163 buf
->b_cflags
= BC_BUSY
;
166 buf
->b_proc
= lwp
->l_proc
;
172 rs
.nbytes
= md
->md_size
;
174 rs
.bufp
= md
->md_addr
;
175 rs
.ebufp
= (char *)md
->md_addr
+ md
->md_size
;
176 rs
.chunk
= RAMD_CHUNK
;
177 rs
.media_sz
= md
->md_size
;
178 rs
.strat
= bdp
->d_strategy
;
181 * Open device and try to get some statistics.
183 if ((error
= bdp
->d_open(ld_dev
, FREAD
| FNONBLOCK
, 0, lwp
)) != 0) {
187 if (bdp
->d_ioctl(ld_dev
, DIOCGDINFO
, (void *)&dl
, FREAD
, lwp
) == 0) {
188 /* Read on a cylinder basis */
189 rs
.chunk
= dl
.d_secsize
* dl
.d_secpercyl
;
190 rs
.media_sz
= dl
.d_secperunit
* dl
.d_secsize
;
193 #ifdef support_compression
194 if (ri
->ramd_flag
& RAMD_LCOMP
)
195 error
= decompress(cpy_uncompressed
, md_compressed
, &rs
);
197 #endif /* support_compression */
198 error
= ramd_norm_read(&rs
);
200 bdp
->d_close(ld_dev
, FREAD
| FNONBLOCK
, 0, lwp
);
206 ramd_norm_read(struct read_info
*rsp
)
213 bytes_left
= rsp
->nbytes
;
217 while (bytes_left
> 0) {
218 bp
->b_cflags
= BC_BUSY
;
219 bp
->b_flags
= B_PHYS
| B_READ
;
220 bp
->b_oflags
&= ~BO_DONE
;
221 bp
->b_blkno
= btodb(rsp
->offset
);
222 bp
->b_bcount
= min(rsp
->chunk
, bytes_left
);
223 bp
->b_data
= rsp
->bufp
;
229 /* Wait for results */
238 done
= bp
->b_bcount
- bp
->b_resid
;
247 if ((rsp
->offset
== rsp
->media_sz
) && (bytes_left
!= 0)) {
248 printf("\nInsert next media and hit any key...");
258 #ifdef support_compression
260 * Functions supporting uncompression:
263 * Copy from the uncompression buffer to the ramdisk
266 cpy_uncompressed(void * buf
, int nbyte
, struct read_info
*rsp
)
269 if ((rsp
->bufp
+ nbyte
) >= rsp
->ebufp
)
271 memcpy(rsp
->bufp
, buf
, nbyte
);
277 * Read a maximum of 'nbyte' bytes into 'buf'.
280 md_compressed(void * buf
, int nbyte
, struct read_info
*rsp
)
290 nbyte
&= ~(DEV_BSIZE
- 1);
293 bp
->b_cflags
= BC_BUSY
;
294 bp
->b_flags
= B_PHYS
| B_READ
;
295 bp
->b_oflags
&= ~BO_DONE
;
296 bp
->b_blkno
= btodb(rsp
->offset
);
297 bp
->b_bcount
= min(rsp
->chunk
, nbyte
);
304 /* Wait for results */
313 done
= bp
->b_bcount
- bp
->b_resid
;
322 if ((rsp
->offset
== rsp
->media_sz
) && (nbyte
!= 0)) {
323 printf("\nInsert next media and hit any key...");
324 if (cngetc() != '\n')
331 #endif /* support_compression */