1 /* $NetBSD: diskio.c,v 1.2 2009/03/14 15:36:04 dsl Exp $ */
4 * Copyright (c) 1995 Waldi Ravens.
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.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Waldi Ravens.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/types.h>
47 u_int32_t part_start
[16];
51 u_int16_t P_max_sector
;
52 u_int32_t reserved
[16];
55 static char * strbd
PROTO((char *, ...));
56 static int setmami
PROTO((disk_t
*, char *));
57 static int setnames
PROTO((disk_t
*));
58 static int setsizes
PROTO((disk_t
*));
59 static int ahdi_compatible
PROTO((void));
66 dd
= xmalloc(sizeof *dd
);
67 memset(dd
, 0, sizeof *dd
);
69 if (setmami(dd
, name
) || setnames(dd
) || setsizes(dd
)) {
77 disk_close(disk_t
*dd
)
83 if (dd
->xtra_info
!= NULL
)
90 disk_read(dd
, start
, count
)
99 buffer
= xmalloc(count
* dd
->bsize
);
101 e
= XHReadWrite(dd
->major
, dd
->minor
, 0, start
, count
, buffer
);
104 if (e
== -32 || (e
== -1 && XHGetVersion() == -1)) {
105 if (!ahdi_compatible())
106 fatal(-1, "AHDI 3.0 compatible harddisk driver required");
107 bdev
= BIOSDEV(dd
->major
, dd
->minor
);
108 if (bdev
&& !bios_read(buffer
, start
, count
, bdev
))
117 disk_write(dd
, start
, count
, buffer
)
126 e
= XHReadWrite(dd
->major
, dd
->minor
, 1, start
, count
, buffer
);
127 if (e
== -32 || (e
== -1 && XHGetVersion() == -1)) {
128 if (!ahdi_compatible())
129 fatal(-1, "AHDI 3.0 compatible harddisk driver required");
130 bdev
= BIOSDEV(dd
->major
, dd
->minor
);
132 e
= bios_write(buffer
, start
, count
, bdev
);
139 ahdi_compatible(void)
141 static int ahdi_compat
;
144 long oldsp
= Super(0L);
145 struct pun_info
*punp
= *((struct pun_info
**)0x0516);
147 if (punp
&& punp
->P_cookie
== 0x41484449
148 && punp
->P_cookptr
== &punp
->P_cookie
149 && punp
->P_version
>= 0x0300)
156 setmami(disk_t
*dd
, char *name
)
164 if (*++p
< '0' || *p
> '1') {
166 error(-1, "%s: invalid IDE target `%c'", name
, *p
);
168 error(-1, "%s: missing IDE target", name
);
179 } else if (*p
== 's') {
183 error(-1, "%s: invalid DISK argument", name
);
186 if (*++p
< '0' || *p
> '7') {
188 error(-1, "%s: invalid %s target `%c'", name
,
191 error(-1, "%s: missing %s target", name
, b
);
196 if (*p
< '0' || *p
> '7') {
198 error(-1, "%s: invalid %s lun `%c'", name
,
207 error(-1, "%s: invalid DISK argument", name
);
210 dd
->major
= MAJOR(bus
, target
, lun
);
211 dd
->minor
= MINOR(bus
, target
, lun
);
218 char sn
[16], us
[16], ls
[16], *bs
;
221 b
= BUS(dd
->major
, dd
->minor
);
222 u
= TARGET(dd
->major
, dd
->minor
);
223 l
= LUN(dd
->major
, dd
->minor
);
226 case IDE
: bs
= "IDE";
228 case ACSI
: bs
= "ACSI";
230 case SCSI
: bs
= "SCSI";
232 default: error(-1, "invalid bus no. %d", b
);
236 if (u
< 0 || u
> 7 || (b
== IDE
&& u
> 1)) {
237 error(-1, "invalid %s target `%d'", bs
, u
);
240 sprintf(us
, " target %d", u
);
242 if (l
< 0 || l
> 7 || (b
== IDE
&& l
> 0)) {
243 error(-1, "invalid %s lun `%d'", bs
, l
);
247 sprintf(sn
, "i%d", u
);
250 sprintf(sn
, "%c%d%d", tolower(*bs
), u
, l
);
251 sprintf(ls
, " lun %d", l
);
254 dd
->fname
= strbd(bs
, us
, ls
, NULL
);
255 dd
->sname
= strbd(sn
, NULL
);
262 if (XHGetVersion() != -1) {
265 if (XHInqTarget2(dd
->major
, dd
->minor
, &dd
->bsize
, NULL
, prod
,
267 if (XHInqTarget(dd
->major
, dd
->minor
, &dd
->bsize
, NULL
, prod
)) {
268 error(-1, "%s: device not configured", dd
->sname
);
272 p
= strrchr(prod
, '\0');
273 while (isspace(*--p
))
275 dd
->product
= strbd(prod
, NULL
);
276 if (!XHGetCapacity(dd
->major
, dd
->minor
, &dd
->msize
, &dd
->bsize
))
279 dd
->product
= strbd("unknown", NULL
);
280 dd
->bsize
= AHDI_BSIZE
; /* XXX */
283 /* Trial&error search for last sector on medium */
286 void *p
, (*oldvec
)();
288 /* turn off etv_critic handler */
289 oldvec
= Setexc(257, bios_critic
);
291 u
= (u_int
)-2; l
= 0;
293 m
= l
+ ((u
- l
+ 1) / 2);
294 p
= disk_read(dd
, m
, 1);
302 /* turn on etv_critic handler */
303 (void)Setexc(257, oldvec
);
309 error(-1, "%s: device not configured", dd
->sname
);
321 va_start(ap
, string1
);
322 for (p
= string1
; p
; p
= va_arg(ap
, char *))
326 *(result
= xmalloc(length
)) = '\0';
328 va_start(ap
, string1
);
329 for (p
= string1
; p
; p
= va_arg(ap
, char *))