Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / ews4800mips / stand / common / disk.c
blobe8e21e8a7b51aad29745ec97438533317d38ed80
1 /* $NetBSD: disk.c,v 1.6 2008/04/28 20:23:18 martin Exp $ */
3 /*-
4 * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <lib/libsa/stand.h>
33 #include <lib/libkern/libkern.h>
35 #include <machine/param.h>
36 #include <machine/sbd.h>
37 #include <machine/sector.h>
39 #include "local.h"
40 #include "common.h"
42 #if defined(LIBSA_NO_TWIDDLE)
43 #define twiddle()
44 #endif
46 int dkopen(struct open_file *, ...);
47 int dkclose(struct open_file *);
48 int dkstrategy(void *, int, daddr_t, size_t, void *, size_t *);
50 struct devsw dkdevsw = {
51 "dk", dkstrategy, dkopen, dkclose, noioctl
54 struct disk {
55 bool active;
56 int type; /* FD/HD */
57 int unit;
58 int format; /* 2D/2HD */
59 int partition;
60 int offset;
61 int (*rw)(uint8_t *, int, int, int);
62 } __disk;
64 void sector_init(void);
65 bool __sector_rw(uint8_t *, int, int, int);
66 int __hd_rw(uint8_t *, int, int, int);
67 int __fd_2d_rw(uint8_t *, int, int, int);
68 int __fd_2hd_rw(uint8_t *, int, int, int);
69 #ifdef DEBUG
70 void __fd_progress_msg(int);
71 #else
72 #define __fd_progress_msg(pos) twiddle()
73 #endif
75 bool
76 device_attach(int type, int unit, int partition)
79 /* Inquire boot device type and unit from NVSRAM */
80 boot_device(&__disk.type, &__disk.unit, &__disk.format);
82 if (type >= 0)
83 __disk.type = type;
84 if (unit >= 0)
85 __disk.unit = unit;
87 __disk.partition = partition;
89 __disk.active = true;
90 __disk.offset = 0;
92 if (partition >= 0) {
93 if (!find_partition_start(__disk.partition, &__disk.offset)) {
94 printf("type %d, unit %d partition %d not found.\n",
95 __disk.type, __disk.unit, __disk.partition);
96 return false;
99 DEVICE_CAPABILITY.active_device = type;
101 /* Set actual read/write routine */
102 if (__disk.type == NVSRAM_BOOTDEV_HARDDISK) {
103 __disk.rw = __hd_rw;
104 } else if (__disk.type == NVSRAM_BOOTDEV_FLOPPYDISK) {
105 if (__disk.format == FD_FORMAT_2HD) {
106 __disk.rw = __fd_2hd_rw;
107 } else if (__disk.format == FD_FORMAT_2D) {
108 __disk.rw = __fd_2d_rw;
109 } else {
110 printf("unknown floppy disk format %d.\n",
111 __disk.format);
112 return false;
114 } else {
115 printf("unknown disk type %d.\n", __disk.type);
116 return false;
119 return true;
123 dkopen(struct open_file *f, ...)
126 return 0;
130 dkclose(struct open_file *f)
133 return 0;
137 dkstrategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf,
138 size_t *rsize)
140 int n;
142 if ((int)size < 0) {
143 printf("%s: invalid request block %d size %d base %d\n",
144 __func__, blk, size, __disk.offset);
145 return -1;
148 n = ROUND_SECTOR(size) >> DEV_BSHIFT;
149 if (!sector_read_n(0, buf, __disk.offset + blk, n))
150 return -1;
152 *rsize = size;
154 return 0;
157 void
158 sector_init(void)
161 if (!__disk.active)
162 device_attach(-1, -1, -1);
165 void
166 sector_fini(void *self)
169 __disk.active = false;
172 bool
173 sector_read_n(void *self, uint8_t *buf, int sector, int count)
176 if (!__sector_rw(buf, sector, 0, count))
177 return false;
178 return true;
181 bool
182 sector_read(void *self, uint8_t *buf, int sector)
185 return __sector_rw(buf, sector, 0, 1);
188 bool
189 sector_write_n(void *self, uint8_t *buf, int sector, int count)
192 if (!__sector_rw(buf, sector, 0x1000, count))
193 return false;
194 return true;
197 bool
198 sector_write(void *self, uint8_t *buf, int sector)
201 return __sector_rw(buf, sector, 0x1000, 1);
204 bool
205 __sector_rw(uint8_t *buf, int block, int flag, int count)
207 int err;
209 if (!__disk.active)
210 sector_init();
212 if ((err = __disk.rw(buf, block, flag, count)) != 0)
213 printf("%s: type=%d unit=%d offset=%d block=%d err=%d\n",
214 __func__, __disk.type, __disk.unit, __disk.offset,
215 block, err);
217 return err == 0;
221 __hd_rw(uint8_t *buf, int block, int flag, int count)
224 return (ROM_DK_RW(flag | __disk.unit, block, count, buf) & 0x7f);
228 __fd_2d_rw(uint8_t *buf, int block, int flag, int count)
230 int cnt, err;
231 uint32_t pos;
233 while (count > 0) {
234 if (!blk_to_2d_position(block, &pos, &cnt)) {
235 printf("%s: invalid block #%d.\n", __func__, block);
236 return -1;
239 __fd_progress_msg(pos);
241 if (cnt > count)
242 cnt = count;
244 err = ROM_FD_RW(flag | __disk.unit, pos, cnt * 2, buf);
245 if (err)
246 return err;
248 count -= cnt;
249 block += cnt;
250 buf += DEV_BSIZE * cnt;
252 return 0;
256 __fd_2hd_rw(uint8_t *buf, int block, int flag, int count)
258 int cnt, err;
259 uint32_t pos;
261 while (count > 0) {
262 if (!blk_to_2hd_position(block, &pos, &cnt)) {
263 printf("%s: invalid block #%d.\n", __func__, block);
264 return -1;
266 if (cnt > count)
267 cnt = count;
269 __fd_progress_msg(pos);
271 err = ROM_FD_RW(flag | __disk.unit | 0x1000000, pos, cnt, buf);
272 if (err)
273 return err;
275 count -= cnt;
276 block += cnt;
277 buf += DEV_BSIZE * cnt;
279 return 0;
282 #ifdef DEBUG
283 void
284 __fd_progress_msg(int pos)
286 char msg[16];
288 memset(msg, 0, sizeof msg);
289 sprintf(msg, "C%d H%d S%d \r", (pos >> 16) & 0xff, (pos >> 8) & 0xff,
290 pos & 0xff);
291 printf("%s", msg);
293 #endif