Init
This commit is contained in:
299
sys/boot/os/devio.c
Normal file
299
sys/boot/os/devio.c
Normal file
@@ -0,0 +1,299 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user