1 /* $NetBSD: disk.c,v 1.6 2008/04/28 20:23:18 martin Exp $ */
4 * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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>
42 #if defined(LIBSA_NO_TWIDDLE)
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
58 int format
; /* 2D/2HD */
61 int (*rw
)(uint8_t *, int, int, int);
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);
70 void __fd_progress_msg(int);
72 #define __fd_progress_msg(pos) twiddle()
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
);
87 __disk
.partition
= partition
;
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
);
99 DEVICE_CAPABILITY
.active_device
= type
;
101 /* Set actual read/write routine */
102 if (__disk
.type
== NVSRAM_BOOTDEV_HARDDISK
) {
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
;
110 printf("unknown floppy disk format %d.\n",
115 printf("unknown disk type %d.\n", __disk
.type
);
123 dkopen(struct open_file
*f
, ...)
130 dkclose(struct open_file
*f
)
137 dkstrategy(void *devdata
, int rw
, daddr_t blk
, size_t size
, void *buf
,
143 printf("%s: invalid request block %d size %d base %d\n",
144 __func__
, blk
, size
, __disk
.offset
);
148 n
= ROUND_SECTOR(size
) >> DEV_BSHIFT
;
149 if (!sector_read_n(0, buf
, __disk
.offset
+ blk
, n
))
162 device_attach(-1, -1, -1);
166 sector_fini(void *self
)
169 __disk
.active
= false;
173 sector_read_n(void *self
, uint8_t *buf
, int sector
, int count
)
176 if (!__sector_rw(buf
, sector
, 0, count
))
182 sector_read(void *self
, uint8_t *buf
, int sector
)
185 return __sector_rw(buf
, sector
, 0, 1);
189 sector_write_n(void *self
, uint8_t *buf
, int sector
, int count
)
192 if (!__sector_rw(buf
, sector
, 0x1000, count
))
198 sector_write(void *self
, uint8_t *buf
, int sector
)
201 return __sector_rw(buf
, sector
, 0x1000, 1);
205 __sector_rw(uint8_t *buf
, int block
, int flag
, int count
)
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
,
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
)
234 if (!blk_to_2d_position(block
, &pos
, &cnt
)) {
235 printf("%s: invalid block #%d.\n", __func__
, block
);
239 __fd_progress_msg(pos
);
244 err
= ROM_FD_RW(flag
| __disk
.unit
, pos
, cnt
* 2, buf
);
250 buf
+= DEV_BSIZE
* cnt
;
256 __fd_2hd_rw(uint8_t *buf
, int block
, int flag
, int count
)
262 if (!blk_to_2hd_position(block
, &pos
, &cnt
)) {
263 printf("%s: invalid block #%d.\n", __func__
, block
);
269 __fd_progress_msg(pos
);
271 err
= ROM_FD_RW(flag
| __disk
.unit
| 0x1000000, pos
, cnt
, buf
);
277 buf
+= DEV_BSIZE
* cnt
;
284 __fd_progress_msg(int pos
)
288 memset(msg
, 0, sizeof msg
);
289 sprintf(msg
, "C%d H%d S%d \r", (pos
>> 16) & 0xff, (pos
>> 8) & 0xff,