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