1*7991f5a7Sandvar /* $NetBSD: saio.c,v 1.15 2021/07/24 21:31:34 andvar Exp $ */
2a3ec1726Swdk
3a3ec1726Swdk /*
4a3ec1726Swdk * Copyright (c) 1992, 1993
5a3ec1726Swdk * The Regents of the University of California. All rights reserved.
6a3ec1726Swdk *
7a3ec1726Swdk * This code is derived from software contributed to Berkeley by
8a3ec1726Swdk * Van Jacobson of Lawrence Berkeley Laboratory and Ralph Campbell.
9a3ec1726Swdk *
10a3ec1726Swdk * Redistribution and use in source and binary forms, with or without
11a3ec1726Swdk * modification, are permitted provided that the following conditions
12a3ec1726Swdk * are met:
13a3ec1726Swdk * 1. Redistributions of source code must retain the above copyright
14a3ec1726Swdk * notice, this list of conditions and the following disclaimer.
15a3ec1726Swdk * 2. Redistributions in binary form must reproduce the above copyright
16a3ec1726Swdk * notice, this list of conditions and the following disclaimer in the
17a3ec1726Swdk * documentation and/or other materials provided with the distribution.
18aad01611Sagc * 3. Neither the name of the University nor the names of its contributors
19a3ec1726Swdk * may be used to endorse or promote products derived from this software
20a3ec1726Swdk * without specific prior written permission.
21a3ec1726Swdk *
22a3ec1726Swdk * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23a3ec1726Swdk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24a3ec1726Swdk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25a3ec1726Swdk * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26a3ec1726Swdk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27a3ec1726Swdk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28a3ec1726Swdk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29a3ec1726Swdk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30a3ec1726Swdk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31a3ec1726Swdk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32a3ec1726Swdk * SUCH DAMAGE.
33a3ec1726Swdk *
34a3ec1726Swdk * @(#)rz.c 8.1 (Berkeley) 6/10/93
35a3ec1726Swdk */
36a3ec1726Swdk
37a3ec1726Swdk #include <lib/libsa/stand.h>
38e1445fedSwdk #include <lib/libkern/libkern.h>
39a3ec1726Swdk #include <machine/prom.h>
40a3ec1726Swdk
41a3ec1726Swdk #include <sys/param.h>
42a3ec1726Swdk #include <sys/disklabel.h>
43a3ec1726Swdk
44a3ec1726Swdk #include "common.h"
45a3ec1726Swdk #include "saio.h"
46a3ec1726Swdk
47a3ec1726Swdk struct saio_softc {
48a3ec1726Swdk int sc_fd; /* PROM file id */
49a3ec1726Swdk int sc_ctlr; /* controller number */
50a3ec1726Swdk int sc_unit; /* disk unit number */
51a3ec1726Swdk int sc_part; /* disk partition number */
52a3ec1726Swdk struct disklabel sc_label; /* disk label for this disk */
53a3ec1726Swdk };
54a3ec1726Swdk
55a3ec1726Swdk struct io_arg {
56a3ec1726Swdk int retval;
57a3ec1726Swdk unsigned long sectst;
58a3ec1726Swdk unsigned long memaddr;
59a3ec1726Swdk unsigned long datasz;
60a3ec1726Swdk };
61a3ec1726Swdk
62a3ec1726Swdk #define IOB_BUFSZ 512
6350e120c1Swdk #define IOB_INODESZ 316
64a3ec1726Swdk
65a3ec1726Swdk struct device_table {
66a3ec1726Swdk char *dt_string; /* device name */
67a3ec1726Swdk int (*dt_init) (int); /* device init routine */
6802cdf4d2Sdsl int (*dt_open)(int); /* device open routine */
6902cdf4d2Sdsl int (*dt_strategy)(int); /* device strategy routine, returns cnt */
7002cdf4d2Sdsl int (*dt_close)(int); /* device close routine */
7102cdf4d2Sdsl int (*dt_ioctl)(int); /* device ioctl routine */
72a3ec1726Swdk int dt_type; /* device "type" */
73a3ec1726Swdk int dt_fs; /* file system type */
74a3ec1726Swdk char *dt_desc; /* device description */
75a3ec1726Swdk };
76a3ec1726Swdk
77a3ec1726Swdk struct sa_iob {
78a3ec1726Swdk char i_buf[IOB_BUFSZ]; /* file system or tape header */
79a3ec1726Swdk char i_ino_dir[IOB_INODESZ]; /* inode or disk/tape directory */
80a3ec1726Swdk
81a3ec1726Swdk int i_flgs; /* see F_ below */
82a3ec1726Swdk int i_ctlr; /* controller board */
83a3ec1726Swdk int i_unit; /* pseudo device unit */
84a3ec1726Swdk int i_part; /* disk partition */
85a3ec1726Swdk char *i_ma; /* memory address of i/o buffer */
86a3ec1726Swdk int i_cc; /* character count of transfer */
8750e120c1Swdk int32_t i_offset; /* seek offset in file */
88a3ff3a30Sfvdl /* XXX ondisk32 */
89a3ff3a30Sfvdl int32_t i_bn; /* 1st block # of next read */
90a3ec1726Swdk int i_fstype; /* file system type */
91a3ec1726Swdk int i_errno; /* error # return */
92a3ec1726Swdk unsigned int i_devaddr; /* csr address */
93a3ec1726Swdk struct device_table *i_dp; /* pointer into device_table */
94a3ec1726Swdk char *i_bufp; /* i/o buffer for blk devs */
95a3ec1726Swdk }__attribute__((__packed__));
96a3ec1726Swdk
97a3ec1726Swdk extern struct sa_iob *saiob[];
98a3ec1726Swdk
99a3ec1726Swdk int
saiostrategy(void * devdata,int rw,daddr_t bn,size_t reqcnt,void * addr,size_t * cnt)10082357f6dSdsl saiostrategy(void *devdata, int rw, daddr_t bn, size_t reqcnt, void *addr, size_t *cnt)
101*7991f5a7Sandvar /* cnt: out: number of bytes transferred */
102a3ec1726Swdk {
103a3ec1726Swdk struct saio_softc *sc = (struct saio_softc *)devdata;
104a3ec1726Swdk int part = sc->sc_part;
105a3ec1726Swdk struct partition *pp = &sc->sc_label.d_partitions[part];
106a3ec1726Swdk int s;
107a3ec1726Swdk long offset;
108a3ec1726Swdk struct sa_iob *iob;
1099f30ac89She char *adr;
110a3ec1726Swdk
111a3ec1726Swdk offset = bn * DEV_BSIZE;
112a3ec1726Swdk *cnt = 0;
113a3ec1726Swdk
114a3ec1726Swdk /*
115a3ec1726Swdk * Partial-block transfers not handled.
116a3ec1726Swdk */
117a3ec1726Swdk if (reqcnt & (DEV_BSIZE - 1)) {
118a3ec1726Swdk return (EINVAL);
119a3ec1726Swdk }
120a3ec1726Swdk offset += pp->p_offset * DEV_BSIZE;
121a3ec1726Swdk
122a3ec1726Swdk iob = saiob[sc->sc_fd];
123a3ec1726Swdk iob->i_offset = offset;
124a3ec1726Swdk
125a3ec1726Swdk #if notyet
126a3ec1726Swdk if (prom_lseek(sc->sc_fd, offset, 0) < 0)
127a3ec1726Swdk return (EIO);
128a3ec1726Swdk #endif
129a3ec1726Swdk
1309f30ac89She adr = (char *)addr;
131a3ec1726Swdk while (*cnt < reqcnt) {
132a3ec1726Swdk s = prom_read(sc->sc_fd, iob->i_buf, 512);
133a3ec1726Swdk if (s < 0) {
134a3ec1726Swdk return (EIO);
135a3ec1726Swdk }
1369f30ac89She memcpy(adr, iob->i_buf, s);
137a3ec1726Swdk *cnt += s;
1389f30ac89She adr += s;
139a3ec1726Swdk }
140a3ec1726Swdk return (0);
141a3ec1726Swdk }
142a3ec1726Swdk
143a3ec1726Swdk int
saioopen(struct open_file * f,...)144a3ec1726Swdk saioopen(struct open_file *f, ...)
145a3ec1726Swdk {
146a3ec1726Swdk int ctlr, unit, part;
147a3ec1726Swdk
148a3ec1726Swdk struct saio_softc *sc;
149a3ec1726Swdk struct disklabel *lp;
150a3ec1726Swdk int i;
151a3ec1726Swdk char *msg;
152a3ec1726Swdk char buf[DEV_BSIZE];
153fc571bb5Schristos size_t cnt;
154a3ec1726Swdk static char device[] = "dksd(0,0,10)";
155a3ec1726Swdk
156a3ec1726Swdk va_list ap;
157a3ec1726Swdk
158a3ec1726Swdk va_start(ap, f);
159a3ec1726Swdk
160a3ec1726Swdk ctlr = va_arg(ap, int);
161a3ec1726Swdk unit = va_arg(ap, int);
162a3ec1726Swdk part = va_arg(ap, int);
16350e120c1Swdk
1644c999163Swiz va_end(ap);
1654c999163Swiz
16650e120c1Swdk device[5] = '0' + ctlr;
167a3ec1726Swdk device[7] = '0' + unit;
168a3ec1726Swdk
16950e120c1Swdk i = prom_open(device, 0);
170a3ec1726Swdk if (i < 0) {
171a3ec1726Swdk printf("open failed\n");
172a3ec1726Swdk return (ENXIO);
173a3ec1726Swdk }
174a3ec1726Swdk
175a3ec1726Swdk sc = alloc(sizeof(struct saio_softc));
176a3ec1726Swdk memset(sc, 0, sizeof(struct saio_softc));
177a3ec1726Swdk f->f_devdata = (void *)sc;
178a3ec1726Swdk
179a3ec1726Swdk sc->sc_fd = i;
180a3ec1726Swdk sc->sc_ctlr = ctlr;
181a3ec1726Swdk sc->sc_unit = unit;
182a3ec1726Swdk sc->sc_part = part;
183a3ec1726Swdk
184a3ec1726Swdk /* try to read disk label and partition table information */
185a3ec1726Swdk lp = &sc->sc_label;
186a3ec1726Swdk lp->d_secsize = DEV_BSIZE;
187a3ec1726Swdk lp->d_secpercyl = 1;
188a3ec1726Swdk lp->d_npartitions = MAXPARTITIONS;
189a3ec1726Swdk lp->d_partitions[part].p_offset = 0;
190a3ec1726Swdk lp->d_partitions[part].p_size = 0x7fffffff;
191a3ec1726Swdk
192a3ec1726Swdk i = saiostrategy(sc, F_READ, (daddr_t)LABELSECTOR, DEV_BSIZE, buf, &cnt);
193a3ec1726Swdk if (i || cnt != DEV_BSIZE) {
194a3ec1726Swdk printf("%s: error reading disk label\n", device);
195a3ec1726Swdk goto bad;
196a3ec1726Swdk }
197a3ec1726Swdk
198a3ec1726Swdk msg = getdisklabel(buf, lp);
199a3ec1726Swdk if (msg) {
20050e120c1Swdk #ifdef LIBSA_NO_DISKLABEL_MSGS
20150e120c1Swdk printf("%s: no disklabel\n", device);
20250e120c1Swdk #else
203a3ec1726Swdk printf("getlabel: %s\n", msg);
20450e120c1Swdk #endif
205a3ec1726Swdk return (0);
206a3ec1726Swdk }
207a3ec1726Swdk if (part >= lp->d_npartitions || lp->d_partitions[part].p_size == 0) {
208a3ec1726Swdk bad:
209606bb2caSchristos dealloc(sc, sizeof(struct saio_softc));
210a3ec1726Swdk return (ENXIO);
211a3ec1726Swdk }
212a3ec1726Swdk return (0);
213a3ec1726Swdk }
214a3ec1726Swdk
215a3ec1726Swdk #ifndef LIBSA_NO_DEV_CLOSE
216a3ec1726Swdk int
saioclose(struct open_file * f)217454af1c0Sdsl saioclose(struct open_file *f)
218a3ec1726Swdk {
219a3ec1726Swdk
220a3ec1726Swdk prom_close(((struct saio_softc *)f->f_devdata)->sc_fd);
221606bb2caSchristos dealloc(f->f_devdata, sizeof(struct saio_softc));
222a3ec1726Swdk f->f_devdata = (void *)0;
223a3ec1726Swdk return (0);
224a3ec1726Swdk }
225a3ec1726Swdk #endif
226