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