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