Home | History | Annotate | Line # | Download | only in boot
      1 /*	$NetBSD: ctu.c,v 1.9 2017/05/22 16:59:32 ragge Exp $ */
      2 /*
      3  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 /*
     28  * Standalone device driver for 11/750 Console TU58.
     29  * It can only handle reads, and doesn't calculate checksum.
     30  */
     31 
     32 #include <sys/param.h>
     33 
     34 #include <lib/libsa/stand.h>
     35 
     36 #include <machine/mtpr.h>
     37 #include <machine/rsp.h>
     38 
     39 #include "vaxstand.h"
     40 
     41 static short ctu_cksum(unsigned short *, int);
     42 
     43 enum tu_state {
     44 	SC_INIT,
     45 	SC_READY,
     46 	SC_SEND_CMD,
     47 	SC_GET_RESP,
     48 };
     49 
     50 volatile struct tu_softc {
     51 	enum	tu_state sc_state;
     52 	char	sc_rsp[15];	/* Should be struct rsb; but don't work */
     53 	u_char	*sc_xfptr;	/* Current char to xfer */
     54 	int	sc_nbytes;	/* Number of bytes to xfer */
     55 	int	sc_xbytes;	/* Number of xfer'd bytes */
     56 	int	sc_bbytes;	/* Number of xfer'd bytes this block */
     57 } tu_sc;
     58 
     59 void	ctutintr(void);
     60 void	cturintr(void);
     61 
     62 int
     63 ctuopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
     64 {
     65 
     66 	tu_sc.sc_state = SC_INIT;
     67 
     68 	mtpr(RSP_TYP_INIT, PR_CSTD);
     69 	cturintr();
     70 	tu_sc.sc_state = SC_READY;
     71 	return 0;
     72 
     73 }
     74 
     75 int
     76 ctustrategy(void *f, int func, daddr_t dblk, size_t size, void *buf, size_t *rsize)
     77 {
     78 	struct rsp *rsp = (struct rsp *)tu_sc.sc_rsp;
     79 
     80 	tu_sc.sc_xfptr = buf;
     81 	tu_sc.sc_nbytes = size;
     82 	tu_sc.sc_xbytes = tu_sc.sc_bbytes = 0;
     83 
     84 	rsp->rsp_typ = RSP_TYP_COMMAND;
     85 	rsp->rsp_sz = 012;
     86 	rsp->rsp_op = RSP_OP_READ;
     87 	rsp->rsp_mod = 0;
     88 	rsp->rsp_drv = 0;
     89 	rsp->rsp_sw = rsp->rsp_xx1 = rsp->rsp_xx2 = 0;
     90 	rsp->rsp_cnt = tu_sc.sc_nbytes;
     91 	rsp->rsp_blk = dblk;
     92 	rsp->rsp_sum = ctu_cksum((u_short *)rsp, 6);
     93 	tu_sc.sc_state = SC_SEND_CMD;
     94 	while (tu_sc.sc_state != SC_GET_RESP)
     95 		ctutintr();
     96 	while (tu_sc.sc_state != SC_READY)
     97 		cturintr();
     98 	*rsize = size;
     99 	return 0;
    100 }
    101 
    102 void
    103 cturintr(void)
    104 {
    105 	int	status;
    106 
    107 	while ((mfpr(PR_CSRS) & 0x80) == 0)
    108 		;
    109 
    110 	status = mfpr(PR_CSRD);
    111 
    112 	switch (tu_sc.sc_state) {
    113 
    114 	case SC_INIT:
    115 		break;
    116 
    117 	case SC_GET_RESP:
    118 		if (tu_sc.sc_xbytes == tu_sc.sc_nbytes) {
    119 			tu_sc.sc_bbytes++;
    120 			if (tu_sc.sc_bbytes == 146)
    121 				tu_sc.sc_state = SC_READY;
    122 			break;
    123 		}
    124 		tu_sc.sc_bbytes++;
    125 		if (tu_sc.sc_bbytes <  3) /* Data header */
    126 			break;
    127 		if (tu_sc.sc_bbytes == 132) { /* Finished */
    128 			tu_sc.sc_bbytes = 0;
    129 			break;
    130 		}
    131 		if (tu_sc.sc_bbytes == 131) /* First checksum */
    132 			break;
    133 		tu_sc.sc_xfptr[tu_sc.sc_xbytes++] = status;
    134 		break;
    135 
    136 	case SC_READY:
    137 	case SC_SEND_CMD:
    138 		break;
    139 	}
    140 
    141 }
    142 
    143 void
    144 ctutintr(void)
    145 {
    146 	int	c;
    147 
    148 	while ((mfpr(PR_CSTS) & 0x80) == 0)
    149 		;
    150 
    151 	c = tu_sc.sc_rsp[tu_sc.sc_xbytes++] & 0xff;
    152 	mtpr(c, PR_CSTD);
    153 	if (tu_sc.sc_xbytes > 13) {
    154 		tu_sc.sc_state = SC_GET_RESP;
    155 		tu_sc.sc_xbytes = 0;
    156 	}
    157 }
    158 
    159 short
    160 ctu_cksum(unsigned short *buf, int words)
    161 {
    162 	int i, cksum;
    163 
    164 	for (i = cksum = 0; i < words; i++)
    165 		cksum += buf[i];
    166 
    167 hej:	if (cksum > 65535) {
    168 		cksum = (cksum & 65535) + (cksum >> 16);
    169 		goto hej;
    170 	}
    171 	return cksum;
    172 }
    173