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