182 lines
4.3 KiB
C
182 lines
4.3 KiB
C
/* $NetBSD: ctu.c,v 1.1 1996/02/17 18:23:20 ragge Exp $ */
|
|
/*
|
|
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed at Ludd, University of
|
|
* Lule}, Sweden and its contributors.
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/*
|
|
* Standalone device driver for 11/750 Console TU58.
|
|
* It can only handle reads, and doesn't calculate checksum.
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <lib/libsa/stand.h>
|
|
|
|
#include <machine/mtpr.h>
|
|
#include <machine/rsp.h>
|
|
|
|
enum tu_state {
|
|
SC_INIT,
|
|
SC_READY,
|
|
SC_SEND_CMD,
|
|
SC_GET_RESP,
|
|
};
|
|
|
|
volatile struct tu_softc {
|
|
enum tu_state sc_state;
|
|
char sc_rsp[15]; /* Should be struct rsb; but don't work */
|
|
u_char *sc_xfptr; /* Current char to xfer */
|
|
int sc_nbytes; /* Number of bytes to xfer */
|
|
int sc_xbytes; /* Number of xfer'd bytes */
|
|
int sc_bbytes; /* Number of xfer'd bytes this block */
|
|
} tu_sc;
|
|
|
|
void ctutintr __P(());
|
|
void cturintr __P(());
|
|
|
|
int
|
|
ctuopen(f, adapt, ctlr, unit, part)
|
|
struct open_file *f;
|
|
int ctlr, unit, part;
|
|
{
|
|
|
|
tu_sc.sc_state = SC_INIT;
|
|
|
|
mtpr(RSP_TYP_INIT, PR_CSTD);
|
|
cturintr();
|
|
tu_sc.sc_state = SC_READY;
|
|
return 0;
|
|
|
|
}
|
|
|
|
int
|
|
ctustrategy(ra, func, dblk, size, buf, rsize)
|
|
struct ra_softc *ra;
|
|
int func;
|
|
daddr_t dblk;
|
|
char *buf;
|
|
u_int size, *rsize;
|
|
{
|
|
int s;
|
|
|
|
struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp;
|
|
|
|
tu_sc.sc_xfptr = buf;
|
|
tu_sc.sc_nbytes = size;
|
|
tu_sc.sc_xbytes = tu_sc.sc_bbytes = 0;
|
|
|
|
rsp->rsp_typ = RSP_TYP_COMMAND;
|
|
rsp->rsp_sz = 012;
|
|
rsp->rsp_op = RSP_OP_READ;
|
|
rsp->rsp_mod = 0;
|
|
rsp->rsp_drv = 0;
|
|
rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0;
|
|
rsp->rsp_cnt = tu_sc.sc_nbytes;
|
|
rsp->rsp_blk = dblk;
|
|
rsp->rsp_sum = ctu_cksum(rsp, 6);
|
|
tu_sc.sc_state = SC_SEND_CMD;
|
|
while (tu_sc.sc_state != SC_GET_RESP)
|
|
ctutintr();
|
|
while (tu_sc.sc_state != SC_READY)
|
|
cturintr();
|
|
*rsize = size;
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
cturintr()
|
|
{
|
|
int status;
|
|
|
|
while ((mfpr(PR_CSRS) & 0x80) == 0)
|
|
;
|
|
|
|
status = mfpr(PR_CSRD);
|
|
|
|
switch (tu_sc.sc_state) {
|
|
|
|
case SC_INIT:
|
|
break;
|
|
|
|
case SC_GET_RESP:
|
|
if (tu_sc.sc_xbytes == tu_sc.sc_nbytes) {
|
|
tu_sc.sc_bbytes++;
|
|
if (tu_sc.sc_bbytes == 146)
|
|
tu_sc.sc_state = SC_READY;
|
|
break;
|
|
}
|
|
tu_sc.sc_bbytes++;
|
|
if (tu_sc.sc_bbytes < 3) /* Data header */
|
|
break;
|
|
if (tu_sc.sc_bbytes == 132) { /* Finished */
|
|
tu_sc.sc_bbytes = 0;
|
|
break;
|
|
}
|
|
if (tu_sc.sc_bbytes == 131) /* First checksum */
|
|
break;
|
|
tu_sc.sc_xfptr[tu_sc.sc_xbytes++] = status;
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
ctutintr()
|
|
{
|
|
int c;
|
|
|
|
while ((mfpr(PR_CSTS) & 0x80) == 0)
|
|
;
|
|
|
|
c = tu_sc.sc_rsp[tu_sc.sc_xbytes++] & 0xff;
|
|
mtpr(c, PR_CSTD);
|
|
if (tu_sc.sc_xbytes > 13) {
|
|
tu_sc.sc_state = SC_GET_RESP;
|
|
tu_sc.sc_xbytes = 0;
|
|
}
|
|
}
|
|
|
|
ctu_cksum(buf, words)
|
|
unsigned short *buf;
|
|
int words;
|
|
{
|
|
int i, cksum;
|
|
|
|
for (i = cksum = 0; i < words; i++)
|
|
cksum += buf[i];
|
|
|
|
hej: if (cksum > 65535) {
|
|
cksum = (cksum & 65535) + (cksum >> 16);
|
|
goto hej;
|
|
}
|
|
return cksum;
|
|
}
|