1/* $NetBSD: mlhsc.c,v 1.34 2021/08/07 16:18:41 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 1982, 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)dma.c 32 */ 33 34/* 35 * Copyright (c) 1994 Michael L. Hitch 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 * 57 * @(#)dma.c 58 */ 59 60#include <sys/cdefs.h> 61__KERNEL_RCSID(0, "$NetBSD: mlhsc.c,v 1.34 2021/08/07 16:18:41 thorpej Exp $"); 62 63#include <sys/param.h> 64#include <sys/systm.h> 65#include <sys/kernel.h> 66#include <sys/device.h> 67#include <dev/scsipi/scsi_all.h> 68#include <dev/scsipi/scsipi_all.h> 69#include <dev/scsipi/scsiconf.h> 70#include <amiga/amiga/device.h> 71#include <amiga/amiga/isr.h> 72#include <amiga/dev/scireg.h> 73#include <amiga/dev/scivar.h> 74#include <amiga/dev/zbusvar.h> 75 76void mlhscattach(device_t, device_t, void *); 77int mlhscmatch(device_t, cfdata_t, void *); 78 79int mlhsc_dma_xfer_in(struct sci_softc *dev, int len, 80 register u_char *buf, int phase); 81int mlhsc_dma_xfer_out(struct sci_softc *dev, int len, 82 register u_char *buf, int phase); 83 84#ifdef DEBUG 85extern int sci_debug; 86#define QPRINTF(a) if (sci_debug > 1) printf a 87#else 88#define QPRINTF(a) 89#endif 90 91extern int sci_data_wait; 92 93CFATTACH_DECL_NEW(mlhsc, sizeof(struct sci_softc), 94 mlhscmatch, mlhscattach, NULL, NULL); 95 96/* 97 * if we are my Hacker's SCSI board we are here. 98 */ 99int 100mlhscmatch(device_t parent, cfdata_t cf, void *aux) 101{ 102 struct zbus_args *zap; 103 104 zap = aux; 105 106 /* 107 * Check manufacturer and product id. 108 */ 109 if (zap->manid == 2011 && zap->prodid == 1) 110 return(1); 111 else 112 return(0); 113} 114 115void 116mlhscattach(device_t parent, device_t self, void *aux) 117{ 118 volatile u_char *rp; 119 struct sci_softc *sc = device_private(self); 120 struct zbus_args *zap; 121 struct scsipi_adapter *adapt = &sc->sc_adapter; 122 struct scsipi_channel *chan = &sc->sc_channel; 123 124 sc->sc_dev = self; 125 126 printf("\n"); 127 128 zap = aux; 129 130 rp = zap->va; 131 sc->sci_data = rp + 1; 132 sc->sci_odata = rp + 1; 133 sc->sci_icmd = rp + 3; 134 sc->sci_mode = rp + 5; 135 sc->sci_tcmd = rp + 7; 136 sc->sci_bus_csr = rp + 9; 137 sc->sci_sel_enb = rp + 9; 138 sc->sci_csr = rp + 11; 139 sc->sci_dma_send = rp + 11; 140 sc->sci_idata = rp + 13; 141 sc->sci_trecv = rp + 13; 142 sc->sci_iack = rp + 15; 143 sc->sci_irecv = rp + 15; 144 145 sc->dma_xfer_in = mlhsc_dma_xfer_in; 146 sc->dma_xfer_out = mlhsc_dma_xfer_out; 147 148 scireset(sc); 149 150 /* 151 * Fill in the scsipi_adapter. 152 */ 153 memset(adapt, 0, sizeof(*adapt)); 154 adapt->adapt_dev = self; 155 adapt->adapt_nchannels = 1; 156 adapt->adapt_openings = 7; 157 adapt->adapt_max_periph = 1; 158 adapt->adapt_request = sci_scsipi_request; 159 adapt->adapt_minphys = sci_minphys; 160 161 /* 162 * Fill in the scsipi_channel. 163 */ 164 memset(chan, 0, sizeof(*chan)); 165 chan->chan_adapter = adapt; 166 chan->chan_bustype = &scsi_bustype; 167 chan->chan_channel = 0; 168 chan->chan_ntargets = 8; 169 chan->chan_nluns = 8; 170 chan->chan_id = 7; 171 172 /* 173 * attach all scsi units on us 174 */ 175 config_found(self, chan, scsiprint, CFARGS_NONE); 176} 177 178int 179mlhsc_dma_xfer_in(struct sci_softc *dev, int len, register u_char *buf, 180 int phase) 181{ 182 int wait = sci_data_wait; 183 u_char csr; 184 volatile register u_char *sci_dma = dev->sci_data + 16; 185 volatile register u_char *sci_csr = dev->sci_csr; 186#ifdef DEBUG 187 u_char *obp = buf; 188#endif 189 190 csr = *dev->sci_bus_csr; 191 __USE(csr); 192 193 QPRINTF(("mlhdma_in %d, csr=%02x\n", len, csr)); 194 195 *dev->sci_tcmd = phase; 196 *dev->sci_mode |= SCI_MODE_DMA; 197 *dev->sci_icmd = 0; 198 *dev->sci_irecv = 0; 199 while (len > 128) { 200 wait = sci_data_wait; 201 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 202 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 203 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 204 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 205 || --wait < 0) { 206#ifdef DEBUG 207 if (sci_debug) 208 printf("mlhdma_in fail: l%d i%x w%d\n", 209 len, csr, wait); 210#endif 211 *dev->sci_mode &= ~SCI_MODE_DMA; 212 return 0; 213 } 214 } 215 216#define R1 (*buf++ = *sci_dma) 217 R1; R1; R1; R1; R1; R1; R1; R1; 218 R1; R1; R1; R1; R1; R1; R1; R1; 219 R1; R1; R1; R1; R1; R1; R1; R1; 220 R1; R1; R1; R1; R1; R1; R1; R1; 221 R1; R1; R1; R1; R1; R1; R1; R1; 222 R1; R1; R1; R1; R1; R1; R1; R1; 223 R1; R1; R1; R1; R1; R1; R1; R1; 224 R1; R1; R1; R1; R1; R1; R1; R1; 225 R1; R1; R1; R1; R1; R1; R1; R1; 226 R1; R1; R1; R1; R1; R1; R1; R1; 227 R1; R1; R1; R1; R1; R1; R1; R1; 228 R1; R1; R1; R1; R1; R1; R1; R1; 229 R1; R1; R1; R1; R1; R1; R1; R1; 230 R1; R1; R1; R1; R1; R1; R1; R1; 231 R1; R1; R1; R1; R1; R1; R1; R1; 232 R1; R1; R1; R1; R1; R1; R1; R1; 233 len -= 128; 234 } 235 while (len > 0) { 236 wait = sci_data_wait; 237 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 238 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 239 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 240 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 241 || --wait < 0) { 242#ifdef DEBUG 243 if (sci_debug) 244 printf("mlhdma_in fail: l%d i%x w%d\n", 245 len, csr, wait); 246#endif 247 *dev->sci_mode &= ~SCI_MODE_DMA; 248 return 0; 249 } 250 } 251 252 *buf++ = *sci_dma; 253 len--; 254 } 255 256 QPRINTF(("mlhdma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 257 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 258 obp[6], obp[7], obp[8], obp[9])); 259 260 *dev->sci_mode &= ~SCI_MODE_DMA; 261 return 0; 262} 263 264int 265mlhsc_dma_xfer_out(struct sci_softc *dev, int len, register u_char *buf, 266 int phase) 267{ 268 int wait = sci_data_wait; 269 u_char csr; 270 volatile register u_char *sci_dma = dev->sci_data + 16; 271 volatile register u_char *sci_csr = dev->sci_csr; 272 273 csr = *dev->sci_bus_csr; 274 __USE(csr); 275 276 QPRINTF(("mlhdma_xfer %d, csr=%02x\n", len, csr)); 277 278 QPRINTF(("mlhgdma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 279 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 280 buf[6], buf[7], buf[8], buf[9])); 281 282 *dev->sci_tcmd = phase; 283 *dev->sci_mode |= SCI_MODE_DMA; 284 *dev->sci_icmd = SCI_ICMD_DATA; 285 *dev->sci_dma_send = 0; 286 while (len > 64) { 287 wait = sci_data_wait; 288 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 289 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 290 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 291 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 292 || --wait < 0) { 293#ifdef DEBUG 294 if (sci_debug) 295 printf("mlhdma_out fail: l%d i%x w%d\n", 296 len, csr, wait); 297#endif 298 *dev->sci_mode &= ~SCI_MODE_DMA; 299 return 0; 300 } 301 } 302 303#define W1 (*sci_dma = *buf++) 304 W1; W1; W1; W1; W1; W1; W1; W1; 305 W1; W1; W1; W1; W1; W1; W1; W1; 306 W1; W1; W1; W1; W1; W1; W1; W1; 307 W1; W1; W1; W1; W1; W1; W1; W1; 308 W1; W1; W1; W1; W1; W1; W1; W1; 309 W1; W1; W1; W1; W1; W1; W1; W1; 310 W1; W1; W1; W1; W1; W1; W1; W1; 311 W1; W1; W1; W1; W1; W1; W1; W1; 312 len -= 64; 313 } 314 while (len > 0) { 315 wait = sci_data_wait; 316 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 317 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 318 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 319 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 320 || --wait < 0) { 321#ifdef DEBUG 322 if (sci_debug) 323 printf("mlhdma_out fail: l%d i%x w%d\n", 324 len, csr, wait); 325#endif 326 *dev->sci_mode &= ~SCI_MODE_DMA; 327 return 0; 328 } 329 } 330 331 *sci_dma = *buf++; 332 len--; 333 } 334 335 wait = sci_data_wait; 336 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) == 337 SCI_CSR_PHASE_MATCH && --wait); 338 339 *dev->sci_mode &= ~SCI_MODE_DMA; 340 return 0; 341} 342