157096Sakito /*
257096Sakito * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic * Copyright (c) 1992, 1993
4*63199Sbostic * The Regents of the University of California. All rights reserved.
557096Sakito *
657096Sakito * This code is derived from software contributed to Berkeley by
757096Sakito * OMRON Corporation.
857096Sakito *
957096Sakito * %sccs.include.redist.c%
1057096Sakito *
11*63199Sbostic * @(#)sc.c 8.1 (Berkeley) 06/10/93
1257096Sakito */
1357096Sakito
1457096Sakito /*
1557096Sakito * sc.c -- SCSI Protocole Controller (SPC) driver
1657096Sakito * remaked by A.Fujita, MAR-11-199
1757096Sakito */
1857096Sakito
1957096Sakito
2057096Sakito #define NSC 1
2157096Sakito
2257096Sakito #include <sys/param.h>
2357096Sakito #include <luna68k/dev/scsireg.h>
2457096Sakito #include <luna68k/stand/device.h>
2557096Sakito #include <luna68k/stand/scsivar.h>
2657096Sakito
2757096Sakito #define SCSI_IPL 2
2857096Sakito #define SCSI_ID 7
2957096Sakito
3057096Sakito int scinit(), scstart(), scgo(), scintr(), scdone();
3157096Sakito void screset();
3257096Sakito struct driver scdriver = {
3357096Sakito scinit, "sc", scstart, scgo, scintr, scdone
3457096Sakito };
3557096Sakito
3657096Sakito struct scsi_softc scsi_softc[NSC];
3757096Sakito
3857096Sakito /*
3957096Sakito * Initialize SPC & Data Structure
4057096Sakito */
4157096Sakito
4257096Sakito int
scinit(hc)4357096Sakito scinit(hc)
4457096Sakito register struct hp_ctlr *hc;
4557096Sakito {
4657096Sakito register struct scsi_softc *hs = &scsi_softc[hc->hp_unit];
4757096Sakito register int i;
4857096Sakito
4957096Sakito hc->hp_ipl = SCSI_IPL;
5057096Sakito hs->sc_hc = hc;
5157096Sakito
5257096Sakito hs->sc_flags = 0;
5357096Sakito hs->sc_phase = BUS_FREE_PHASE;
5457096Sakito hs->sc_target = SCSI_ID;
5557096Sakito
5657096Sakito hs->sc_cdb = NULL;
5757096Sakito hs->sc_cdblen = 0;
5857096Sakito hs->sc_buf = NULL;
5957096Sakito hs->sc_len = 0;
6057096Sakito hs->sc_lock = NULL;
6157096Sakito
6257096Sakito hs->sc_stat = 0;
6357096Sakito hs->sc_msg[0] = 0;
6457096Sakito
6557096Sakito screset(hc->hp_unit);
6657096Sakito return(1);
6757096Sakito }
6857096Sakito
6957096Sakito void
screset(unit)7057096Sakito screset(unit)
7157096Sakito register int unit;
7257096Sakito {
7357096Sakito register struct scsi_softc *hs = &scsi_softc[unit];
7457096Sakito volatile register struct scsidevice *hd =
7557096Sakito (struct scsidevice *)hs->sc_hc->hp_addr;
7657096Sakito
7757096Sakito printf("sc%d: ", unit);
7857096Sakito
7957096Sakito /*
8057096Sakito * Disable interrupts then reset the FUJI chip.
8157096Sakito */
8257096Sakito
8357096Sakito hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
8457096Sakito hd->scsi_scmd = 0;
8557096Sakito hd->scsi_pctl = 0;
8657096Sakito hd->scsi_temp = 0;
8757096Sakito hd->scsi_tch = 0;
8857096Sakito hd->scsi_tcm = 0;
8957096Sakito hd->scsi_tcl = 0;
9057096Sakito hd->scsi_ints = 0;
9157096Sakito
9257096Sakito /* We can use Asynchronous Transfer only */
9357096Sakito printf("async");
9457096Sakito
9557096Sakito /*
9657096Sakito * Configure MB89352 with its SCSI address, all
9757096Sakito * interrupts enabled & appropriate parity.
9857096Sakito */
9957096Sakito hd->scsi_bdid = SCSI_ID;
10057096Sakito hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB|
10157096Sakito SCTL_PARITY_ENAB | SCTL_RESEL_ENAB |
10257096Sakito SCTL_INTR_ENAB;
10357096Sakito printf(", parity");
10457096Sakito
10557096Sakito DELAY(400);
10657096Sakito hd->scsi_sctl &= ~SCTL_DISABLE;
10757096Sakito
10857096Sakito printf(", scsi id %d\n", SCSI_ID);
10957096Sakito }
11057096Sakito
11157096Sakito
11257096Sakito /*
11357096Sakito * SPC Arbitration/Selection routine
11457096Sakito */
11557096Sakito
11657096Sakito int
issue_select(hd,target)11757096Sakito issue_select(hd, target)
11857096Sakito volatile register struct scsidevice *hd;
11957096Sakito u_char target;
12057096Sakito {
12157096Sakito hd->scsi_pctl = 0;
12257096Sakito hd->scsi_temp = (1 << SCSI_ID) | (1 << target);
12357096Sakito
12457096Sakito /* select timeout is hardcoded to 2ms */
12557096Sakito hd->scsi_tch = 0;
12657096Sakito hd->scsi_tcm = 32;
12757096Sakito hd->scsi_tcl = 4;
12857096Sakito
12957096Sakito hd->scsi_scmd = SCMD_SELECT;
13057096Sakito
13157096Sakito return (1);
13257096Sakito }
13357096Sakito
13457096Sakito
13557096Sakito /*
13657096Sakito * SPC Manual Transfer routines
13757096Sakito */
13857096Sakito
13957096Sakito /* not yet */
14057096Sakito
14157096Sakito
14257096Sakito /*
14357096Sakito * SPC Program Transfer routines
14457096Sakito */
14557096Sakito
14657096Sakito int
ixfer_start(hd,len,phase,wait)14757096Sakito ixfer_start(hd, len, phase, wait)
14857096Sakito volatile register struct scsidevice *hd;
14957096Sakito int len;
15057096Sakito u_char phase;
15157096Sakito register int wait;
15257096Sakito {
15357096Sakito hd->scsi_tch = ((len & 0xff0000) >> 16);
15457096Sakito hd->scsi_tcm = ((len & 0x00ff00) >> 8);
15557096Sakito hd->scsi_tcl = (len & 0x0000ff);
15657096Sakito hd->scsi_pctl = phase;
15757096Sakito hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
15857096Sakito }
15957096Sakito
16057096Sakito int
ixfer_out(hd,len,buf)16157096Sakito ixfer_out(hd, len, buf)
16257096Sakito volatile register struct scsidevice *hd;
16357096Sakito int len;
16457096Sakito register u_char *buf;
16557096Sakito {
16657096Sakito for(; len > 0; len--) {
16757096Sakito while (hd->scsi_ssts & SSTS_DREG_FULL) {
16857096Sakito DELAY(5);
16957096Sakito }
17057096Sakito hd->scsi_dreg = *buf++;
17157096Sakito }
17257096Sakito }
17357096Sakito
17457096Sakito int
ixfer_in(hd,len,buf)17557096Sakito ixfer_in(hd, len, buf)
17657096Sakito volatile register struct scsidevice *hd;
17757096Sakito int len;
17857096Sakito register u_char *buf;
17957096Sakito {
18057096Sakito for (; len > 0; len--) {
18157096Sakito int i;
18257096Sakito while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
18357096Sakito DELAY(5);
18457096Sakito }
18557096Sakito *buf++ = hd->scsi_dreg;
18657096Sakito }
18757096Sakito }
18857096Sakito
18957096Sakito
19057096Sakito /*
19157096Sakito * SPC drive routines
19257096Sakito */
19357096Sakito
19457096Sakito int
scrun(ctlr,slave,cdb,cdblen,buf,len,lock)19557096Sakito scrun(ctlr, slave, cdb, cdblen, buf, len, lock)
19657096Sakito int ctlr, slave;
19757096Sakito u_char *cdb;
19857096Sakito int cdblen;
19957096Sakito u_char *buf;
20057096Sakito int len;
20157096Sakito int *lock;
20257096Sakito {
20357096Sakito register struct scsi_softc *hs = &scsi_softc[ctlr];
20457096Sakito volatile register struct scsidevice *hd =
20557096Sakito (struct scsidevice *) hs->sc_hc->hp_addr;
20657096Sakito
20757096Sakito if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
20857096Sakito return(0);
20957096Sakito
21057096Sakito hs->sc_flags = 0;
21157096Sakito hs->sc_phase = ARB_SEL_PHASE;
21257096Sakito hs->sc_target = slave;
21357096Sakito
21457096Sakito hs->sc_cdb = cdb;
21557096Sakito hs->sc_cdblen = cdblen;
21657096Sakito hs->sc_buf = buf;
21757096Sakito hs->sc_len = len;
21857096Sakito hs->sc_lock = lock;
21957096Sakito
22057096Sakito hs->sc_stat = 0;
22157096Sakito hs->sc_msg[0] = 0;
22257096Sakito
22357096Sakito *(hs->sc_lock) = SC_IN_PROGRESS;
22457096Sakito issue_select(hd, hs->sc_target);
22557096Sakito
22657096Sakito return(1);
22757096Sakito }
22857096Sakito
22957096Sakito int
scfinish(ctlr)23057096Sakito scfinish(ctlr)
23157096Sakito int ctlr;
23257096Sakito {
23357096Sakito register struct scsi_softc *hs = &scsi_softc[ctlr];
23457096Sakito int status = hs->sc_stat;
23557096Sakito
23657096Sakito hs->sc_flags = 0;
23757096Sakito hs->sc_phase = BUS_FREE_PHASE;
23857096Sakito hs->sc_target = SCSI_ID;
23957096Sakito
24057096Sakito hs->sc_cdb = NULL;
24157096Sakito hs->sc_cdblen = 0;
24257096Sakito hs->sc_buf = NULL;
24357096Sakito hs->sc_len = 0;
24457096Sakito hs->sc_lock = NULL;
24557096Sakito
24657096Sakito hs->sc_stat = 0;
24757096Sakito hs->sc_msg[0] = 0;
24857096Sakito
24957096Sakito return(status);
25057096Sakito }
25157096Sakito
25257096Sakito int
scabort(hs,hd)25357096Sakito scabort(hs, hd)
25457096Sakito register struct scsi_softc *hs;
25557096Sakito volatile register struct scsidevice *hd;
25657096Sakito {
25757096Sakito int len;
25857096Sakito u_char junk;
25957096Sakito
26057096Sakito printf("sc%d: abort phase=0x%x, ssts=0x%x, ints=0x%x\n",
26157096Sakito hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts,
26257096Sakito hd->scsi_ints);
26357096Sakito
26457096Sakito if (hd->scsi_ints != 0)
26557096Sakito hd->scsi_ints = hd->scsi_ints;
26657096Sakito
26757096Sakito if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
26857096Sakito /* no longer connected to scsi target */
26957096Sakito return;
27057096Sakito
27157096Sakito /* get the number of bytes remaining in current xfer + fudge */
27257096Sakito len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;
27357096Sakito
27457096Sakito /* for that many bus cycles, try to send an abort msg */
27557096Sakito for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
27657096Sakito hd->scsi_scmd = SCMD_SET_ATN;
27757096Sakito
27857096Sakito while ((hd->scsi_psns & PSNS_REQ) == 0) {
27957096Sakito if (! (hd->scsi_ssts & SSTS_INITIATOR))
28057096Sakito goto out;
28157096Sakito DELAY(1);
28257096Sakito }
28357096Sakito
28457096Sakito if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE)
28557096Sakito hd->scsi_scmd = SCMD_RST_ATN;
28657096Sakito hd->scsi_pctl = hs->sc_phase = hd->scsi_psns & PHASE;
28757096Sakito
28857096Sakito if (hd->scsi_psns & PHASE_IO) {
28957096Sakito /* one of the input phases - read & discard a byte */
29057096Sakito hd->scsi_scmd = SCMD_SET_ACK;
29157096Sakito while (hd->scsi_psns & PSNS_REQ)
29257096Sakito DELAY(1);
29357096Sakito junk = hd->scsi_temp;
29457096Sakito } else {
29557096Sakito /* one of the output phases - send an abort msg */
29657096Sakito hd->scsi_temp = MSG_ABORT;
29757096Sakito hd->scsi_scmd = SCMD_SET_ACK;
29857096Sakito while (hd->scsi_psns & PSNS_REQ)
29957096Sakito DELAY(1);
30057096Sakito }
30157096Sakito
30257096Sakito hd->scsi_scmd = SCMD_RST_ACK;
30357096Sakito }
30457096Sakito out:
30557096Sakito /*
30657096Sakito * Either the abort was successful & the bus is disconnected or
30757096Sakito * the device didn't listen. If the latter, announce the problem.
30857096Sakito * Either way, reset the card & the SPC.
30957096Sakito */
31057096Sakito if (len < 0 && hs)
31157096Sakito printf("sc%d: abort failed. phase=0x%x, ssts=0x%x\n",
31257096Sakito hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts);
31357096Sakito }
31457096Sakito
31557096Sakito
31657096Sakito /*
31757096Sakito * SCSI Command Handler
31857096Sakito */
31957096Sakito
32057096Sakito int
scsi_test_unit_rdy(ctlr,slave,unit)32157096Sakito scsi_test_unit_rdy(ctlr, slave, unit)
32257096Sakito int ctlr, slave, unit;
32357096Sakito {
32457096Sakito static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
32557096Sakito int status, lock;
32657096Sakito
32757096Sakito #ifdef DEBUG
32857096Sakito printf("scsi_test_unit_rdy( %d, %d, %d): Start\n", ctlr, slave, unit);
32957096Sakito #endif
33057096Sakito
33157096Sakito cdb.lun = unit;
33257096Sakito
33357096Sakito if (!(scrun(ctlr, slave, &cdb, 6, (u_char *) 0, 0, &lock))) {
33457096Sakito #ifdef DEBUG
33557096Sakito printf("scsi_test_unit_rdy: Command Transfer Failed.\n");
33657096Sakito #endif
33757096Sakito return(-1);
33857096Sakito }
33957096Sakito
34057096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
34157096Sakito DELAY(10);
34257096Sakito
34357096Sakito status = scfinish(ctlr);
34457096Sakito
34557096Sakito if (lock == SC_IO_COMPLETE) {
34657096Sakito #ifdef DEBUG
34757096Sakito printf("scsi_test_unit_rdy: Status -- 0x%x\n", status);
34857096Sakito #endif
34957096Sakito return(status);
35057096Sakito } else {
35157096Sakito return(lock);
35257096Sakito }
35357096Sakito }
35457096Sakito
35557096Sakito int
scsi_request_sense(ctlr,slave,unit,buf,len)35657096Sakito scsi_request_sense(ctlr, slave, unit, buf, len)
35757096Sakito int ctlr, slave, unit;
35857096Sakito u_char *buf;
35957096Sakito unsigned len;
36057096Sakito {
36157096Sakito static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE };
36257096Sakito int status, lock;
36357096Sakito
36457096Sakito #ifdef DEBUG
36557096Sakito printf("scsi_request_sense: Start\n");
36657096Sakito #endif
36757096Sakito
36857096Sakito /* Request Sense$N>l9g!"E>Aw$5$l$k%G!<%?D9$O%?!<%2368H$K0MB8$7!" */
36957096Sakito /* %;%s%9%G!<%?$N#8/usr/home/csrg/sccs/sys/luna68k/stand/SCCS/s.sc.c$%HL\$NAddtional Sens Length$K$h$jF0E*$K7hDj$9$k!#*/
37057096Sakito /* $3$3$G$O%G!<%?!<E>Aw?t$rcdb$NAllocation Length$K:GDcD9$G$"$k#8/usr/home/csrg/sccs/sys/luna68k/stand/SCCS/s.sc.c$%H */
37157096Sakito /* $r8GDj$7$F!"#S#P#C$N=hM}%7!<%1%s%9$rJx$5$J$$$h$&$K$7$F$$$k!# */
37257096Sakito
373*63199Sbostic /* %F!<@(#)sc.c 8.1f%K373H$N>uBV$rD4$Y$k$?$a!"Addtional Sens Field$r%"%/%;%9$9$k */
374*63199Sbostic /* I,MW$,$"$k$N$G06/10/93P%$%98.1i%$%PB&$Glen$r7hDj$9$k$3$H$K$9$k */
37557096Sakito
37657096Sakito cdb.lun = unit;
37757096Sakito cdb.len = len;
37857096Sakito
37957096Sakito if (!(scrun(ctlr, slave, &cdb, 6, buf, len, &lock))) {
38057096Sakito #ifdef DEBUG
38157096Sakito printf("scsi_request_sense: Command Transfer Failed.\n");
38257096Sakito #endif
38357096Sakito return(-1);
38457096Sakito }
38557096Sakito
38657096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
38757096Sakito DELAY(10);
38857096Sakito
38957096Sakito status = scfinish(ctlr);
39057096Sakito
39157096Sakito if (lock == SC_IO_COMPLETE) {
39257096Sakito #ifdef DEBUG
39357096Sakito printf("scsi_request_sense: Status -- 0x%x\n", status);
39457096Sakito #endif
39557096Sakito return(status);
39657096Sakito } else {
39757096Sakito return(lock);
39857096Sakito }
39957096Sakito }
40057096Sakito
40157096Sakito int
scsi_immed_command(ctlr,slave,unit,cdb,buf,len)40257096Sakito scsi_immed_command(ctlr, slave, unit, cdb, buf, len)
40357096Sakito int ctlr, slave, unit;
40457096Sakito struct scsi_fmt_cdb *cdb;
40557096Sakito u_char *buf;
40657096Sakito unsigned len;
40757096Sakito {
40857096Sakito int lock, status;
40957096Sakito
41057096Sakito #ifdef DEBUG
41157096Sakito printf("scsi_immed_command( %d, %d, %d, cdb(%d), buf, %d): Start\n",
41257096Sakito ctlr, slave, unit, cdb->len, len);
41357096Sakito #endif
41457096Sakito
41557096Sakito cdb->cdb[1] |= unit << 5;
41657096Sakito
41757096Sakito if (!(scrun(ctlr, slave, &cdb->cdb[0], cdb->len, buf, len, &lock))) {
41857096Sakito #ifdef DEBUG
41957096Sakito printf("scsi_immed_command: Command Transfer Failed.\n");
42057096Sakito #endif
42157096Sakito return(-1);
42257096Sakito }
42357096Sakito
42457096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
42557096Sakito DELAY(10);
42657096Sakito
42757096Sakito status = scfinish(ctlr);
42857096Sakito
42957096Sakito if (lock == SC_IO_COMPLETE) {
43057096Sakito #ifdef DEBUG
43157096Sakito printf("scsi_immed_command: Status -- 0x%x\n", status);
43257096Sakito #endif
43357096Sakito return(status);
43457096Sakito } else {
43557096Sakito return(lock);
43657096Sakito }
43757096Sakito }
43857096Sakito
43957096Sakito int
scsi_format_unit(ctlr,slave,unit)44057096Sakito scsi_format_unit(ctlr, slave, unit)
44157096Sakito int ctlr, slave, unit;
44257096Sakito {
44357096Sakito static struct scsi_cdb6 cdb = { CMD_FORMAT_UNIT, 0, 0, 0, 0, 0 };
44457096Sakito int status, lock, count = 0;
44557096Sakito
44657096Sakito #ifdef DEBUG
44757096Sakito printf("scsi_format_unit( %d, %d, %d): Start\n", ctlr, slave, unit);
44857096Sakito #endif
44957096Sakito
45057096Sakito cdb.lun = unit;
45157096Sakito
45257096Sakito if (!(scrun(ctlr, slave, &cdb, 6, (u_char *) 0, 0, &lock))) {
45357096Sakito #ifdef DEBUG
45457096Sakito printf("scsi_format_unit: Command Transfer Failed.\n");
45557096Sakito #endif
45657096Sakito return(-1);
45757096Sakito }
45857096Sakito
45957096Sakito while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) {
46057096Sakito DELAY(1000000);
46157096Sakito #ifdef DEBUG
46257096Sakito if ((count % 60) == 0)
46357096Sakito printf("scsi_format_unit: %d\n");
46457096Sakito #endif
46557096Sakito }
46657096Sakito
46757096Sakito status = scfinish(ctlr);
46857096Sakito
46957096Sakito if (lock == SC_IO_COMPLETE) {
47057096Sakito #ifdef DEBUG
47157096Sakito printf("scsi_format_unit: Status -- 0x%x\n", status);
47257096Sakito #endif
47357096Sakito return(status);
47457096Sakito } else {
47557096Sakito return(lock);
47657096Sakito }
47757096Sakito }
47857096Sakito
47957096Sakito
48057096Sakito /*
48157096Sakito * ????
48257096Sakito */
48357096Sakito
48457096Sakito int
scstart()48557096Sakito scstart()
48657096Sakito {
48757096Sakito }
48857096Sakito
48957096Sakito int
scgo()49057096Sakito scgo()
49157096Sakito {
49257096Sakito }
49357096Sakito
49457096Sakito int
scdone()49557096Sakito scdone()
49657096Sakito {
49757096Sakito }
49857096Sakito
49957096Sakito
50057096Sakito /*
50157096Sakito * Interrupt Routine
50257096Sakito */
50357096Sakito
50457096Sakito int
scintr()50557096Sakito scintr()
50657096Sakito {
50757096Sakito register struct scsi_softc *hs;
50857096Sakito volatile register struct scsidevice *hd;
50957096Sakito register u_char ints, temp;
51057096Sakito register int i;
51157096Sakito u_char *buf;
51257096Sakito int len;
51357096Sakito
51457096Sakito for (i = 0; i < NSC; i++) {
51557096Sakito hs = &scsi_softc[i];
51657096Sakito hd = (struct scsidevice *) hs->sc_hc->hp_addr;
51757096Sakito if ((ints = hd->scsi_ints) != 0)
51857096Sakito goto get_intr;
51957096Sakito }
52057096Sakito
52157096Sakito /* Unknown Interrupt occured */
52257096Sakito return;
52357096Sakito
52457096Sakito
52557096Sakito /*
52657096Sakito * Interrupt
52757096Sakito */
52857096Sakito
52957096Sakito get_intr:
53057096Sakito #ifdef DEBUG
53157096Sakito printf("scintr: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x 0x%x\n",
53257096Sakito ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns,
53357096Sakito hs->sc_phase);
53457096Sakito #endif
53557096Sakito if (ints & INTS_RESEL) {
53657096Sakito if (hs->sc_phase == BUS_FREE_PHASE) {
53757096Sakito temp = hd->scsi_temp & ~(1 << SCSI_ID);
53857096Sakito for (i = 0; temp != 1; i++) {
53957096Sakito temp >>= 1;
54057096Sakito }
54157096Sakito hs->sc_target = i;
54257096Sakito *(hs->sc_lock) = SC_IN_PROGRESS;
54357096Sakito } else
54457096Sakito goto abort;
54557096Sakito } else if (ints & INTS_DISCON) {
54657096Sakito if ((hs->sc_msg[0] == MSG_CMD_COMPLETE) || (hs->sc_msg[0] == MSG_DISCONNECT)) {
54757096Sakito hs->sc_phase = BUS_FREE_PHASE;
54857096Sakito hs->sc_target = SCSI_ID;
54957096Sakito if (hs->sc_msg[0] == MSG_CMD_COMPLETE)
55057096Sakito /* SCSI IO complete */
55157096Sakito *(hs->sc_lock) = SC_IO_COMPLETE;
55257096Sakito else
55357096Sakito /* Cisconnected from Target */
55457096Sakito *(hs->sc_lock) = SC_DISCONNECTED;
55557096Sakito hd->scsi_ints = ints;
55657096Sakito return;
55757096Sakito } else
55857096Sakito goto abort;
55957096Sakito } else if (ints & INTS_CMD_DONE) {
56057096Sakito if (hs->sc_phase == BUS_FREE_PHASE)
56157096Sakito goto abort;
56257096Sakito else if (hs->sc_phase == MESG_IN_PHASE) {
56357096Sakito hd->scsi_scmd = SCMD_RST_ACK;
56457096Sakito hd->scsi_ints = ints;
56557096Sakito hs->sc_phase = hd->scsi_psns & PHASE;
56657096Sakito return;
56757096Sakito }
56857096Sakito if (hs->sc_flags & SC_SEL_TIMEOUT)
56957096Sakito hs->sc_flags &= ~SC_SEL_TIMEOUT;
57057096Sakito } else if (ints & INTS_SRV_REQ) {
57157096Sakito if (hs->sc_phase != MESG_IN_PHASE)
57257096Sakito goto abort;
57357096Sakito } else if (ints & INTS_TIMEOUT) {
57457096Sakito if (hs->sc_phase == ARB_SEL_PHASE) {
57557096Sakito if (hs->sc_flags & SC_SEL_TIMEOUT) {
57657096Sakito hs->sc_flags &= ~SC_SEL_TIMEOUT;
57757096Sakito hs->sc_phase = BUS_FREE_PHASE;
57857096Sakito hs->sc_target = SCSI_ID;
57957096Sakito /* Such SCSI Device is not conected. */
58057096Sakito *(hs->sc_lock) = SC_DEV_NOT_FOUND;
58157096Sakito hd->scsi_ints = ints;
58257096Sakito return;
58357096Sakito } else {
58457096Sakito /* wait more 250 usec */
58557096Sakito hs->sc_flags |= SC_SEL_TIMEOUT;
58657096Sakito hd->scsi_temp = 0;
58757096Sakito hd->scsi_tch = 0;
58857096Sakito hd->scsi_tcm = 0x06;
58957096Sakito hd->scsi_tcl = 0x40;
59057096Sakito hd->scsi_ints = ints;
59157096Sakito return;
59257096Sakito }
59357096Sakito } else
59457096Sakito goto abort;
59557096Sakito } else
59657096Sakito goto abort;
59757096Sakito
59857096Sakito hd->scsi_ints = ints;
59957096Sakito
60057096Sakito /*
60157096Sakito * Next SCSI Transfer
60257096Sakito */
60357096Sakito
60457096Sakito while ((hd->scsi_psns & PSNS_REQ) == 0) {
60557096Sakito DELAY(1);
60657096Sakito }
60757096Sakito
60857096Sakito hs->sc_phase = hd->scsi_psns & PHASE;
60957096Sakito
61057096Sakito if ((hs->sc_phase == DATA_OUT_PHASE) || (hs->sc_phase == DATA_IN_PHASE)) {
61157096Sakito len = hs->sc_len;
61257096Sakito buf = hs->sc_buf;
61357096Sakito } else if (hs->sc_phase == CMD_PHASE) {
61457096Sakito len = hs->sc_cdblen;
61557096Sakito buf = hs->sc_cdb;
61657096Sakito } else if (hs->sc_phase == STATUS_PHASE) {
61757096Sakito len = 1;
61857096Sakito buf = &hs->sc_stat;
61957096Sakito } else {
62057096Sakito len = 1;
62157096Sakito buf = hs->sc_msg;
62257096Sakito }
62357096Sakito
62457096Sakito ixfer_start(hd, len, hs->sc_phase, 0);
62557096Sakito if (hs->sc_phase & PHASE_IO)
62657096Sakito ixfer_in(hd, len, buf);
62757096Sakito else
62857096Sakito ixfer_out(hd, len, buf);
62957096Sakito
63057096Sakito return;
63157096Sakito
63257096Sakito /*
63357096Sakito * SCSI Abort
63457096Sakito */
63557096Sakito abort:
63657096Sakito /* SCSI IO failed */
63757096Sakito scabort(hs, hd);
63857096Sakito hd->scsi_ints = ints;
63957096Sakito *(hs->sc_lock) = SC_IO_FAILED;
64057096Sakito return;
64157096Sakito }
642