1 /* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Van Jacobson of Lawrence Berkeley Laboratory. 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 * @(#)sci.c 7.5 (Berkeley) 5/4/91 37 * $Id: sci.c,v 1.4 1994/05/08 05:53:40 chopps Exp $ 38 * 39 */ 40 41 /* 42 * AMIGA NCR 5380 scsi adaptor driver 43 */ 44 45 #include "mlhscsi.h" 46 #include "csa12gscsi.h" 47 #include "suprascsi.h" 48 #include "ivsscsi.h" 49 #if (NMLHSCSI + NCSA12GSCSI + NSUPRASCSI + NIVSSCSI) > 0 50 #define NSCI NMLHSCSI 51 #if NSCI < NCSA12GSCSI 52 #undef NSCI 53 #define NSCI NCSA12GSCSI 54 #endif 55 #if NSCI < NSUPRASCSI 56 #undef NSCI 57 #define NSCI NSUPRASCSI 58 #endif 59 #if NSCI < NIVSSCSI 60 #undef NSCI 61 #define NSCI NIVSSCI 62 #endif 63 64 /* need to know if any tapes have been configured */ 65 #include "st.h" 66 67 #include <sys/param.h> 68 #include <sys/systm.h> 69 #include <sys/buf.h> 70 #include <vm/vm.h> 71 #include <vm/vm_kern.h> 72 #include <vm/vm_page.h> 73 #include <machine/pmap.h> 74 75 #include <amiga/dev/device.h> 76 77 #include <amiga/dev/scsidefs.h> 78 #include <amiga/dev/scivar.h> 79 #include <amiga/dev/scireg.h> 80 81 #include <amiga/amiga/custom.h> 82 83 #include <machine/cpu.h> 84 85 extern u_int kvtop(); 86 87 static int sci_wait __P((char until, int timeo, int line)); 88 static void scsiabort __P((register struct sci_softc *dev, char *where)); 89 static void scsierror __P((register struct sci_softc *dev, u_char csr)); 90 static int issue_select __P((register struct sci_softc *dev, u_char target, 91 u_char our_addr)); 92 static int ixfer_out __P((register struct sci_softc *dev, int len, 93 register u_char *buf, int phase)); 94 static void ixfer_in __P((register struct sci_softc *dev, int len, 95 register u_char *buf, int phase)); 96 static int scsiicmd __P((struct sci_softc *dev, int target, u_char *cbuf, 97 int clen, u_char *buf, int len, u_char xferphase)); 98 99 100 /* 101 * SCSI delays 102 * In u-seconds, primarily for state changes on the SPC. 103 */ 104 #define SCSI_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */ 105 #define SCSI_DATA_WAIT 50000 /* wait per data in/out step */ 106 #define SCSI_INIT_WAIT 50000 /* wait per step (both) during init */ 107 108 extern void _insque(); 109 extern void _remque(); 110 111 void scistart __P((int unit)); 112 int scigo __P((int ctlr, int slave, int unit, struct buf *bp, 113 struct scsi_fmt_cdb *cdb, int pad)); 114 int sciintr __P((void)); 115 void scidone __P((int unit)); 116 int sciustart __P((int unit)); 117 int scireq __P((register struct devqueue *dq)); 118 void scifree __P((register struct devqueue *dq)); 119 void scireset __P((int unit)); 120 void sci_delay __P((int delay)); 121 int sci_test_unit_rdy __P((int ctlr, int slave, int unit)); 122 int sci_start_stop_unit __P((int ctlr, int slave, int unit, int start)); 123 int sci_request_sense __P((int ctlr, int slave, int unit, u_char *buf, 124 unsigned int len)); 125 int sci_immed_command __P((int ctlr, int slave, int unit, 126 struct scsi_fmt_cdb *cdb, u_char *buf, unsigned int len, int rd)); 127 int sci_immed_command_nd __P((int ctlr, int slave, int unit, 128 struct scsi_fmt_cdb *cdb)); 129 int sci_tt_read __P((int ctlr, int slave, int unit, u_char *buf, 130 u_int len, daddr_t blk, int bshift)); 131 int sci_tt_write __P((int ctlr, int slave, int unit, u_char *buf, 132 u_int len, daddr_t blk, int bshift)); 133 #if NST > 0 134 int sci_tt_oddio __P((int ctlr, int slave, int unit, u_char *buf, u_int len, int b_flags, int freedma)); 135 #endif 136 137 138 #if NMLHSCSI > 0 139 int mlhscsiinit (); 140 141 struct driver mlhscsidriver = { 142 (int (*)(void *)) mlhscsiinit, "mlhscsi", (int (*)(int)) scistart, 143 (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr, 144 (int (*)())scidone, sciustart, scireq, scifree, scireset, 145 sci_delay, sci_test_unit_rdy, sci_start_stop_unit, 146 sci_request_sense, sci_immed_command, sci_immed_command_nd, 147 sci_tt_read, sci_tt_write, 148 #if NST > 0 149 sci_tt_oddio 150 #else 151 NULL 152 #endif 153 }; 154 #endif 155 156 #if NCSA12GSCSI > 0 157 int csa12gscsiinit (); 158 159 struct driver csa12gscsidriver = { 160 (int (*)(void *)) csa12gscsiinit, "csa12gscsi", (int (*)(int)) scistart, 161 (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr, 162 (int (*)())scidone, sciustart, scireq, scifree, scireset, 163 sci_delay, sci_test_unit_rdy, sci_start_stop_unit, 164 sci_request_sense, sci_immed_command, sci_immed_command_nd, 165 sci_tt_read, sci_tt_write, 166 #if NST > 0 167 sci_tt_oddio 168 #else 169 NULL 170 #endif 171 }; 172 #endif 173 174 #if NSUPRASCSI > 0 175 int suprascsiinit (); 176 177 struct driver suprascsidriver = { 178 (int (*)(void *)) suprascsiinit, "suprascsi", (int (*)(int)) scistart, 179 (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr, 180 (int (*)())scidone, sciustart, scireq, scifree, scireset, 181 sci_delay, sci_test_unit_rdy, sci_start_stop_unit, 182 sci_request_sense, sci_immed_command, sci_immed_command_nd, 183 sci_tt_read, sci_tt_write, 184 #if NST > 0 185 sci_tt_oddio 186 #else 187 NULL 188 #endif 189 }; 190 #endif 191 192 #if NIVSSCSI > 0 193 int ivsscsiinit (); 194 195 struct driver ivsscsidriver = { 196 (int (*)(void *)) ivsscsiinit, "ivsscsi", (int (*)(int)) scistart, 197 (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr, 198 (int (*)())scidone, sciustart, scireq, scifree, scireset, 199 sci_delay, sci_test_unit_rdy, sci_start_stop_unit, 200 sci_request_sense, sci_immed_command, sci_immed_command_nd, 201 sci_tt_read, sci_tt_write, 202 #if NST > 0 203 sci_tt_oddio 204 #else 205 NULL 206 #endif 207 }; 208 #endif 209 210 struct sci_softc sci_softc[NSCI]; 211 212 int sci_cmd_wait = SCSI_CMD_WAIT; 213 int sci_data_wait = SCSI_DATA_WAIT; 214 int sci_init_wait = SCSI_INIT_WAIT; 215 216 int sci_no_dma = 0; 217 218 #ifdef DEBUG 219 int sci_debug = 0; 220 #define WAITHIST 221 #define QUASEL 222 223 static long dmahits[NSCI]; 224 static long dmamisses[NSCI]; 225 #endif 226 227 #ifdef QUASEL 228 #define QPRINTF(a) if (sci_debug > 1) printf a 229 #else 230 #define QPRINTF 231 #endif 232 233 #ifdef WAITHIST 234 #define MAXWAIT 1022 235 u_int ixstart_wait[MAXWAIT+2]; 236 u_int ixin_wait[MAXWAIT+2]; 237 u_int ixout_wait[MAXWAIT+2]; 238 u_int mxin_wait[MAXWAIT+2]; 239 u_int mxin2_wait[MAXWAIT+2]; 240 u_int cxin_wait[MAXWAIT+2]; 241 u_int fxfr_wait[MAXWAIT+2]; 242 u_int sgo_wait[MAXWAIT+2]; 243 #define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]); 244 #else 245 #define HIST(h,w) 246 #endif 247 248 #define b_cylin b_resid 249 250 static sci_wait (until, timeo, line) 251 char until; 252 int timeo; 253 int line; 254 { 255 register unsigned char val; 256 257 if (! timeo) 258 timeo = 1000000; /* some large value.. */ 259 260 return val; 261 } 262 263 static void 264 scsiabort(dev, where) 265 register struct sci_softc *dev; 266 char *where; 267 { 268 269 printf ("sci%d: abort %s: csr = 0x%02x, bus = 0x%02x\n", 270 dev->sc_ac->amiga_unit, 271 where, *dev->sci_csr, *dev->sci_bus_csr); 272 273 if (dev->sc_flags & SCI_SELECTED) { 274 275 /* XXX */ 276 scireset (dev->sc_ac->amiga_unit); 277 /* lets just hope it worked.. */ 278 dev->sc_flags &= ~SCI_SELECTED; 279 } 280 } 281 282 /* 283 * XXX Set/reset long delays. 284 * 285 * if delay == 0, reset default delays 286 * if delay < 0, set both delays to default long initialization values 287 * if delay > 0, set both delays to this value 288 * 289 * Used when a devices is expected to respond slowly (e.g. during 290 * initialization). 291 */ 292 void 293 sci_delay(delay) 294 int delay; 295 { 296 static int saved_cmd_wait, saved_data_wait; 297 298 if (delay) { 299 saved_cmd_wait = sci_cmd_wait; 300 saved_data_wait = sci_data_wait; 301 if (delay > 0) 302 sci_cmd_wait = sci_data_wait = delay; 303 else 304 sci_cmd_wait = sci_data_wait = sci_init_wait; 305 } else { 306 sci_cmd_wait = saved_cmd_wait; 307 sci_data_wait = saved_data_wait; 308 } 309 } 310 311 static int initialized[NSCI]; 312 313 #if NMLHSCSI > 0 314 int 315 mlhscsiinit(ac) 316 register struct amiga_ctlr *ac; 317 { 318 register struct sci_softc *dev = &sci_softc[ac->amiga_unit]; 319 320 if (! ac->amiga_addr) 321 return 0; 322 323 if (initialized[ac->amiga_unit]) 324 return 0; 325 326 if (ac->amiga_unit > NSCI) 327 return 0; 328 329 initialized[ac->amiga_unit] = 1; 330 331 /* advance ac->amiga_addr to point to the real sci-registers */ 332 ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr); 333 dev->sci_data = (caddr_t) ac->amiga_addr + 1; 334 dev->sci_odata = (caddr_t) ac->amiga_addr + 1; 335 dev->sci_icmd = (caddr_t) ac->amiga_addr + 3; 336 dev->sci_mode = (caddr_t) ac->amiga_addr + 5; 337 dev->sci_tcmd = (caddr_t) ac->amiga_addr + 7; 338 dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 9; 339 dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 9; 340 dev->sci_csr = (caddr_t) ac->amiga_addr + 11; 341 dev->sci_dma_send = (caddr_t) ac->amiga_addr + 11; 342 dev->sci_idata = (caddr_t) ac->amiga_addr + 13; 343 dev->sci_trecv = (caddr_t) ac->amiga_addr + 13; 344 dev->sci_iack = (caddr_t) ac->amiga_addr + 15; 345 dev->sci_irecv = (caddr_t) ac->amiga_addr + 15; 346 mlhdmainit (dev); 347 348 /* hardwired IPL */ 349 ac->amiga_ipl = 0; /* doesn't use interrupts */ 350 dev->sc_ac = ac; 351 dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq; 352 scireset (ac->amiga_unit); 353 354 return(1); 355 } 356 #endif 357 358 #if NCSA12GSCSI > 0 359 int 360 csa12gscsiinit(ac) 361 register struct amiga_ctlr *ac; 362 { 363 register struct sci_softc *dev = &sci_softc[ac->amiga_unit]; 364 365 if (! ac->amiga_addr) 366 return 0; 367 368 if (initialized[ac->amiga_unit]) 369 return 0; 370 371 if (ac->amiga_unit > NSCI) 372 return 0; 373 374 initialized[ac->amiga_unit] = 1; 375 376 /* advance ac->amiga_addr to point to the real sci-registers */ 377 ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr + 0x2000); 378 dev->sci_data = (caddr_t) ac->amiga_addr; 379 dev->sci_odata = (caddr_t) ac->amiga_addr; 380 dev->sci_icmd = (caddr_t) ac->amiga_addr + 0x10; 381 dev->sci_mode = (caddr_t) ac->amiga_addr + 0x20; 382 dev->sci_tcmd = (caddr_t) ac->amiga_addr + 0x30; 383 dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 0x40; 384 dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 0x40; 385 dev->sci_csr = (caddr_t) ac->amiga_addr + 0x50; 386 dev->sci_dma_send = (caddr_t) ac->amiga_addr + 0x50; 387 dev->sci_idata = (caddr_t) ac->amiga_addr + 0x60; 388 dev->sci_trecv = (caddr_t) ac->amiga_addr + 0x60; 389 dev->sci_iack = (caddr_t) ac->amiga_addr + 0x70; 390 dev->sci_irecv = (caddr_t) ac->amiga_addr + 0x70; 391 csa12gdmainit (dev); 392 393 /* hardwired IPL */ 394 ac->amiga_ipl = 2; 395 dev->sc_ac = ac; 396 dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq; 397 scireset (ac->amiga_unit); 398 399 /* make sure IPL2 interrupts are delivered to the cpu when the sci 400 generates some. Note that this does not yet enable sci-interrupts, 401 this is handled in dma.c, which selectively enables interrupts only 402 while DMA requests are pending. 403 404 Note that enabling PORTS interrupts also enables keyboard interrupts 405 as soon as the corresponding int-enable bit in CIA-A is set. */ 406 407 custom.intreq = INTF_PORTS; 408 custom.intena = INTF_SETCLR | INTF_PORTS; 409 return(1); 410 } 411 #endif 412 413 #if NSUPRASCSI > 0 414 int 415 suprascsiinit(ac) 416 register struct amiga_ctlr *ac; 417 { 418 register struct sci_softc *dev = &sci_softc[ac->amiga_unit]; 419 420 if (! ac->amiga_addr) 421 return 0; 422 423 if (initialized[ac->amiga_unit]) 424 return 0; 425 426 if (ac->amiga_unit > NSCI) 427 return 0; 428 429 initialized[ac->amiga_unit] = 1; 430 431 /* advance ac->amiga_addr to point to the real sci-registers */ 432 /* XXX Supra Word Sync version 2 only for now !!! */ 433 dev->sci_data = (caddr_t) ac->amiga_addr; 434 dev->sci_odata = (caddr_t) ac->amiga_addr; 435 dev->sci_icmd = (caddr_t) ac->amiga_addr + 2; 436 dev->sci_mode = (caddr_t) ac->amiga_addr + 4; 437 dev->sci_tcmd = (caddr_t) ac->amiga_addr + 6; 438 dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 8; 439 dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 8; 440 dev->sci_csr = (caddr_t) ac->amiga_addr + 10; 441 dev->sci_dma_send = (caddr_t) ac->amiga_addr + 10; 442 dev->sci_idata = (caddr_t) ac->amiga_addr + 12; 443 dev->sci_trecv = (caddr_t) ac->amiga_addr + 12; 444 dev->sci_iack = (caddr_t) ac->amiga_addr + 14; 445 dev->sci_irecv = (caddr_t) ac->amiga_addr + 14; 446 supradmainit (dev); 447 448 /* hardwired IPL */ 449 ac->amiga_ipl = 2; 450 dev->sc_ac = ac; 451 dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq; 452 scireset (ac->amiga_unit); 453 454 /* make sure IPL2 interrupts are delivered to the cpu when the sci 455 generates some. Note that this does not yet enable sci-interrupts, 456 this is handled in dma.c, which selectively enables interrupts only 457 while DMA requests are pending. 458 459 Note that enabling PORTS interrupts also enables keyboard interrupts 460 as soon as the corresponding int-enable bit in CIA-A is set. */ 461 462 custom.intreq = INTF_PORTS; 463 custom.intena = INTF_SETCLR | INTF_PORTS; 464 return(1); 465 } 466 #endif 467 468 #if NIVSSCSI > 0 469 int 470 ivsscsiinit(ac) 471 register struct amiga_ctlr *ac; 472 { 473 register struct sci_softc *dev = &sci_softc[ac->amiga_unit]; 474 475 if (! ac->amiga_addr) 476 return 0; 477 478 if (initialized[ac->amiga_unit]) 479 return 0; 480 481 if (ac->amiga_unit > NSCI) 482 return 0; 483 484 initialized[ac->amiga_unit] = 1; 485 486 /* advance ac->amiga_addr to point to the real sci-registers */ 487 ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr + 0x40); 488 dev->sci_data = (caddr_t) ac->amiga_addr; 489 dev->sci_odata = (caddr_t) ac->amiga_addr; 490 dev->sci_icmd = (caddr_t) ac->amiga_addr + 2; 491 dev->sci_mode = (caddr_t) ac->amiga_addr + 4; 492 dev->sci_tcmd = (caddr_t) ac->amiga_addr + 6; 493 dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 8; 494 dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 8; 495 dev->sci_csr = (caddr_t) ac->amiga_addr + 10; 496 dev->sci_dma_send = (caddr_t) ac->amiga_addr + 10; 497 dev->sci_idata = (caddr_t) ac->amiga_addr + 12; 498 dev->sci_trecv = (caddr_t) ac->amiga_addr + 12; 499 dev->sci_iack = (caddr_t) ac->amiga_addr + 14; 500 dev->sci_irecv = (caddr_t) ac->amiga_addr + 14; 501 ivsdmainit (dev); 502 503 /* hardwired IPL */ 504 ac->amiga_ipl = 2; 505 dev->sc_ac = ac; 506 dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq; 507 scireset (ac->amiga_unit); 508 509 /* make sure IPL2 interrupts are delivered to the cpu when the sci 510 generates some. Note that this does not yet enable sci-interrupts, 511 this is handled in dma.c, which selectively enables interrupts only 512 while DMA requests are pending. 513 514 Note that enabling PORTS interrupts also enables keyboard interrupts 515 as soon as the corresponding int-enable bit in CIA-A is set. */ 516 517 custom.intreq = INTF_PORTS; 518 custom.intena = INTF_SETCLR | INTF_PORTS; 519 return(1); 520 } 521 #endif 522 523 void 524 scireset(unit) 525 register int unit; 526 { 527 register struct sci_softc *dev = &sci_softc[unit]; 528 u_int i, s; 529 u_char my_id, csr; 530 531 if (dev->sc_flags & SCI_ALIVE) 532 scsiabort(dev, "reset"); 533 534 printf("sci%d: ", unit); 535 536 s = splbio(); 537 /* preserve our ID for now */ 538 my_id = 7; 539 540 /* 541 * Disable interrupts (in dmainit) then reset the chip 542 */ 543 *dev->sci_icmd = SCI_ICMD_TEST; 544 *dev->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST; 545 DELAY (25); 546 *dev->sci_icmd = 0; 547 548 /* 549 * Set up various chip parameters 550 */ 551 *dev->sci_icmd = 0; 552 *dev->sci_tcmd = 0; 553 *dev->sci_sel_enb = 0; 554 555 /* anything else was zeroed by reset */ 556 557 splx (s); 558 559 printf("sci id %d\n", my_id); 560 dev->sc_flags |= SCI_ALIVE; 561 dev->sc_flags &= ~SCI_SELECTED; 562 } 563 564 static void 565 scsierror(dev, csr) 566 register struct sci_softc *dev; 567 u_char csr; 568 { 569 int unit = dev->sc_ac->amiga_unit; 570 char *sep = ""; 571 572 printf("sci%d: ", unit); 573 printf("\n"); 574 } 575 576 static int 577 issue_select(dev, target, our_addr) 578 register struct sci_softc *dev; 579 u_char target, our_addr; 580 { 581 register int timeo = 2500; 582 583 QPRINTF (("issue_select %d\n", target)); 584 585 /* if we're already selected, return */ 586 if (dev->sc_flags & SCI_SELECTED) /* XXXX */ 587 return 1; 588 589 if ((*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 590 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) && 591 (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL))) 592 return 1; 593 594 *dev->sci_tcmd = 0; 595 *dev->sci_odata = 0x80 + (1 << target); 596 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_SEL; 597 while ((*dev->sci_bus_csr & SCI_BUS_BSY) == 0) { 598 if (--timeo > 0) { 599 DELAY(100); 600 } else { 601 break; 602 } 603 } 604 if (timeo) { 605 *dev->sci_icmd = 0; 606 dev->sc_flags |= SCI_SELECTED; 607 return (0); 608 } 609 *dev->sci_icmd = 0; 610 return (1); 611 } 612 613 static int 614 ixfer_out(dev, len, buf, phase) 615 register struct sci_softc *dev; 616 int len; 617 register u_char *buf; 618 int phase; 619 { 620 register int wait = sci_data_wait; 621 u_char csr; 622 623 QPRINTF(("ixfer_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 624 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], 625 buf[6], buf[7], buf[8], buf[9])); 626 627 *dev->sci_tcmd = phase; 628 *dev->sci_icmd = SCI_ICMD_DATA; 629 for (;len > 0; len--) { 630 csr = *dev->sci_bus_csr; 631 while (!(csr & SCI_BUS_REQ)) { 632 if ((csr & SCI_BUS_BSY) == 0 || --wait < 0) { 633 #ifdef DEBUG 634 if (sci_debug) 635 printf("ixfer_out fail: l%d i%x w%d\n", 636 len, csr, wait); 637 #endif 638 HIST(ixout_wait, wait) 639 return (len); 640 } 641 DELAY(1); 642 csr = *dev->sci_bus_csr; 643 } 644 645 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 646 break; 647 *dev->sci_odata = *buf; 648 *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_ACK; 649 buf++; 650 while (*dev->sci_bus_csr & SCI_BUS_REQ); 651 *dev->sci_icmd = SCI_ICMD_DATA; 652 } 653 654 QPRINTF(("ixfer_out done\n")); 655 /* this leaves with one csr to be read */ 656 HIST(ixout_wait, wait) 657 return (0); 658 } 659 660 static void 661 ixfer_in(dev, len, buf, phase) 662 struct sci_softc *dev; 663 int len; 664 register u_char *buf; 665 int phase; 666 { 667 int wait = sci_data_wait; 668 u_char *obp = buf; 669 u_char csr; 670 volatile register u_char *sci_bus_csr = dev->sci_bus_csr; 671 volatile register u_char *sci_data = dev->sci_data; 672 volatile register u_char *sci_icmd = dev->sci_icmd; 673 674 csr = *sci_bus_csr; 675 676 QPRINTF(("ixfer_in %d, csr=%02x\n", len, csr)); 677 678 *dev->sci_tcmd = phase; 679 *sci_icmd = 0; 680 for (;len > 0; len--) { 681 csr = *sci_bus_csr; 682 while (!(csr & SCI_BUS_REQ)) { 683 if (!(csr & SCI_BUS_BSY) || --wait < 0) { 684 #ifdef DEBUG 685 if (sci_debug) 686 printf("ixfer_in fail: l%d i%x w%d\n", 687 len, csr, wait); 688 #endif 689 HIST(ixin_wait, wait) 690 return; 691 } 692 693 DELAY(1); 694 csr = *sci_bus_csr; 695 } 696 697 if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH)) 698 break; 699 *buf = *sci_data; 700 *sci_icmd = SCI_ICMD_ACK; 701 buf++; 702 while (*sci_bus_csr & SCI_BUS_REQ); 703 *sci_icmd = 0; 704 } 705 706 QPRINTF(("ixfer_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 707 len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5], 708 obp[6], obp[7], obp[8], obp[9])); 709 710 /* this leaves with one csr to be read */ 711 HIST(ixin_wait, wait) 712 } 713 714 /* 715 * SCSI 'immediate' command: issue a command to some SCSI device 716 * and get back an 'immediate' response (i.e., do programmed xfer 717 * to get the response data). 'cbuf' is a buffer containing a scsi 718 * command of length clen bytes. 'buf' is a buffer of length 'len' 719 * bytes for data. The transfer direction is determined by the device 720 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 721 * command must supply no data. 'xferphase' is the bus phase the 722 * caller expects to happen after the command is issued. It should 723 * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE. 724 */ 725 static int 726 scsiicmd(dev, target, cbuf, clen, buf, len, xferphase) 727 struct sci_softc *dev; 728 int target; 729 u_char *cbuf; 730 int clen; 731 u_char *buf; 732 int len; 733 u_char xferphase; 734 { 735 u_char phase, csr, asr; 736 register int wait; 737 738 /* select the SCSI bus (it's an error if bus isn't free) */ 739 if (issue_select (dev, target, dev->sc_scsi_addr)) 740 return -1; 741 /* 742 * Wait for a phase change (or error) then let the device 743 * sequence us through the various SCSI phases. 744 */ 745 dev->sc_stat[0] = 0xff; 746 dev->sc_msg[0] = 0xff; 747 phase = CMD_PHASE; 748 while (1) { 749 wait = sci_cmd_wait; 750 751 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == SCI_BUS_BSY); 752 753 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 754 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 755 return -1; 756 } 757 phase = SCI_PHASE(*dev->sci_bus_csr); 758 759 switch (phase) { 760 case CMD_PHASE: 761 if (ixfer_out (dev, clen, cbuf, phase)) 762 goto abort; 763 phase = xferphase; 764 break; 765 766 case DATA_IN_PHASE: 767 if (len <= 0) 768 goto abort; 769 wait = sci_data_wait; 770 ixfer_in (dev, len, buf, phase); 771 phase = STATUS_PHASE; 772 break; 773 774 case DATA_OUT_PHASE: 775 if (len <= 0) 776 goto abort; 777 wait = sci_data_wait; 778 if (ixfer_out (dev, len, buf, phase)) 779 goto abort; 780 phase = STATUS_PHASE; 781 break; 782 783 case MESG_IN_PHASE: 784 dev->sc_msg[0] = 0xff; 785 ixfer_in (dev, 1, dev->sc_msg,phase); 786 dev->sc_flags &= ~SCI_SELECTED; 787 while (*dev->sci_bus_csr & SCI_BUS_BSY); 788 goto out; 789 break; 790 791 case MESG_OUT_PHASE: 792 phase = STATUS_PHASE; 793 break; 794 795 case STATUS_PHASE: 796 ixfer_in (dev, 1, dev->sc_stat, phase); 797 phase = MESG_IN_PHASE; 798 break; 799 800 case BUS_FREE_PHASE: 801 goto out; 802 803 default: 804 printf("sci: unexpected phase %d in icmd from %d\n", 805 phase, target); 806 goto abort; 807 } 808 #if 0 809 if (wait <= 0) 810 goto abort; 811 #endif 812 } 813 814 abort: 815 scsiabort(dev, "icmd"); 816 out: 817 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 818 return (dev->sc_stat[0]); 819 } 820 821 int 822 sci_test_unit_rdy(ctlr, slave, unit) 823 int ctlr, slave, unit; 824 { 825 register struct sci_softc *dev = &sci_softc[ctlr]; 826 static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY }; 827 828 cdb.lun = unit; 829 return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), (u_char *)0, 0, 830 STATUS_PHASE)); 831 } 832 833 int 834 sci_start_stop_unit (ctlr, slave, unit, start) 835 int ctlr, slave, unit; 836 { 837 register struct sci_softc *dev = &sci_softc[ctlr]; 838 static struct scsi_cdb6 cdb = { CMD_LOADUNLOAD }; 839 840 cdb.lun = unit; 841 /* we don't set the immediate bit, so we wait for the 842 command to succeed. 843 We also don't touch the LoEj bit, which is primarily meant 844 for floppies. */ 845 cdb.len = start & 0x01; 846 return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), (u_char *)0, 0, 847 STATUS_PHASE)); 848 } 849 850 851 int 852 sci_request_sense(ctlr, slave, unit, buf, len) 853 int ctlr, slave, unit; 854 u_char *buf; 855 unsigned len; 856 { 857 register struct sci_softc *dev = &sci_softc[ctlr]; 858 static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE }; 859 860 cdb.lun = unit; 861 cdb.len = len; 862 return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), buf, len, DATA_IN_PHASE)); 863 } 864 865 int 866 sci_immed_command_nd(ctlr, slave, unit, cdb) 867 int ctlr, slave, unit; 868 struct scsi_fmt_cdb *cdb; 869 { 870 register struct sci_softc *dev = &sci_softc[ctlr]; 871 872 cdb->cdb[1] |= (unit << 5); 873 return(scsiicmd(dev, slave, (u_char *) cdb->cdb, cdb->len, 874 0, 0, STATUS_PHASE)); 875 } 876 877 int 878 sci_immed_command(ctlr, slave, unit, cdb, buf, len, rd) 879 int ctlr, slave, unit; 880 struct scsi_fmt_cdb *cdb; 881 u_char *buf; 882 unsigned len; 883 { 884 register struct sci_softc *dev = &sci_softc[ctlr]; 885 886 cdb->cdb[1] |= (unit << 5); 887 return (scsiicmd(dev, slave, (u_char *) cdb->cdb, cdb->len, buf, len, 888 rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE)); 889 } 890 891 /* 892 * The following routines are test-and-transfer i/o versions of read/write 893 * for things like reading disk labels and writing core dumps. The 894 * routine scigo should be used for normal data transfers, NOT these 895 * routines. 896 */ 897 int 898 sci_tt_read(ctlr, slave, unit, buf, len, blk, bshift) 899 int ctlr, slave, unit; 900 u_char *buf; 901 u_int len; 902 daddr_t blk; 903 int bshift; 904 { 905 register struct sci_softc *dev = &sci_softc[ctlr]; 906 struct scsi_cdb10 cdb; 907 int stat; 908 int old_wait = sci_data_wait; 909 910 sci_data_wait = 300000; 911 bzero(&cdb, sizeof(cdb)); 912 cdb.cmd = CMD_READ_EXT; 913 cdb.lun = unit; 914 blk >>= bshift; 915 cdb.lbah = blk >> 24; 916 cdb.lbahm = blk >> 16; 917 cdb.lbalm = blk >> 8; 918 cdb.lbal = blk; 919 cdb.lenh = len >> (8 + DEV_BSHIFT + bshift); 920 cdb.lenl = len >> (DEV_BSHIFT + bshift); 921 stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE); 922 sci_data_wait = old_wait; 923 return (stat); 924 } 925 926 int 927 sci_tt_write(ctlr, slave, unit, buf, len, blk, bshift) 928 int ctlr, slave, unit; 929 u_char *buf; 930 u_int len; 931 daddr_t blk; 932 int bshift; 933 { 934 register struct sci_softc *dev = &sci_softc[ctlr]; 935 struct scsi_cdb10 cdb; 936 int stat; 937 int old_wait = sci_data_wait; 938 939 sci_data_wait = 300000; 940 941 bzero(&cdb, sizeof(cdb)); 942 cdb.cmd = CMD_WRITE_EXT; 943 cdb.lun = unit; 944 blk >>= bshift; 945 cdb.lbah = blk >> 24; 946 cdb.lbahm = blk >> 16; 947 cdb.lbalm = blk >> 8; 948 cdb.lbal = blk; 949 cdb.lenh = len >> (8 + DEV_BSHIFT + bshift); 950 cdb.lenl = len >> (DEV_BSHIFT + bshift); 951 stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE); 952 sci_data_wait = old_wait; 953 return (stat); 954 } 955 956 int 957 scireq(dq) 958 register struct devqueue *dq; 959 { 960 register struct devqueue *hq; 961 962 hq = &sci_softc[dq->dq_ctlr].sc_sq; 963 insque(dq, hq->dq_back); 964 if (dq->dq_back == hq) 965 return(1); 966 return(0); 967 } 968 969 int 970 sciustart (int unit) 971 { 972 register struct sci_softc *dev = &sci_softc[unit]; 973 974 /* If we got here, this controller is not busy 975 so we are ready to accept a command 976 */ 977 return(1); 978 } 979 980 void 981 scistart (int unit) 982 { 983 register struct devqueue *dq; 984 985 dq = sci_softc[unit].sc_sq.dq_forw; 986 (dq->dq_driver->d_go)(dq->dq_unit); 987 } 988 989 int 990 scigo(ctlr, slave, unit, bp, cdb, pad) 991 int ctlr, slave, unit; 992 struct buf *bp; 993 struct scsi_fmt_cdb *cdb; 994 int pad; 995 { 996 register struct sci_softc *dev = &sci_softc[ctlr]; 997 u_char phase, csr, asr, cmd; 998 char *addr; 999 int count; 1000 register struct devqueue *dq; 1001 1002 cdb->cdb[1] |= unit << 5; 1003 1004 addr = bp->b_un.b_addr; 1005 count = bp->b_bcount; 1006 1007 if (sci_no_dma) { 1008 1009 scsiicmd (dev, slave, (u_char *) cdb->cdb, cdb->len, 1010 addr, count, 1011 bp->b_flags & B_READ ? DATA_IN_PHASE : DATA_OUT_PHASE); 1012 1013 dq = dev->sc_sq.dq_forw; 1014 dev->sc_flags &=~ (SCI_IO); 1015 (dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]); 1016 return dev->sc_stat[0]; 1017 } 1018 1019 /* select the SCSI bus (it's an error if bus isn't free) */ 1020 if (issue_select (dev, slave, dev->sc_scsi_addr)) 1021 return -1; 1022 /* 1023 * Wait for a phase change (or error) then let the device 1024 * sequence us through the various SCSI phases. 1025 */ 1026 dev->sc_stat[0] = 0xff; 1027 dev->sc_msg[0] = 0xff; 1028 phase = CMD_PHASE; 1029 while (1) { 1030 while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == 1031 SCI_BUS_BSY); 1032 1033 QPRINTF((">CSR:%02x<", *dev->sci_bus_csr)); 1034 if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) { 1035 goto abort; 1036 } 1037 phase = SCI_PHASE(*dev->sci_bus_csr); 1038 1039 switch (phase) { 1040 case CMD_PHASE: 1041 if (ixfer_out (dev, cdb->len, cdb->cdb, phase)) 1042 goto abort; 1043 phase = bp->b_flags & B_READ ? DATA_IN_PHASE : DATA_OUT_PHASE; 1044 break; 1045 1046 case DATA_IN_PHASE: 1047 if (count <= 0) 1048 goto abort; 1049 /* XXX use psuedo DMA if available */ 1050 if (count >= 128 && dev->dma_xfer_in) 1051 (*dev->dma_xfer_in)(dev, count, addr, phase); 1052 else 1053 ixfer_in (dev, count, addr, phase); 1054 phase = STATUS_PHASE; 1055 break; 1056 1057 case DATA_OUT_PHASE: 1058 if (count <= 0) 1059 goto abort; 1060 /* XXX use psuedo DMA if available */ 1061 if (count >= 128 && dev->dma_xfer_out) 1062 (*dev->dma_xfer_out)(dev, count, addr, phase); 1063 else 1064 if (ixfer_out (dev, count, addr, phase)) 1065 goto abort; 1066 phase = STATUS_PHASE; 1067 break; 1068 1069 case MESG_IN_PHASE: 1070 dev->sc_msg[0] = 0xff; 1071 ixfer_in (dev, 1, dev->sc_msg,phase); 1072 dev->sc_flags &= ~SCI_SELECTED; 1073 while (*dev->sci_bus_csr & SCI_BUS_BSY); 1074 goto out; 1075 break; 1076 1077 case MESG_OUT_PHASE: 1078 phase = STATUS_PHASE; 1079 break; 1080 1081 case STATUS_PHASE: 1082 ixfer_in (dev, 1, dev->sc_stat, phase); 1083 phase = MESG_IN_PHASE; 1084 break; 1085 1086 case BUS_FREE_PHASE: 1087 goto out; 1088 1089 default: 1090 printf("sci: unexpected phase %d in icmd from %d\n", 1091 phase, slave); 1092 goto abort; 1093 } 1094 } 1095 1096 abort: 1097 scsiabort(dev, "go"); 1098 out: 1099 QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 1100 dq = dev->sc_sq.dq_forw; 1101 dev->sc_flags &=~ (SCI_IO); 1102 (dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]); 1103 return dev->sc_stat[0]; 1104 } 1105 1106 void 1107 scidone (int unit) 1108 { 1109 1110 #ifdef DEBUG 1111 if (sci_debug) 1112 printf("sci%d: done called!\n", unit); 1113 #endif 1114 } 1115 1116 int 1117 sciintr () 1118 { 1119 register struct sci_softc *dev = sci_softc; 1120 int unit; 1121 int dummy; 1122 int found = 0; 1123 1124 for (unit = 0; unit < NSCI; ++unit, ++dev) { 1125 if (dev->sc_ac->amiga_ipl == 0) 1126 continue; 1127 /* XXX check if expecting interrupt? */ 1128 if (dev->dma_intr) 1129 found += (*dev->dma_intr)(dev); 1130 else if ((*dev->sci_csr & SCI_CSR_INT)) { 1131 *dev->sci_mode = 0; 1132 dummy = *dev->sci_iack; 1133 ++found; 1134 } 1135 } 1136 return found; 1137 } 1138 1139 void 1140 scifree(dq) 1141 register struct devqueue *dq; 1142 { 1143 register struct devqueue *hq; 1144 1145 hq = &sci_softc[dq->dq_ctlr].sc_sq; 1146 remque(dq); 1147 if ((dq = hq->dq_forw) != hq) 1148 (dq->dq_driver->d_start)(dq->dq_unit); 1149 } 1150 1151 /* 1152 * (XXX) The following routine is needed for the SCSI tape driver 1153 * to read odd-size records. 1154 */ 1155 1156 #if NST > 0 1157 int 1158 sci_tt_oddio(ctlr, slave, unit, buf, len, b_flags, freedma) 1159 int ctlr, slave, unit, b_flags; 1160 u_char *buf; 1161 u_int len; 1162 { 1163 register struct sci_softc *dev = &sci_softc[ctlr]; 1164 struct scsi_cdb6 cdb; 1165 u_char iphase; 1166 int stat; 1167 1168 /* 1169 * First free any DMA channel that was allocated. 1170 * We can't use DMA to do this transfer. 1171 */ 1172 /* 1173 * Initialize command block 1174 */ 1175 bzero(&cdb, sizeof(cdb)); 1176 cdb.lun = unit; 1177 cdb.lbam = (len >> 16) & 0xff; 1178 cdb.lbal = (len >> 8) & 0xff; 1179 cdb.len = len & 0xff; 1180 if (buf == 0) { 1181 cdb.cmd = CMD_SPACE; 1182 cdb.lun |= 0x00; 1183 len = 0; 1184 iphase = MESG_IN_PHASE; 1185 } else if (b_flags & B_READ) { 1186 cdb.cmd = CMD_READ; 1187 iphase = DATA_IN_PHASE; 1188 } else { 1189 cdb.cmd = CMD_WRITE; 1190 iphase = DATA_OUT_PHASE; 1191 } 1192 /* 1193 * Perform command (with very long delays) 1194 */ 1195 sci_delay(30000000); 1196 stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, iphase); 1197 sci_delay(0); 1198 return (stat); 1199 } 1200 #endif 1201 #endif 1202