2021-10-11 18:37:13 -03:00

300 lines
6.5 KiB
C

#ifndef lint
static char sccsid[] = "@(#)devio.c 1.1 94/10/31 Copyr 1983 Sun Micro";
#endif
/*
* Device interface code for standalone I/O system.
*
* Most simply indirect thru the table to call the "right" routine.
*/
#include <mon/sunromvec.h>
#include <stand/saio.h>
#include "param.h"
#include <sys/dir.h>
#include <sys/time.h>
#include "boot/vnode.h"
#include <ufs/fs.h>
#include "boot/inode.h"
#include "boot/iob.h"
#ifdef OPENPROMS
#include "boot/conf.h"
#endif OPENPROMS
#ifdef DUMP_DEBUG
static int dump_debug = 10;
#endif DUMP_DEBUG
/*
* Strategy -- handles I/O in large blocks for drivers.
* (This routine is private to this file.)
*
* If a devread() or devwrite() is attempted which is larger
* than the max I/O size for this device, break it up into a
* series of max-sized operations.
*
* Devices which do not declare a max size get the whole thing.
*/
static int
strategy(sip, rw)
register struct saioreq *sip;
int rw;
{
register char *ma;
register unsigned cc;
register daddr_t bn;
register int errs;
register unsigned maxsize;
register struct devinfo *dp;
#ifdef DUMP_DEBUG
dprint(dump_debug, 6, "strategy(sip 0x%x rw 0x%x)\n",
sip, rw);
#endif /* DUMP_DEBUG */
if (rw == READ && (sip->si_flgs & F_EOF)) {
sip->si_flgs &= ~F_EOF;
return (0);
}
ma = sip->si_ma; /* Save for later */
bn = sip->si_bn;
cc = sip->si_cc;
dp = sip->si_boottab->b_devinfo;
if (dp && (maxsize = dp->d_maxiobytes) != 0 &&
((maxsize & (DEV_BSIZE-1)) == 0))
;
else
maxsize = 0x7FFFFFFF;
errs = 0;
while (sip->si_cc > 0) {
if (sip->si_cc > maxsize)
sip->si_cc = maxsize;
errs = (*sip->si_boottab->b_strategy)(sip, rw);
/* short read is expected for 1/2" tape */
if (errs <= 0) /* error or EOF */
break;
sip->si_ma += errs;
sip->si_bn += errs / DEV_BSIZE;
sip->si_cc = cc - (sip->si_ma - ma);
}
if (errs == 0)
sip->si_flgs |= F_EOF;
if (errs >= 0)
errs = sip->si_ma - ma; /* Add the part we did before */
if (errs == 0)
sip->si_flgs &= ~F_EOF;
sip->si_ma = ma; /* Restore */
sip->si_bn = bn;
sip->si_cc = cc;
return (errs);
}
int
devread(sip)
struct saioreq *sip;
{
return (strategy(sip, READ));
}
int
devwrite(sip)
struct saioreq *sip;
{
return (strategy(sip, WRITE));
}
int
devopen(sip)
register struct saioreq *sip;
{
register struct devinfo *dp;
register char *a;
register int result;
#ifdef DUMP_DEBUG
dprint(dump_debug, 10,
"devopen(sip 0x%x)\n",
sip);
dump_saioreq(sip);
#endif /* DUMP_DEBUG */
sip->si_flgs &= ~F_EOF;
#ifdef OPENPROMS
if (prom_getversion() > 0)
sip->si_devaddr = sip->si_dmaaddr = (char *)0;
else
#endif
sip->si_devaddr = sip->si_devdata = sip->si_dmaaddr = (char *)0;
dp = sip->si_boottab->b_devinfo;
if (dp) {
/* Map controller number into controller address */
if (sip->si_ctlr < dp->d_stdcount) {
sip->si_ctlr = (int)((dp->d_stdaddrs)[sip->si_ctlr]);
}
/* Map in device itself */
if (dp->d_devbytes) {
a = devalloc(dp->d_devtype, (char *)sip->si_ctlr,
dp->d_devbytes);
if (!a)
goto bad;
sip->si_devaddr = a;
}
if (dp->d_dmabytes) {
a = resalloc(RES_DMAMEM, dp->d_dmabytes);
if (!a)
goto bad;
sip->si_dmaaddr = a;
}
if (dp->d_localbytes) {
a = resalloc(RES_MAINMEM, dp->d_localbytes);
if (!a)
goto bad;
sip->si_devdata = a;
}
}
result = (sip->si_boottab->b_open)(sip);
if (result != -1)
return (result);
bad:
return (-1); /* Indicate failure */
}
devclose(sip)
register struct saioreq *sip;
{
sip->si_flgs &= ~F_EOF;
if (sip->si_boottab->b_close)
(sip->si_boottab->b_close)(sip);
}
/*
* If the device is an ethernet interface (hard to tell, isn't it?),
* reset it. This restarts transmitters after they've been shut off.
*/
devreopen(sip)
register struct saioreq *sip;
{
sip->si_flgs &= ~F_EOF;
if (sip->si_boottab && sip->si_boottab->b_open)
(sip->si_boottab->b_open)(sip);
}
dump_iob(f)
struct iob *f;
{
printf("iob: 0x%x\n", f);
dump_saioreq(&(f->i_si));
}
dump_saioreq(s)
struct saioreq *s;
{
printf("saioreq: si_flgs 0x%x\n",
s->si_flgs);
dump_boottab(s->si_boottab);
if (s->si_devdata)
#ifdef OPENPROMS
if (prom_getversion() > 0)
dump_devdata(s->si_devdata);
else
#endif OPENPROMS
printf("saioreq: si_devdata '%s'\n", s->si_devdata);
else
printf("saioreq: si_devdata ' '\n");
printf("saioreq: si_ctlr 0x%x si_unit 0x%x si_boff 0x%x\n",
s->si_ctlr, s->si_unit, s->si_boff);
printf("saioreq: si_cyloff 0x%x si_offset 0x%x si_bn 0x%x si_ma 0x%x ",
s->si_cyloff, s->si_offset, s->si_bn, s->si_ma);
printf("si_cc 0x%x\n", s->si_cc);
if (s->si_sif)
dump_saif(s->si_sif);
else
printf("saif:\n");
printf("saioreq: si_devaddr 0x%x si_dmaaddr 0x%x\n",
s->si_devaddr, s->si_dmaaddr);
}
dump_saif(s)
struct saif *s;
{
printf("saif: sif_xmit 0x%x sif_poll 0x%x sif_reset 0x%x\n",
s->sif_xmit, s->sif_poll, s->sif_reset);
}
dump_bootparam(bp)
struct bootparam *bp;
{
printf("bootparam: bp_argv[0] 0x%x bp_argv[1] 0x%x bp_argv[2] 0x%x\n",
bp->bp_argv[0], bp->bp_argv[1], bp->bp_argv[2]);
printf("bootparam: bp_argv[3] 0x%x bp_argv[4] 0x%x bp_argv[5] 0x%x\n",
bp->bp_argv[3], bp->bp_argv[4], bp->bp_argv[5]);
printf("bootparam: bp_argv[6] 0x%x bp_argv[7] 0x%x\n",
bp->bp_argv[6], bp->bp_argv[7]);
printf("bootparam: bp_strings %s\n", bp->bp_strings);
printf("\tbp_dev %c%c bp_ctlr 0x%x bp_unit 0x%x bp_part 0x%x\n",
bp->bp_dev[0], bp->bp_dev[1], bp->bp_ctlr, bp->bp_unit,
bp->bp_part);
printf("bootparam: bp_name %s\n", bp->bp_name);
dump_boottab(bp->bp_boottab);
}
dump_boottab(b)
struct boottab *b;
{
printf("boottab: dev %c%c b_probe 0x%x b_boot 0x%x b_open 0x%x\n",
b->b_dev[0], b->b_dev[1], b->b_probe, b->b_boot, b->b_open);
printf("boottab: b_close 0x%x b_strategy 0x%x\n",
b->b_close, b->b_strategy);
if (b->b_desc)
printf("boottab: b_desc '%s'\n", b->b_desc);
else
printf("boottab: b_desc ' '\n");
if (b->b_devinfo)
dump_devinfo(b->b_devinfo);
else
printf("devinfo:\n");
}
dump_devinfo(d)
struct devinfo *d;
{
printf("devinfo: d_devbytes 0x%x d_dmabytes 0x%x d_localbytes 0x%x\n",
d->d_devbytes, d->d_dmabytes, d->d_localbytes);
dump_stdaddrs((unsigned long *)d->d_stdaddrs, (int)d->d_stdcount);
printf("devinfo: d_devtype 0x%x d_maxiobytes 0x%x\n",
d->d_devtype, d->d_maxiobytes);
}
dump_stdaddrs(vec, count)
unsigned long *vec;
int count;
{
printf("stdaddrs: ");
for (; count > 0; count--, vec++)
printf("d_stdaddr[%d] 0x%x ",
count, *vec);
printf ("\n");
}
#ifdef OPENPROMS
dump_devdata(dp)
struct binfo *dp;
{
printf("devdata: ihandle 0x%x name '%s'\n", dp->ihandle, dp->name);
}
#endif