1 /* 2 * Copyright (c) 1982, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)supradma.c 34 * $Id: wstsc.c,v 1.1 1994/05/08 05:53:50 chopps Exp $ 35 */ 36 37 /* 38 * dummy Supra 5380 DMA driver 39 */ 40 41 #include "suprascsi.h" 42 43 #if NSUPRASCSI > 0 44 45 #include <sys/param.h> 46 47 #include <amiga/dev/device.h> 48 #include <amiga/dev/scivar.h> 49 #include <amiga/dev/scireg.h> 50 51 int supradma_pseudo = 0; /* 0=none, 1=byte, 2=word */ 52 53 #ifdef DEBUG 54 extern int sci_debug; 55 #define QUASEL 56 #endif 57 #define HIST(h,w) 58 59 #ifdef QUASEL 60 #define QPRINTF(a) if (sci_debug > 1) printf a 61 #else 62 #define QPRINTF 63 #endif 64 65 extern int sci_data_wait; 66 67 static int dma_xfer_in __P((struct sci_softc *dev, int len, 68 register u_char *buf, int phase)); 69 static int dma_xfer_out __P((struct sci_softc *dev, int len, 70 register u_char *buf, int phase)); 71 static int dma_xfer_in2 __P((struct sci_softc *dev, int len, 72 register u_short *buf, int phase)); 73 static int dma_xfer_out2 __P((struct sci_softc *dev, int len, 74 register u_short *buf, int phase)); 75 static int supra_intr __P((struct sci_softc *dev)); 76 77 void 78 supradmainit (dev) 79 struct sci_softc *dev; 80 { 81 if (supradma_pseudo == 2) { 82 dev->dma_xfer_in = dma_xfer_in2; 83 dev->dma_xfer_out = dma_xfer_out2; 84 } else if (supradma_pseudo == 1) { 85 dev->dma_xfer_in = dma_xfer_in; 86 dev->dma_xfer_out = dma_xfer_out; 87 } 88 dev->dma_intr = supra_intr; 89 } 90 91 static int 92 dma_xfer_in (dev, len, buf, phase) 93 struct sci_softc *dev; 94 int len; 95 register u_char *buf; 96 int phase; 97 { 98 int wait = sci_data_wait; 99 u_char csr; 100 u_char *obp = (u_char *) buf; 101 volatile register u_char *sci_dma = dev->sci_idata; 102 volatile register u_char *sci_csr = dev->sci_csr; 103 104 QPRINTF(("supradma_in %d, csr=%02x\n", len, *dev->sci_bus_csr)); 105 106 *dev->sci_tcmd = phase; 107 *dev->sci_icmd = 0; 108 *dev->sci_mode = SCI_MODE_DMA; 109 *dev->sci_irecv = 0; 110 111 while (len >= 128) { 112 wait = sci_data_wait; 113 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 114 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 115 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 116 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 117 || --wait < 0) { 118 #ifdef DEBUG 119 if (sci_debug | 1) 120 printf("supradma2_in fail: l%d i%x w%d\n", 121 len, *dev->sci_bus_csr, wait); 122 #endif 123 HIST(ixin_wait, wait) 124 *dev->sci_mode = 0; 125 return 0; 126 } 127 } 128 129 *buf++ = *sci_dma; *buf++ = *sci_dma; 130 *buf++ = *sci_dma; *buf++ = *sci_dma; 131 *buf++ = *sci_dma; *buf++ = *sci_dma; 132 *buf++ = *sci_dma; *buf++ = *sci_dma; 133 *buf++ = *sci_dma; *buf++ = *sci_dma; 134 *buf++ = *sci_dma; *buf++ = *sci_dma; 135 *buf++ = *sci_dma; *buf++ = *sci_dma; 136 *buf++ = *sci_dma; *buf++ = *sci_dma; 137 *buf++ = *sci_dma; *buf++ = *sci_dma; 138 *buf++ = *sci_dma; *buf++ = *sci_dma; 139 *buf++ = *sci_dma; *buf++ = *sci_dma; 140 *buf++ = *sci_dma; *buf++ = *sci_dma; 141 *buf++ = *sci_dma; *buf++ = *sci_dma; 142 *buf++ = *sci_dma; *buf++ = *sci_dma; 143 *buf++ = *sci_dma; *buf++ = *sci_dma; 144 *buf++ = *sci_dma; *buf++ = *sci_dma; 145 *buf++ = *sci_dma; *buf++ = *sci_dma; 146 *buf++ = *sci_dma; *buf++ = *sci_dma; 147 *buf++ = *sci_dma; *buf++ = *sci_dma; 148 *buf++ = *sci_dma; *buf++ = *sci_dma; 149 *buf++ = *sci_dma; *buf++ = *sci_dma; 150 *buf++ = *sci_dma; *buf++ = *sci_dma; 151 *buf++ = *sci_dma; *buf++ = *sci_dma; 152 *buf++ = *sci_dma; *buf++ = *sci_dma; 153 *buf++ = *sci_dma; *buf++ = *sci_dma; 154 *buf++ = *sci_dma; *buf++ = *sci_dma; 155 *buf++ = *sci_dma; *buf++ = *sci_dma; 156 *buf++ = *sci_dma; *buf++ = *sci_dma; 157 *buf++ = *sci_dma; *buf++ = *sci_dma; 158 *buf++ = *sci_dma; *buf++ = *sci_dma; 159 *buf++ = *sci_dma; *buf++ = *sci_dma; 160 *buf++ = *sci_dma; *buf++ = *sci_dma; 161 *buf++ = *sci_dma; *buf++ = *sci_dma; 162 *buf++ = *sci_dma; *buf++ = *sci_dma; 163 *buf++ = *sci_dma; *buf++ = *sci_dma; 164 *buf++ = *sci_dma; *buf++ = *sci_dma; 165 *buf++ = *sci_dma; *buf++ = *sci_dma; 166 *buf++ = *sci_dma; *buf++ = *sci_dma; 167 *buf++ = *sci_dma; *buf++ = *sci_dma; 168 *buf++ = *sci_dma; *buf++ = *sci_dma; 169 *buf++ = *sci_dma; *buf++ = *sci_dma; 170 *buf++ = *sci_dma; *buf++ = *sci_dma; 171 *buf++ = *sci_dma; *buf++ = *sci_dma; 172 *buf++ = *sci_dma; *buf++ = *sci_dma; 173 *buf++ = *sci_dma; *buf++ = *sci_dma; 174 *buf++ = *sci_dma; *buf++ = *sci_dma; 175 *buf++ = *sci_dma; *buf++ = *sci_dma; 176 *buf++ = *sci_dma; *buf++ = *sci_dma; 177 *buf++ = *sci_dma; *buf++ = *sci_dma; 178 *buf++ = *sci_dma; *buf++ = *sci_dma; 179 *buf++ = *sci_dma; *buf++ = *sci_dma; 180 *buf++ = *sci_dma; *buf++ = *sci_dma; 181 *buf++ = *sci_dma; *buf++ = *sci_dma; 182 *buf++ = *sci_dma; *buf++ = *sci_dma; 183 *buf++ = *sci_dma; *buf++ = *sci_dma; 184 *buf++ = *sci_dma; *buf++ = *sci_dma; 185 *buf++ = *sci_dma; *buf++ = *sci_dma; 186 *buf++ = *sci_dma; *buf++ = *sci_dma; 187 *buf++ = *sci_dma; *buf++ = *sci_dma; 188 *buf++ = *sci_dma; *buf++ = *sci_dma; 189 *buf++ = *sci_dma; *buf++ = *sci_dma; 190 *buf++ = *sci_dma; *buf++ = *sci_dma; 191 *buf++ = *sci_dma; *buf++ = *sci_dma; 192 *buf++ = *sci_dma; *buf++ = *sci_dma; 193 len -= 128; 194 } 195 196 while (len > 0) { 197 wait = sci_data_wait; 198 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 199 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 200 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 201 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 202 || --wait < 0) { 203 #ifdef DEBUG 204 if (sci_debug | 1) 205 printf("supradma1_in fail: l%d i%x w%d\n", 206 len, *dev->sci_bus_csr, wait); 207 #endif 208 HIST(ixin_wait, wait) 209 *dev->sci_mode = 0; 210 return 0; 211 } 212 } 213 214 *buf++ = *sci_dma; 215 len--; 216 } 217 218 QPRINTF(("supradma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 219 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 220 obp[6], obp[7], obp[8], obp[9])); 221 222 HIST(ixin_wait, wait) 223 *dev->sci_mode = 0; 224 return 0; 225 } 226 227 static int 228 dma_xfer_out (dev, len, buf, phase) 229 struct sci_softc *dev; 230 int len; 231 register u_char *buf; 232 int phase; 233 { 234 int wait = sci_data_wait; 235 u_char csr; 236 u_char *obp = buf; 237 volatile register u_char *sci_dma = dev->sci_data; 238 volatile register u_char *sci_csr = dev->sci_csr; 239 240 QPRINTF(("supradma_out %d, csr=%02x\n", len, *dev->sci_bus_csr)); 241 242 QPRINTF(("supradma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 243 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 244 buf[6], buf[7], buf[8], buf[9])); 245 246 *dev->sci_tcmd = phase; 247 *dev->sci_mode = SCI_MODE_DMA; 248 *dev->sci_icmd = SCI_ICMD_DATA; 249 *dev->sci_dma_send = 0; 250 while (len > 0) { 251 wait = sci_data_wait; 252 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 253 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 254 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 255 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 256 || --wait < 0) { 257 #ifdef DEBUG 258 if (sci_debug) 259 printf("supradma_out fail: l%d i%x w%d\n", 260 len, csr, wait); 261 #endif 262 HIST(ixin_wait, wait) 263 *dev->sci_mode = 0; 264 return 0; 265 } 266 } 267 268 *sci_dma = *buf++; 269 len--; 270 } 271 272 wait = sci_data_wait; 273 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) == 274 SCI_CSR_PHASE_MATCH && --wait); 275 276 277 HIST(ixin_wait, wait) 278 *dev->sci_mode = 0; 279 *dev->sci_icmd = 0; 280 return 0; 281 } 282 283 284 static int 285 dma_xfer_in2 (dev, len, buf, phase) 286 struct sci_softc *dev; 287 int len; 288 register u_short *buf; 289 int phase; 290 { 291 int wait = sci_data_wait; 292 u_char csr; 293 u_char *obp = (u_char *) buf; 294 volatile register u_short *sci_dma = (u_short *)(dev->sci_idata + 0x10); 295 volatile register u_char *sci_csr = dev->sci_csr + 0x10; 296 297 QPRINTF(("supradma_in2 %d, csr=%02x\n", len, *dev->sci_bus_csr)); 298 299 *dev->sci_tcmd = phase; 300 *dev->sci_mode = SCI_MODE_DMA; 301 *dev->sci_icmd = 0; 302 *(dev->sci_irecv + 16) = 0; 303 while (len >= 128) { 304 #if 0 305 wait = sci_data_wait; 306 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 307 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 308 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 309 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 310 || --wait < 0) { 311 #ifdef DEBUG 312 if (sci_debug | 1) 313 printf("supradma2_in2 fail: l%d i%x w%d\n", 314 len, *dev->sci_bus_csr, wait); 315 #endif 316 HIST(ixin_wait, wait) 317 *dev->sci_mode &= ~SCI_MODE_DMA; 318 return 0; 319 } 320 } 321 #else 322 while (!(*sci_csr & SCI_CSR_DREQ)) 323 ; 324 #endif 325 326 *buf++ = *sci_dma; *buf++ = *sci_dma; 327 *buf++ = *sci_dma; *buf++ = *sci_dma; 328 *buf++ = *sci_dma; *buf++ = *sci_dma; 329 *buf++ = *sci_dma; *buf++ = *sci_dma; 330 *buf++ = *sci_dma; *buf++ = *sci_dma; 331 *buf++ = *sci_dma; *buf++ = *sci_dma; 332 *buf++ = *sci_dma; *buf++ = *sci_dma; 333 *buf++ = *sci_dma; *buf++ = *sci_dma; 334 *buf++ = *sci_dma; *buf++ = *sci_dma; 335 *buf++ = *sci_dma; *buf++ = *sci_dma; 336 *buf++ = *sci_dma; *buf++ = *sci_dma; 337 *buf++ = *sci_dma; *buf++ = *sci_dma; 338 *buf++ = *sci_dma; *buf++ = *sci_dma; 339 *buf++ = *sci_dma; *buf++ = *sci_dma; 340 *buf++ = *sci_dma; *buf++ = *sci_dma; 341 *buf++ = *sci_dma; *buf++ = *sci_dma; 342 *buf++ = *sci_dma; *buf++ = *sci_dma; 343 *buf++ = *sci_dma; *buf++ = *sci_dma; 344 *buf++ = *sci_dma; *buf++ = *sci_dma; 345 *buf++ = *sci_dma; *buf++ = *sci_dma; 346 *buf++ = *sci_dma; *buf++ = *sci_dma; 347 *buf++ = *sci_dma; *buf++ = *sci_dma; 348 *buf++ = *sci_dma; *buf++ = *sci_dma; 349 *buf++ = *sci_dma; *buf++ = *sci_dma; 350 *buf++ = *sci_dma; *buf++ = *sci_dma; 351 *buf++ = *sci_dma; *buf++ = *sci_dma; 352 *buf++ = *sci_dma; *buf++ = *sci_dma; 353 *buf++ = *sci_dma; *buf++ = *sci_dma; 354 *buf++ = *sci_dma; *buf++ = *sci_dma; 355 *buf++ = *sci_dma; *buf++ = *sci_dma; 356 *buf++ = *sci_dma; *buf++ = *sci_dma; 357 *buf++ = *sci_dma; *buf++ = *sci_dma; 358 len -= 128; 359 } 360 while (len > 0) { 361 #if 0 362 wait = sci_data_wait; 363 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 364 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 365 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 366 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 367 || --wait < 0) { 368 #ifdef DEBUG 369 if (sci_debug | 1) 370 printf("supradma1_in2 fail: l%d i%x w%d\n", 371 len, *dev->sci_bus_csr, wait); 372 #endif 373 HIST(ixin_wait, wait) 374 *dev->sci_mode &= ~SCI_MODE_DMA; 375 return 0; 376 } 377 } 378 #else 379 while (!(*sci_csr * SCI_CSR_DREQ)) 380 ; 381 #endif 382 383 *buf++ = *sci_dma; 384 len -= 2; 385 } 386 387 QPRINTF(("supradma_in2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 388 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 389 obp[6], obp[7], obp[8], obp[9])); 390 391 HIST(ixin_wait, wait) 392 *dev->sci_irecv = 0; 393 *dev->sci_mode = 0; 394 return 0; 395 } 396 397 static int 398 dma_xfer_out2 (dev, len, buf, phase) 399 struct sci_softc *dev; 400 int len; 401 register u_short *buf; 402 int phase; 403 { 404 int wait = sci_data_wait; 405 u_char csr; 406 u_char *obp = (u_char *) buf; 407 volatile register u_short *sci_dma = (ushort *)(dev->sci_data + 0x10); 408 volatile register u_char *sci_bus_csr = dev->sci_bus_csr; 409 410 QPRINTF(("supradma_out2 %d, csr=%02x\n", len, *dev->sci_bus_csr)); 411 412 QPRINTF(("supradma_out2 {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 413 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 414 obp[6], obp[7], obp[8], obp[9])); 415 416 *dev->sci_tcmd = phase; 417 *dev->sci_mode = SCI_MODE_DMA; 418 *dev->sci_icmd = SCI_ICMD_DATA; 419 *dev->sci_dma_send = 0; 420 while (len > 0) { 421 #if 0 422 wait = sci_data_wait; 423 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) != 424 (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) { 425 if (!(*sci_csr & SCI_CSR_PHASE_MATCH) 426 || !(*dev->sci_bus_csr & SCI_BUS_BSY) 427 || --wait < 0) { 428 #ifdef DEBUG 429 if (sci_debug) 430 printf("supradma_out2 fail: l%d i%x w%d\n", 431 len, csr, wait); 432 #endif 433 HIST(ixin_wait, wait) 434 *dev->sci_mode = 0; 435 return 0; 436 } 437 } 438 #else 439 *dev->sci_mode = 0; 440 *dev->sci_icmd &= ~SCI_ICMD_ACK; 441 while (!(*sci_bus_csr & SCI_BUS_REQ)) 442 ; 443 *dev->sci_mode = SCI_MODE_DMA; 444 *dev->sci_dma_send = 0; 445 #endif 446 447 *sci_dma = *buf++; *sci_dma = *buf++; 448 *sci_dma = *buf++; *sci_dma = *buf++; 449 *sci_dma = *buf++; *sci_dma = *buf++; 450 *sci_dma = *buf++; *sci_dma = *buf++; 451 *sci_dma = *buf++; *sci_dma = *buf++; 452 *sci_dma = *buf++; *sci_dma = *buf++; 453 *sci_dma = *buf++; *sci_dma = *buf++; 454 *sci_dma = *buf++; *sci_dma = *buf++; 455 *sci_dma = *buf++; *sci_dma = *buf++; 456 *sci_dma = *buf++; *sci_dma = *buf++; 457 *sci_dma = *buf++; *sci_dma = *buf++; 458 *sci_dma = *buf++; *sci_dma = *buf++; 459 *sci_dma = *buf++; *sci_dma = *buf++; 460 *sci_dma = *buf++; *sci_dma = *buf++; 461 *sci_dma = *buf++; *sci_dma = *buf++; 462 *sci_dma = *buf++; *sci_dma = *buf++; 463 if (*(sci_bus_csr + 0x10) & SCI_BUS_REQ) 464 ; 465 len -= 64; 466 } 467 468 #if 0 469 wait = sci_data_wait; 470 while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) == 471 SCI_CSR_PHASE_MATCH && --wait); 472 #endif 473 474 475 HIST(ixin_wait, wait) 476 *dev->sci_irecv = 0; 477 *dev->sci_icmd &= ~SCI_ICMD_ACK; 478 *dev->sci_mode = 0; 479 *dev->sci_icmd = 0; 480 return 0; 481 } 482 483 static int 484 supra_intr (dev) 485 struct sci_softc *dev; 486 { 487 if (*(dev->sci_csr + 0x10) & SCI_CSR_INT) { 488 char dummy; 489 #if 0 490 printf ("supra_intr\n"); 491 #endif 492 dummy = *(dev->sci_iack + 0x10); 493 return (1); 494 } 495 return (0); 496 } 497 #endif 498