Home | History | Annotate | Line # | Download | only in boot
sc.c revision 1.7
      1 /*	$NetBSD: sc.c,v 1.7 2014/01/02 19:50:03 tsutsui Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1992 OMRON Corporation.
      5  *
      6  * This code is derived from software contributed to Berkeley by
      7  * OMRON Corporation.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *	This product includes software developed by the University of
     20  *	California, Berkeley and its contributors.
     21  * 4. Neither the name of the University nor the names of its contributors
     22  *    may be used to endorse or promote products derived from this software
     23  *    without specific prior written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  * SUCH DAMAGE.
     36  *
     37  *	@(#)sc.c	8.1 (Berkeley) 6/10/93
     38  */
     39 /*
     40  * Copyright (c) 1992, 1993
     41  *	The Regents of the University of California.  All rights reserved.
     42  *
     43  * This code is derived from software contributed to Berkeley by
     44  * OMRON Corporation.
     45  *
     46  * Redistribution and use in source and binary forms, with or without
     47  * modification, are permitted provided that the following conditions
     48  * are met:
     49  * 1. Redistributions of source code must retain the above copyright
     50  *    notice, this list of conditions and the following disclaimer.
     51  * 2. Redistributions in binary form must reproduce the above copyright
     52  *    notice, this list of conditions and the following disclaimer in the
     53  *    documentation and/or other materials provided with the distribution.
     54  * 3. Neither the name of the University nor the names of its contributors
     55  *    may be used to endorse or promote products derived from this software
     56  *    without specific prior written permission.
     57  *
     58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  * SUCH DAMAGE.
     69  *
     70  *	@(#)sc.c	8.1 (Berkeley) 6/10/93
     71  */
     72 
     73 /*
     74  * sc.c -- SCSI Protocole Controller (SPC)  driver
     75  * remaked by A.Fujita, MAR-11-199
     76  */
     77 
     78 
     79 #define NSC	2
     80 
     81 #include <sys/param.h>
     82 #include <luna68k/stand/boot/samachdep.h>
     83 #include <luna68k/stand/boot/scsireg.h>
     84 #include <luna68k/stand/boot/device.h>
     85 #include <luna68k/stand/boot/scsivar.h>
     86 
     87 #define SCSI_IPL	2
     88 #define SCSI_ID		7
     89 
     90 static int scinit(void *);
     91 static void screset(int);
     92 static int issue_select(struct scsidevice *, u_char);
     93 static void ixfer_start(struct scsidevice *, int, u_char, int);
     94 static void ixfer_out(struct scsidevice *, int, u_char *);
     95 static void ixfer_in(struct scsidevice *, int, u_char *);
     96 static int scrun(int, int, u_char *, int, u_char *, int, volatile int *);
     97 static int scfinish(int);
     98 static void scabort(struct scsi_softc *, struct scsidevice *);
     99 
    100 struct	driver scdriver = {
    101 	scinit, "sc", scintr,
    102 };
    103 
    104 struct	scsi_softc scsi_softc[NSC];
    105 
    106 /*
    107  * Initialize SPC & Data Structure
    108  */
    109 
    110 int
    111 scinit(void *arg)
    112 {
    113 	struct hp_ctlr *hc = arg;
    114 	struct scsi_softc *hs;
    115 	int unit;
    116 
    117 	unit = hc->hp_unit;
    118 	if (unit < 0 || unit >= NSC)
    119 		return 0;
    120 
    121 	hs = &scsi_softc[unit];
    122 
    123 	hc->hp_ipl    = SCSI_IPL;
    124 	hs->sc_hc     = hc;
    125 
    126 	hs->sc_flags  = 0;
    127 	hs->sc_phase  = BUS_FREE_PHASE;
    128 	hs->sc_target = SCSI_ID;
    129 
    130 	hs->sc_cdb    = NULL;
    131 	hs->sc_cdblen = 0;
    132 	hs->sc_buf    = NULL;
    133 	hs->sc_len    = 0;
    134 	hs->sc_lock   = NULL;
    135 
    136 	hs->sc_stat   = 0;
    137 	hs->sc_msg[0] = 0;
    138 
    139 	screset(hc->hp_unit);
    140 	return(1);
    141 }
    142 
    143 void
    144 screset(int unit)
    145 {
    146 	struct scsi_softc *hs = &scsi_softc[unit];
    147 	struct scsidevice *hd = (struct scsidevice *)hs->sc_hc->hp_addr;
    148 
    149 	printf("sc%d: ", unit);
    150 
    151 	/*
    152 	 * Disable interrupts then reset the FUJI chip.
    153 	 */
    154 
    155 	hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
    156 	hd->scsi_scmd = 0;
    157 	hd->scsi_pctl = 0;
    158 	hd->scsi_temp = 0;
    159 	hd->scsi_tch  = 0;
    160 	hd->scsi_tcm  = 0;
    161 	hd->scsi_tcl  = 0;
    162 	hd->scsi_ints = 0;
    163 
    164 	/* We can use Asynchronous Transfer only */
    165 	printf("async");
    166 
    167 	/*
    168 	 * Configure MB89352 with its SCSI address, all
    169 	 * interrupts enabled & appropriate parity.
    170 	 */
    171 	hd->scsi_bdid = SCSI_ID;
    172 	hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB|
    173 			SCTL_PARITY_ENAB | SCTL_RESEL_ENAB |
    174 			SCTL_INTR_ENAB;
    175 	printf(", parity");
    176 
    177 	DELAY(400);
    178 	hd->scsi_sctl &= ~SCTL_DISABLE;
    179 
    180 	printf(", scsi id %d\n", SCSI_ID);
    181 }
    182 
    183 
    184 /*
    185  * SPC Arbitration/Selection routine
    186  */
    187 
    188 int
    189 issue_select(struct scsidevice *hd, u_char target)
    190 {
    191 	hd->scsi_pctl = 0;
    192 	hd->scsi_temp = (1 << SCSI_ID) | (1 << target);
    193 
    194 	/* select timeout is hardcoded to 250ms */
    195 	hd->scsi_tch = 2;
    196 	hd->scsi_tcm = 113;
    197 	hd->scsi_tcl = 3;
    198 
    199 	hd->scsi_scmd = SCMD_SELECT;
    200 
    201 	return (1);
    202 }
    203 
    204 
    205 /*
    206  * SPC Manual Transfer routines
    207  */
    208 
    209 /* not yet */
    210 
    211 
    212 /*
    213  * SPC Program Transfer routines
    214  */
    215 
    216 void
    217 ixfer_start(struct scsidevice *hd, int len, u_char phase, int wait)
    218 {
    219 	hd->scsi_tch  = ((len & 0xff0000) >> 16);
    220 	hd->scsi_tcm  = ((len & 0x00ff00) >>  8);
    221 	hd->scsi_tcl  =  (len & 0x0000ff);
    222 	hd->scsi_pctl = phase;
    223 	hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
    224 }
    225 
    226 void
    227 ixfer_out(struct scsidevice *hd, int len, u_char *buf)
    228 {
    229 	for(; len > 0; len--) {
    230 		while (hd->scsi_ssts & SSTS_DREG_FULL) {
    231 			DELAY(5);
    232 		}
    233 		hd->scsi_dreg = *buf++;
    234 	}
    235 }
    236 
    237 void
    238 ixfer_in(struct scsidevice *hd, int len, u_char *buf)
    239 {
    240 	for (; len > 0; len--) {
    241 		while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
    242 			DELAY(5);
    243 		}
    244 		*buf++ = hd->scsi_dreg;
    245 	}
    246 }
    247 
    248 
    249 /*
    250  * SPC drive routines
    251  */
    252 
    253 int
    254 scrun(int ctlr, int slave, u_char *cdb, int cdblen, u_char *buf, int len,
    255     volatile int *lock)
    256 {
    257 	struct scsi_softc *hs;
    258 	struct scsidevice *hd;
    259 
    260 	if (ctlr < 0 || ctlr >= NSC)
    261 		return 0;
    262 
    263 	hs = &scsi_softc[ctlr];
    264 	hd = (struct scsidevice *)hs->sc_hc->hp_addr;
    265 
    266 	if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
    267 		return(0);
    268 
    269 	hs->sc_flags  = 0;
    270 	hs->sc_phase  = ARB_SEL_PHASE;
    271 	hs->sc_target = slave;
    272 
    273 	hs->sc_cdb    = cdb;
    274 	hs->sc_cdblen = cdblen;
    275 	hs->sc_buf    = buf;
    276 	hs->sc_len    = len;
    277 	hs->sc_lock   = lock;
    278 
    279 	hs->sc_stat   = 0;
    280 	hs->sc_msg[0] = 0;
    281 
    282 	*(hs->sc_lock) = SC_IN_PROGRESS;
    283 	issue_select(hd, hs->sc_target);
    284 
    285 	return(1);
    286 }
    287 
    288 int
    289 scfinish(int ctlr)
    290 {
    291 	struct scsi_softc *hs = &scsi_softc[ctlr];
    292 	int status = hs->sc_stat;
    293 
    294 	hs->sc_flags  = 0;
    295 	hs->sc_phase  = BUS_FREE_PHASE;
    296 	hs->sc_target = SCSI_ID;
    297 
    298 	hs->sc_cdb    = NULL;
    299 	hs->sc_cdblen = 0;
    300 	hs->sc_buf    = NULL;
    301 	hs->sc_len    = 0;
    302 	hs->sc_lock   = NULL;
    303 
    304 	hs->sc_stat   = 0;
    305 	hs->sc_msg[0] = 0;
    306 
    307 	return(status);
    308 }
    309 
    310 void
    311 scabort(struct scsi_softc *hs, struct scsidevice *hd)
    312 {
    313 	int len;
    314 	u_char junk;
    315 
    316 	printf("sc%d: abort  phase=0x%x, ssts=0x%x, ints=0x%x\n",
    317 		hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts,
    318 		hd->scsi_ints);
    319 
    320 	if (hd->scsi_ints != 0)
    321 		hd->scsi_ints = hd->scsi_ints;
    322 
    323 	if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
    324 		/* no longer connected to scsi target */
    325 		return;
    326 
    327 	/* get the number of bytes remaining in current xfer + fudge */
    328 	len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;
    329 
    330 	/* for that many bus cycles, try to send an abort msg */
    331 	for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
    332 		hd->scsi_scmd = SCMD_SET_ATN;
    333 
    334 		while ((hd->scsi_psns & PSNS_REQ) == 0) {
    335 			if (! (hd->scsi_ssts & SSTS_INITIATOR))
    336 				goto out;
    337 			DELAY(1);
    338 		}
    339 
    340 		if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE)
    341 			hd->scsi_scmd = SCMD_RST_ATN;
    342 		hd->scsi_pctl = hs->sc_phase = hd->scsi_psns & PHASE;
    343 
    344 		if (hd->scsi_psns & PHASE_IO) {
    345 			/* one of the input phases - read & discard a byte */
    346 			hd->scsi_scmd = SCMD_SET_ACK;
    347 			while (hd->scsi_psns & PSNS_REQ)
    348 				DELAY(1);
    349 			junk = hd->scsi_temp;
    350 		} else {
    351 			/* one of the output phases - send an abort msg */
    352 			hd->scsi_temp = MSG_ABORT;
    353 			hd->scsi_scmd = SCMD_SET_ACK;
    354 			while (hd->scsi_psns & PSNS_REQ)
    355 				DELAY(1);
    356 		}
    357 
    358 		hd->scsi_scmd = SCMD_RST_ACK;
    359 	}
    360 out:
    361 	/*
    362 	 * Either the abort was successful & the bus is disconnected or
    363 	 * the device didn't listen.  If the latter, announce the problem.
    364 	 * Either way, reset the card & the SPC.
    365 	 */
    366 	if (len < 0 && hs)
    367 		printf("sc%d: abort failed.  phase=0x%x, ssts=0x%x\n",
    368 			hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts);
    369 }
    370 
    371 
    372 /*
    373  * SCSI Command Handler
    374  */
    375 
    376 int
    377 scsi_test_unit_rdy(int ctlr, int slave, int unit)
    378 {
    379 	static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
    380 	int status;
    381 	volatile int lock;
    382 
    383 #ifdef DEBUG
    384 	printf("scsi_test_unit_rdy( %d, %d, %d): Start\n", ctlr, slave, unit);
    385 #endif
    386 
    387 	cdb.lun = unit;
    388 
    389 	if (!(scrun(ctlr, slave, (void *)&cdb, 6, NULL, 0, &lock))) {
    390 #ifdef DEBUG
    391 		printf("scsi_test_unit_rdy: Command Transfer Failed.\n");
    392 #endif
    393 		return(-1);
    394 	}
    395 
    396 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
    397 		DELAY(10);
    398 
    399 	status = scfinish(ctlr);
    400 
    401 	if (lock == SC_IO_COMPLETE) {
    402 #ifdef DEBUG
    403 		printf("scsi_test_unit_rdy: Status -- 0x%x\n", status);
    404 #endif
    405 		return(status);
    406 	} else {
    407 		return(lock);
    408 	}
    409 }
    410 
    411 int
    412 scsi_request_sense(int ctlr, int slave, int unit, u_char *buf, unsigned int len)
    413 {
    414 	static struct scsi_cdb6 cdb = {	CMD_REQUEST_SENSE };
    415 	int status;
    416 	volatile int lock;
    417 
    418 #ifdef DEBUG
    419 	printf("scsi_request_sense: Start\n");
    420 #endif
    421 
    422 	/* Request Sense        */
    423 	/* Additional Sens Length*/
    424 	/* cdbAllocation Length */
    425 	/*          */
    426 
    427 	/* Addtional Sens Field */
    428 	/* len            */
    429 
    430 	cdb.lun = unit;
    431 	cdb.len = len;
    432 
    433 	if (!(scrun(ctlr, slave, (void *)&cdb, 6, buf, len, &lock))) {
    434 #ifdef DEBUG
    435 		printf("scsi_request_sense: Command Transfer Failed.\n");
    436 #endif
    437 		return(-1);
    438 	}
    439 
    440 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
    441 		DELAY(10);
    442 
    443 	status = scfinish(ctlr);
    444 
    445 	if (lock == SC_IO_COMPLETE) {
    446 #ifdef DEBUG
    447 		printf("scsi_request_sense: Status -- 0x%x\n", status);
    448 #endif
    449 		return(status);
    450 	} else {
    451 		return(lock);
    452 	}
    453 }
    454 
    455 int
    456 scsi_immed_command(int ctlr, int slave, int unit, struct scsi_fmt_cdb *cdb,
    457     u_char *buf, unsigned int len)
    458 {
    459 	int status;
    460 	volatile int lock;
    461 
    462 #ifdef DEBUG
    463 	printf("scsi_immed_command( %d, %d, %d, cdb(%d), buf, %d): Start\n",
    464 	       ctlr, slave, unit, cdb->len, len);
    465 #endif
    466 
    467 	cdb->cdb[1] |= unit << 5;
    468 
    469 	if (!(scrun(ctlr, slave, (void *)&cdb->cdb[0], cdb->len, buf, len, &lock))) {
    470 #ifdef DEBUG
    471 		printf("scsi_immed_command: Command Transfer Failed.\n");
    472 #endif
    473 		return(-1);
    474 	}
    475 
    476 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
    477 		DELAY(10);
    478 
    479 	status = scfinish(ctlr);
    480 
    481 	if (lock == SC_IO_COMPLETE) {
    482 #ifdef DEBUG
    483 		printf("scsi_immed_command: Status -- 0x%x\n", status);
    484 #endif
    485 		return(status);
    486 	} else {
    487 		return(lock);
    488 	}
    489 }
    490 
    491 int
    492 scsi_format_unit(int ctlr, int slave, int unit)
    493 {
    494 	static struct scsi_cdb6 cdb = { CMD_FORMAT_UNIT, 0, 0, 0, 0, 0 };
    495 	int status;
    496 	volatile int lock;
    497 #ifdef DEBUG
    498 	int count = 0;
    499 #endif
    500 
    501 #ifdef DEBUG
    502 	printf("scsi_format_unit( %d, %d, %d): Start\n", ctlr, slave, unit);
    503 #endif
    504 
    505 	cdb.lun = unit;
    506 
    507 	if (!(scrun(ctlr, slave, (void *)&cdb, 6, (u_char *) 0, 0, &lock))) {
    508 #ifdef DEBUG
    509 		printf("scsi_format_unit: Command Transfer Failed.\n");
    510 #endif
    511 		return(-1);
    512 	}
    513 
    514 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) {
    515 		DELAY(1000000);
    516 #ifdef DEBUG
    517 		if ((++count % 60) == 0)
    518 			printf("scsi_format_unit: %d\n", count / 60);
    519 #endif
    520 	}
    521 
    522 	status = scfinish(ctlr);
    523 
    524 	if (lock == SC_IO_COMPLETE) {
    525 #ifdef DEBUG
    526 		printf("scsi_format_unit: Status -- 0x%x\n", status);
    527 #endif
    528 		return(status);
    529 	} else {
    530 		return(lock);
    531 	}
    532 }
    533 
    534 
    535 /*
    536  * Interrupt Routine
    537  */
    538 
    539 int
    540 scintr(void)
    541 {
    542 	struct scsi_softc *hs;
    543 	struct scsidevice *hd;
    544 	u_char ints, temp;
    545 	int i;
    546 	u_char *buf;
    547 	int len;
    548 
    549 	for (i = 0; i < NSC; i++) {
    550 		hs = &scsi_softc[i];
    551 		hd = (struct scsidevice *) hs->sc_hc->hp_addr;
    552 		if ((ints = hd->scsi_ints) != 0)
    553 			goto get_intr;
    554 	}
    555 
    556 	/* Unknown Interrupt occured */
    557 	return -1;
    558 
    559 
    560 	/*
    561 	 * Interrupt
    562 	 */
    563 
    564  get_intr:
    565 #ifdef DEBUG
    566 	printf("scintr: INTS 0x%x, SSTS 0x%x,  PCTL 0x%x,  PSNS 0x%x    0x%x\n",
    567 	        ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns,
    568 	        hs->sc_phase);
    569 #endif
    570 	if (ints & INTS_RESEL) {
    571 		if (hs->sc_phase == BUS_FREE_PHASE) {
    572 			temp = hd->scsi_temp & ~(1 << SCSI_ID);
    573 			for (i = 0; temp != 1; i++) {
    574 				temp >>= 1;
    575 			}
    576 			hs->sc_target = i;
    577 			*(hs->sc_lock) = SC_IN_PROGRESS;
    578 		} else
    579 			goto abort;
    580 	} else if (ints & INTS_DISCON) {
    581 		if ((hs->sc_msg[0] == MSG_CMD_COMPLETE) || (hs->sc_msg[0] == MSG_DISCONNECT)) {
    582 			hs->sc_phase  = BUS_FREE_PHASE;
    583 			hs->sc_target = SCSI_ID;
    584 			if (hs->sc_msg[0] == MSG_CMD_COMPLETE)
    585 				/* SCSI IO complete */
    586 				*(hs->sc_lock) = SC_IO_COMPLETE;
    587 			else
    588 				/* Cisconnected from Target */
    589 				*(hs->sc_lock) = SC_DISCONNECTED;
    590 			hd->scsi_ints = ints;
    591 			return 0;
    592 		} else
    593 			goto abort;
    594 	} else if (ints & INTS_CMD_DONE) {
    595 		if (hs->sc_phase == BUS_FREE_PHASE)
    596 			goto abort;
    597 		else if (hs->sc_phase == MESG_IN_PHASE) {
    598 			hd->scsi_scmd = SCMD_RST_ACK;
    599 			hd->scsi_ints = ints;
    600 			hs->sc_phase  = hd->scsi_psns & PHASE;
    601 			return 0;
    602 		}
    603 		if (hs->sc_flags & SC_SEL_TIMEOUT)
    604 			hs->sc_flags &= ~SC_SEL_TIMEOUT;
    605 	} else if (ints & INTS_SRV_REQ) {
    606 		if (hs->sc_phase != MESG_IN_PHASE)
    607 			goto abort;
    608 	} else if (ints & INTS_TIMEOUT) {
    609 		if (hs->sc_phase == ARB_SEL_PHASE) {
    610 			if (hs->sc_flags & SC_SEL_TIMEOUT) {
    611 				hs->sc_flags &= ~SC_SEL_TIMEOUT;
    612 				hs->sc_phase  = BUS_FREE_PHASE;
    613 				hs->sc_target = SCSI_ID;
    614 				/* Such SCSI Device is not conected. */
    615 				*(hs->sc_lock) = SC_DEV_NOT_FOUND;
    616 				hd->scsi_ints = ints;
    617 				return 0;
    618 			} else {
    619 				/* wait more 250 usec */
    620 				hs->sc_flags |= SC_SEL_TIMEOUT;
    621 				hd->scsi_temp = 0;
    622 				hd->scsi_tch  = 0;
    623 				hd->scsi_tcm  = 0x06;
    624 				hd->scsi_tcl  = 0x40;
    625 				hd->scsi_ints = ints;
    626 				return 0;
    627 			}
    628 		} else
    629 			goto abort;
    630 	} else
    631 		goto abort;
    632 
    633 	hd->scsi_ints = ints;
    634 
    635 	/*
    636 	 * Next SCSI Transfer
    637 	 */
    638 
    639 	while ((hd->scsi_psns & PSNS_REQ) == 0) {
    640 		DELAY(1);
    641 	}
    642 
    643 	hs->sc_phase = hd->scsi_psns & PHASE;
    644 
    645 	if ((hs->sc_phase == DATA_OUT_PHASE) || (hs->sc_phase == DATA_IN_PHASE)) {
    646 		len = hs->sc_len;
    647 		buf = hs->sc_buf;
    648 	} else if (hs->sc_phase == CMD_PHASE) {
    649 		len = hs->sc_cdblen;
    650 		buf = hs->sc_cdb;
    651 	} else if (hs->sc_phase == STATUS_PHASE) {
    652 		len = 1;
    653 		buf = &hs->sc_stat;
    654 	} else {
    655 		len = 1;
    656 		buf = hs->sc_msg;
    657 	}
    658 
    659 	ixfer_start(hd, len, hs->sc_phase, 0);
    660 	if (hs->sc_phase & PHASE_IO)
    661 		ixfer_in(hd, len, buf);
    662 	else
    663 		ixfer_out(hd, len, buf);
    664 
    665 	return 0;
    666 
    667 	/*
    668 	 * SCSI Abort
    669 	 */
    670  abort:
    671 	/* SCSI IO failed */
    672 	scabort(hs, hd);
    673 	hd->scsi_ints = ints;
    674 	*(hs->sc_lock) = SC_IO_FAILED;
    675 	return -1;
    676 }
    677