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