xref: /netbsd-src/sys/arch/mipsco/stand/common/saio.c (revision 7991f5a7b8fc83a3d55dc2a1767cca3b84103969)
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