153901Smckusick /*
2*63307Sbostic * Copyright (c) 1992, 1993
3*63307Sbostic * The Regents of the University of California. All rights reserved.
453901Smckusick *
553901Smckusick * This code is derived from software contributed to Berkeley by
653901Smckusick * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753901Smckusick *
853901Smckusick * %sccs.include.redist.c%
953901Smckusick *
1053901Smckusick * from: $Hdr: scsi.c,v 4.300 91/06/27 20:42:51 root Rel41 $ SONY
1153901Smckusick *
12*63307Sbostic * @(#)scsi.c 8.1 (Berkeley) 06/11/93
1353901Smckusick */
1453901Smckusick
1553901Smckusick /*
1653901Smckusick * scsi.c ver 1.1
1753901Smckusick */
1853901Smckusick
1957182Sutashiro #include <machine/param.h>
2053901Smckusick
2157182Sutashiro #include <sys/param.h>
2257182Sutashiro #include <sys/buf.h>
2357182Sutashiro #include <sys/proc.h>
2457182Sutashiro #include <sys/user.h>
2553901Smckusick
2657182Sutashiro # include <machine/cpu.h>
2753901Smckusick
2857182Sutashiro #include <news3400/hbdev/hbvar.h>
2957182Sutashiro #include <news3400/hbdev/scsic.h>
3057182Sutashiro #include <news3400/hbdev/screg_1185.h>
3153901Smckusick
3257182Sutashiro #include <news3400/iodev/scsireg.h>
3357182Sutashiro #include <news3400/iodev/ioptohb.h>
3453901Smckusick
3553901Smckusick #define DEBUG_LOSSBSY_HUNG
3653901Smckusick
3753901Smckusick #ifdef DEBUG_LOSSBSY_HUNG
3853901Smckusick # define PROBE_MAXRETRY 100
3953901Smckusick #endif
4053901Smckusick
4153901Smckusick #ifndef NO_SCSI_DISCONNECT
4253901Smckusick int Scsi_Disconnect = IDT_DISCON;
4353901Smckusick #else
4453901Smckusick int Scsi_Disconnect = 0;
4553901Smckusick #endif
4653901Smckusick
4753901Smckusick # define MAXCTLR 8
4853901Smckusick struct sc_data sc_data[MAXCTLR];
4953901Smckusick struct scintsw scintsw[MAXCTLR];
5053901Smckusick
5153901Smckusick #ifdef RSENSE_MSG_DISP
5253901Smckusick int rsense_msg_disp = 1; /* RSENSE-message display flag */
5353901Smckusick #else
5453901Smckusick int rsense_msg_disp = 0; /* RSENSE-message display flag */
5553901Smckusick #endif
5653901Smckusick
5753901Smckusick int mo_disp_format = 0; /* MO format mode display flag */
5853901Smckusick
5953901Smckusick struct msg_list {
6053901Smckusick int ml_code; /* message code */
6153901Smckusick int ml_msglvl; /* message level */
6253901Smckusick char *ml_msgstr; /* message string */
6353901Smckusick };
6453901Smckusick
6553901Smckusick #ifdef NO_SHRINK_RSENSE_MSG
6658618Sutashiro # define MSG(m) m
6758618Sutashiro #else
6858618Sutashiro # define MSG(m) NULL
6958618Sutashiro #endif
7058618Sutashiro
7153901Smckusick struct msg_list skeylist[] = {
7258618Sutashiro { 0x00, 1, MSG("No Sense") },
7358618Sutashiro { 0x01, 0, MSG("Recoverable Error") },
7458618Sutashiro { 0x02, 0, MSG("Not Ready") },
7558618Sutashiro { 0x03, 0, MSG("Medium Error") },
7658618Sutashiro { 0x04, 0, MSG("Hardware Error") },
7758618Sutashiro { 0x05, 0, MSG("Illegal Request") },
7858618Sutashiro { 0x06, 1, MSG("Unit Attention") },
7958618Sutashiro { 0x07, 1, MSG("Data protect") },
8058618Sutashiro { 0x08, 0, MSG("Blank Check") },
8158618Sutashiro { 0x09, 0, MSG("Vendor Unique") },
8258618Sutashiro { 0x0a, 0, MSG("Copy/Compare Aborted") },
8358618Sutashiro { 0x0b, 0, MSG("Aborted Command") },
8458618Sutashiro { 0x0c, 0, MSG("Equal") },
8558618Sutashiro { 0x0d, 0, MSG("Volume Overflow") },
8658618Sutashiro { 0x0e, 0, MSG("Miscompare") },
8753901Smckusick { -1, 0, (caddr_t)0 }
8853901Smckusick };
8953901Smckusick
9053901Smckusick struct msg_list ecodelist[] = {
9158618Sutashiro { 0x00, 9, MSG("No Additional Sense Information") },
9258618Sutashiro /*HD*/ { 0x01, 1, MSG("No Index/Address Mark Found signal") },
9358618Sutashiro { 0x02, 0, MSG("No Seek Complete") },
9458618Sutashiro { 0x03, 0, MSG("Write Fault") },
9558618Sutashiro { 0x04, 9, MSG("Drive Not Ready") },
9658618Sutashiro { 0x05, 0, MSG("Drive Not Selected") },
9758618Sutashiro /*HD*/ { 0x06, 0, MSG("No Track Zero") },
9858618Sutashiro { 0x07, 0, MSG("Multiple Drives Selected") },
9958618Sutashiro { 0x08, 0, MSG("Logical Unit Communication Failure") },
10058618Sutashiro { 0x09, 2, MSG("Track Following Error") },
10158618Sutashiro /*MO*/ { 0x0a, 1, MSG("No Disk") },
10258618Sutashiro /*MO*/ { 0x0b, 1, MSG("Load/Unload Failure") },
10358618Sutashiro /*MO*/ { 0x0c, 1, MSG("Spindle Failure") },
10458618Sutashiro /*MO*/ { 0x0d, 1, MSG("Focus Failure") },
10558618Sutashiro /*MO*/ { 0x0e, 1, MSG("Tracking Failure") },
10658618Sutashiro /*MO*/ { 0x0f, 0, MSG("Drive Initialization Failure") },
10758618Sutashiro { 0x10, 1, MSG("ID CRC or ECC error") },
10858618Sutashiro { 0x11, 0, MSG("Unrecoverd Read error") },
10958618Sutashiro /*HD*/ { 0x12, 0, MSG("No Address Mark (byte sync byte) found in ID field") },
11058618Sutashiro /*HD*/ { 0x13, 0, MSG("No Address Mark (byte sync byte) found in Data field") },
11158618Sutashiro /*HD*/ { 0x14, 0, MSG("No record found") },
11258618Sutashiro { 0x15, 1, MSG("Seek Positioning Error") },
11353901Smckusick
11458618Sutashiro /*HD*/ { 0x17, 0, MSG("Recovered Read data with Read retries") },
11558618Sutashiro { 0x18, 0, MSG("Recovered Read data with ECC procedure") },
11658618Sutashiro /*HD*/ { 0x19, 0, MSG("Defect List error") },
11758618Sutashiro /*HD*/ { 0x1a, 0, MSG("Parameter overrun") },
11858618Sutashiro /*HD*/ { 0x1b, 0, MSG("Synchronous transfer error") },
11958618Sutashiro /*HD*/ { 0x1c, 0, MSG("Primary Defect List not found") },
12058618Sutashiro /*HD*/ { 0x1d, 0, MSG("Compare error") },
12153901Smckusick
12258618Sutashiro { 0x20, 0, MSG("Invalid Command Operation Code") },
12358618Sutashiro { 0x21, 0, MSG("Illegal Logical Block Address") },
12458618Sutashiro /*HD*/ { 0x22, 0, MSG("Illegal function for device type") },
12558618Sutashiro /*MO*/ { 0x23, 0, MSG("Illegal function for Medium Type") },
12658618Sutashiro { 0x24, 0, MSG("Illegal Field in CDB") },
12758618Sutashiro { 0x25, 0, MSG("Invalid LUN") },
12858618Sutashiro { 0x26, 0, MSG("Invalid field in Parameter List") },
12958618Sutashiro { 0x27, 0, MSG("Write Protected") },
13058618Sutashiro { 0x28, 1, MSG("Medium Changed") },
13158618Sutashiro { 0x29, 1, MSG("Power On or Reset or Bus Device Reset Occured") },
13258618Sutashiro { 0x2a, 1, MSG("Mode Select Parameters Changed") },
13358618Sutashiro /*HD*/ { 0x2b, 0, MSG("Host cannot Disconnect") },
13453901Smckusick
13558618Sutashiro { 0x31, 0, MSG("Medium Format Corrupted") },
13658618Sutashiro { 0x32, 0, MSG("No Defect Spare Location Available") },
13753901Smckusick
13858618Sutashiro /*MO*/ { 0x38, 1, MSG("Recovered with Automatic Reallocation") },
13958618Sutashiro /*MO*/ { 0x39, 0, MSG("Automatic Reallocation Failure") },
14058618Sutashiro /*MO*/ { 0x3a, 1, MSG("Defect List Update Failure") },
14153901Smckusick
14258618Sutashiro /*MO*/ { 0x3d, 0, MSG("Defect List Not Available") },
14353901Smckusick
14458618Sutashiro /*HD*/ { 0x40, 0, MSG("RAM failure") },
14558618Sutashiro /*HD*/ { 0x41, 0, MSG("Data Path diagnostic failure") },
14658618Sutashiro { 0x42, 0, MSG("Power On Diagnostic Failure") },
14758618Sutashiro { 0x43, 0, MSG("Message Reject Error") },
14858618Sutashiro { 0x44, 9, MSG("Internal Controller Error") },
14958618Sutashiro /*HD*/ { 0x45, 0, MSG("Selection/Reselection failure") },
15053901Smckusick
15158618Sutashiro { 0x47, 0, MSG("SCSI Interface Parity Error") },
15258618Sutashiro { 0x48, 0, MSG("Initiator Detected Error") },
15358618Sutashiro { 0x49, 0, MSG("Inappropriate/Illegal Message") },
15453901Smckusick
15558618Sutashiro { 0x64, 1, MSG("Illegal mode for this track") },
15653901Smckusick
15753901Smckusick { -1, 0, (caddr_t)0 }
15853901Smckusick };
15958618Sutashiro #undef MSG
16053901Smckusick
16153901Smckusick /*
16253901Smckusick * Init a scsi bus.
16353901Smckusick */
scop_init(scn)16453901Smckusick scop_init(scn)
16553901Smckusick int scn;
16653901Smckusick {
16753901Smckusick static struct scsi sc;
16853901Smckusick int chan;
16953901Smckusick
17053901Smckusick for (chan = 0; chan < MAXCTLR; chan++) {
17153901Smckusick bzero((caddr_t)&sc, sizeof(struct scsi));
17253901Smckusick sc.sc_cdb.un_reserved[0] = SCOP_RESET;
17353901Smckusick sc.sc_cdb.un_reserved[1] = SCOP_RESET;
17453901Smckusick
17553901Smckusick if (!sc_busy(chan)) {
17653901Smckusick sc_go(chan, (struct scsi *)&sc, SCSI_INTDIS);
17753901Smckusick
17853901Smckusick chan = (chan / 8 + 1) * 8;
17953901Smckusick }
18053901Smckusick }
18153901Smckusick }
18253901Smckusick
18353901Smckusick /**************************************
18453901Smckusick The multiple scsi bus is NOT suported by following routines.
18553901Smckusick How about use inter like dev_t ( uper is scsi#, lower is inter )
18653901Smckusick or hb_ctlr.
18753901Smckusick probe() ga futatuarukara unit# ----- udauda.
18853901Smckusick **************************************/
18953901Smckusick
19053901Smckusick /*
19153901Smckusick * scprobe. probe routine for mass storage controller.
19253901Smckusick */
19353901Smckusick scprobe(im, ctlrintr, sc)
19453901Smckusick struct iop/**/_ctlr *im;
19553901Smckusick int (*ctlrintr)();
19653901Smckusick register struct scsi *sc;
19753901Smckusick {
19853901Smckusick register struct scintsw *sci;
19953901Smckusick int s;
20053901Smckusick #ifdef DEBUG_LOSSBSY_HUNG
20153901Smckusick int retry = 0;
20253901Smckusick #endif DEBUG_LOSSBSY_HUNG
20353901Smckusick
20453901Smckusick sci = &scintsw[im->im_intr];
20553901Smckusick if (sci->sci_inthandler)
20653901Smckusick return (0);
20753901Smckusick
20853901Smckusick #ifdef DEBUG_LOSSBSY_HUNG
20953901Smckusick scprobe_loop:
21053901Smckusick /* s = splsc(); */
21153901Smckusick scop_inquiry(im->im_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0);
21253901Smckusick /* splx(s); */
21353901Smckusick
21453901Smckusick if (sc->sc_istatus != INST_EP) {
21553901Smckusick if ((sc->sc_tstatus == TGST_BUSY) && (retry++ < PROBE_MAXRETRY)) {
21653901Smckusick goto scprobe_loop;
21753901Smckusick }
21853901Smckusick return (0);
21953901Smckusick }
22053901Smckusick
22153901Smckusick #else /* DEBUG_LOSSBSY_HUNG */
22253901Smckusick
22353901Smckusick /* s = splsc(); */
22453901Smckusick scop_inquiry(im->im_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0);
22553901Smckusick /* splx(s); */
22653901Smckusick
22753901Smckusick if (sc->sc_istatus != INST_EP)
22853901Smckusick return (0);
22953901Smckusick
23053901Smckusick #endif /* DEBUG_LOSSBSY_HUNG */
23153901Smckusick
23253901Smckusick sci->sci_inthandler = ctlrintr;
23353901Smckusick sci->sci_ctlr = im->im_ctlr;
23453901Smckusick return (1);
23553901Smckusick }
23653901Smckusick
23753901Smckusick /*
23853901Smckusick * ssprobe. probe routine for non-mass storage peripherals.
23953901Smckusick */
24053901Smckusick ssprobe(ii, ctlrintr, sc)
24153901Smckusick struct iop/**/_device *ii;
24253901Smckusick int (*ctlrintr)();
24353901Smckusick register struct scsi *sc;
24453901Smckusick {
24553901Smckusick register struct scintsw *sci;
24653901Smckusick int s;
24753901Smckusick
24853901Smckusick sci = &scintsw[ii->ii_intr];
24953901Smckusick if (sci->sci_inthandler)
25053901Smckusick return (0);
25153901Smckusick
25253901Smckusick /* s = splsc(); */
25353901Smckusick scop_inquiry(ii->ii_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0);
25453901Smckusick /* splx(s); */
25553901Smckusick
25653901Smckusick if (sc->sc_istatus != INST_EP)
25753901Smckusick return (0);
25853901Smckusick
25953901Smckusick sci->sci_inthandler = ctlrintr;
26053901Smckusick sci->sci_ctlr = ii->ii_unit;
26153901Smckusick return (1);
26253901Smckusick }
26353901Smckusick
26453901Smckusick /*
26553901Smckusick * SCOP_TST request
26653901Smckusick */
scop_tst(intr,sc,slave,ie)26753901Smckusick scop_tst(intr, sc, slave, ie)
26853901Smckusick register int intr;
26953901Smckusick register struct scsi *sc;
27053901Smckusick register int slave;
27153901Smckusick register int ie;
27253901Smckusick {
27353901Smckusick scinit(sc, slave, DEV_BSIZE);
27453901Smckusick
27553901Smckusick /* sc_cdb */
27653901Smckusick sc->sc_opcode = SCOP_TST;
27753901Smckusick
27853901Smckusick sc_go(intr, (struct scsi *)sc, ie);
27953901Smckusick }
28053901Smckusick
28153901Smckusick /*
28253901Smckusick * SCOP_REZERO request
28353901Smckusick */
scop_rezero(intr,sc,slave,ie)28453901Smckusick scop_rezero(intr, sc, slave, ie)
28553901Smckusick register int intr;
28653901Smckusick register struct scsi *sc;
28753901Smckusick register int slave;
28853901Smckusick register int ie;
28953901Smckusick {
29053901Smckusick scinit(sc, slave, DEV_BSIZE);
29153901Smckusick
29253901Smckusick /* sc_cdb */
29353901Smckusick sc->sc_opcode = SCOP_REZERO;
29453901Smckusick
29553901Smckusick sc_go(intr, (struct scsi *)sc, ie);
29653901Smckusick }
29753901Smckusick
29853901Smckusick /*
29953901Smckusick * SCOP_REWIND request
30053901Smckusick */
scop_rewind(intr,sc,slave,ie,imme)30153901Smckusick scop_rewind(intr, sc, slave, ie, imme)
30253901Smckusick register int intr;
30353901Smckusick register struct scsi *sc;
30453901Smckusick register int slave;
30553901Smckusick register int ie, imme;
30653901Smckusick {
30753901Smckusick scinit(sc, slave, DEV_BSIZE);
30853901Smckusick
30953901Smckusick /* sc_cdb */
31053901Smckusick sc->sc_opcode = SCOP_REZERO;
31153901Smckusick sc->sc_tucode = imme;
31253901Smckusick
31353901Smckusick sc_go(intr, (struct scsi *)sc, ie);
31453901Smckusick }
31553901Smckusick
31653901Smckusick /*
31753901Smckusick * SCOP_RSENSE request
31853901Smckusick */
scop_rsense(intr,sc,slave,ie,count,param)31953901Smckusick scop_rsense(intr, sc, slave, ie, count, param)
32053901Smckusick register int intr;
32153901Smckusick register struct scsi *sc;
32253901Smckusick register int slave;
32353901Smckusick register int ie;
32453901Smckusick register int count;
32553901Smckusick register caddr_t param;
32653901Smckusick {
32753901Smckusick scinit(sc, slave, DEV_BSIZE);
32853901Smckusick
32953901Smckusick sc->sc_cpoint = (u_char *)param;
33053901Smckusick sc->sc_ctrnscnt = count;
33153901Smckusick
33253901Smckusick /* sc_cdb */
33353901Smckusick sc->sc_opcode = SCOP_RSENSE;
33453901Smckusick sc->sc_count = count;
33553901Smckusick
33653901Smckusick sc_go(intr, (struct scsi *)sc, ie);
33753901Smckusick }
33853901Smckusick
33953901Smckusick /*
34053901Smckusick * SCOP_RASBLK request
34153901Smckusick */
scop_rasblk(intr,sc,slave,ie,lad)34253901Smckusick scop_rasblk(intr, sc, slave, ie, lad)
34353901Smckusick register int intr;
34453901Smckusick register struct scsi *sc;
34553901Smckusick register int slave;
34653901Smckusick register int ie;
34753901Smckusick register int lad;
34853901Smckusick {
34953901Smckusick struct sc_rab *sca = (struct sc_rab *)sc->sc_param;
35053901Smckusick
35153901Smckusick scinit(sc, slave, DEV_BSIZE);
35253901Smckusick
35353901Smckusick sca->sca_dllen = 4;
35453901Smckusick sca->sca_dlad[0] = lad;
35553901Smckusick sc->sc_cpoint = (u_char *)sca;
35653901Smckusick
35753901Smckusick sc->sc_ctrnscnt = 8;
35853901Smckusick
35953901Smckusick /* sc_cdb */
36053901Smckusick sc->sc_opcode = SCOP_RASBLK;
36153901Smckusick
36253901Smckusick sc_go(intr, (struct scsi *)sc, ie);
36353901Smckusick }
36453901Smckusick
36553901Smckusick /*
36653901Smckusick * SCOP_MERASE request
36753901Smckusick */
scop_merase(intr,sc,slave,ie,count)36853901Smckusick scop_merase(intr, sc, slave, ie, count)
36953901Smckusick register int intr;
37053901Smckusick register struct scsi *sc;
37153901Smckusick register int slave;
37253901Smckusick register int ie;
37353901Smckusick register int count;
37453901Smckusick {
37553901Smckusick scinit(sc, slave, DEV_BSIZE);
37653901Smckusick
37753901Smckusick /* sc_cdb */
37853901Smckusick sc->sc_opcode = SCOP_MERASE;
37953901Smckusick sc->sc_mtcount3 = count;
38053901Smckusick
38153901Smckusick sc_go(intr, (struct scsi *)sc, ie);
38253901Smckusick }
38353901Smckusick
38453901Smckusick /*
38553901Smckusick * SCOP_WFMARK request
38653901Smckusick */
scop_wfmark(intr,sc,slave,ie,count)38753901Smckusick scop_wfmark(intr, sc, slave, ie, count)
38853901Smckusick register int intr;
38953901Smckusick register struct scsi *sc;
39053901Smckusick register int slave;
39153901Smckusick register int ie;
39253901Smckusick register int count;
39353901Smckusick {
39453901Smckusick scinit(sc, slave, DEV_BSIZE);
39553901Smckusick
39653901Smckusick /* sc_cdb */
39753901Smckusick sc->sc_opcode = SCOP_WFMARK;
39853901Smckusick count &= 0xffffff;
39953901Smckusick sc->sc_tucount3 = count & 0xff;
40053901Smckusick count >>= 8;
40153901Smckusick sc->sc_tucount2 = count & 0xff;
40253901Smckusick count >>= 8;
40353901Smckusick sc->sc_tucount1 = count & 0xff;
40453901Smckusick
40553901Smckusick sc_go(intr, (struct scsi *)sc, ie);
40653901Smckusick }
40753901Smckusick
40853901Smckusick /*
40953901Smckusick * SCOP_SPACE request
41053901Smckusick */
scop_space(intr,sc,slave,ie,count,code)41153901Smckusick scop_space(intr, sc, slave, ie, count, code)
41253901Smckusick register int intr;
41353901Smckusick register struct scsi *sc;
41453901Smckusick register int slave;
41553901Smckusick register int ie;
41653901Smckusick register int count;
41753901Smckusick register int code;
41853901Smckusick {
41953901Smckusick scinit(sc, slave, DEV_BSIZE);
42053901Smckusick
42153901Smckusick /* sc_cdb */
42253901Smckusick sc->sc_opcode = SCOP_SPACE;
42353901Smckusick sc->sc_tucode = code;
42453901Smckusick count &= 0xffffff;
42553901Smckusick sc->sc_tucount3 = count & 0xff;
42653901Smckusick count >>= 8;
42753901Smckusick sc->sc_tucount2 = count & 0xff;
42853901Smckusick count >>= 8;
42953901Smckusick sc->sc_tucount1 = count & 0xff;
43053901Smckusick
43153901Smckusick sc_go(intr, (struct scsi *)sc, ie);
43253901Smckusick }
43353901Smckusick
43453901Smckusick /*
43553901Smckusick * SCOP_INQUIRY request
43653901Smckusick */
scop_inquiry(intr,sc,slave,ie,count,param)43753901Smckusick scop_inquiry(intr, sc, slave, ie, count, param)
43853901Smckusick register int intr;
43953901Smckusick register struct scsi *sc;
44053901Smckusick register int slave;
44153901Smckusick register int ie;
44253901Smckusick register int count;
44353901Smckusick register caddr_t param;
44453901Smckusick {
44553901Smckusick scinit(sc, slave, DEV_BSIZE);
44653901Smckusick
44753901Smckusick sc->sc_cpoint = (u_char *)param;
44853901Smckusick sc->sc_ctrnscnt = count;
44953901Smckusick
45053901Smckusick /* sc_cdb */
45153901Smckusick sc->sc_opcode = SCOP_INQUIRY;
45253901Smckusick sc->sc_count = count;
45353901Smckusick
45453901Smckusick sc_go(intr, (struct scsi *)sc, ie);
45553901Smckusick }
45653901Smckusick
45753901Smckusick /*
45853901Smckusick * SCOP_STST request
45953901Smckusick */
scop_stst(intr,sc,slave,ie,sw)46053901Smckusick scop_stst(intr, sc, slave, ie, sw)
46153901Smckusick register int intr;
46253901Smckusick register struct scsi *sc;
46353901Smckusick register int slave;
46453901Smckusick register int ie;
46553901Smckusick register int sw;
46653901Smckusick {
46753901Smckusick scinit(sc, slave, DEV_BSIZE);
46853901Smckusick
46953901Smckusick /* sc_cdb */
47053901Smckusick sc->sc_opcode = SCOP_STST;
47153901Smckusick sc->sc_switch = sw;
47253901Smckusick
47353901Smckusick sc_go(intr, (struct scsi *)sc, ie);
47453901Smckusick }
47553901Smckusick
47653901Smckusick /*
47753901Smckusick * SCOP_RCAP request
47853901Smckusick */
scop_rcap(intr,sc,slave,ie,count,param)47953901Smckusick scop_rcap(intr, sc, slave, ie, count, param)
48053901Smckusick register int intr;
48153901Smckusick register struct scsi *sc;
48253901Smckusick register int slave;
48353901Smckusick register int ie;
48453901Smckusick register int count;
48553901Smckusick register caddr_t param;
48653901Smckusick {
48753901Smckusick scinit(sc, slave, DEV_BSIZE);
48853901Smckusick
48953901Smckusick sc->sc_cpoint = (u_char *)param;
49053901Smckusick sc->sc_ctrnscnt = count;
49153901Smckusick
49253901Smckusick /* sc_cdb */
49353901Smckusick sc->sc_opcode = SCOP_RCAP;
49453901Smckusick sc->sc_pmi = OFF;
49553901Smckusick
49653901Smckusick sc_go(intr, (struct scsi *)sc, ie);
49753901Smckusick }
49853901Smckusick
49953901Smckusick /*
50053901Smckusick * SCOP_BSSRCH request
50153901Smckusick */
scop_bssrch(intr,sc,slave,ie,count,param)50253901Smckusick scop_bssrch(intr, sc, slave, ie, count, param)
50353901Smckusick register int intr;
50453901Smckusick register struct scsi *sc;
50553901Smckusick register int slave;
50653901Smckusick register int ie;
50753901Smckusick register int count;
50853901Smckusick register caddr_t param;
50953901Smckusick {
51053901Smckusick scinit(sc, slave, DEV_BSIZE);
51153901Smckusick
51253901Smckusick sc->sc_cpoint = (u_char *)param;
51353901Smckusick sc->sc_ctrnscnt = count;
51453901Smckusick
51553901Smckusick /* sc_cdb */
51653901Smckusick sc->sc_opcode = SCOP_BSSRCH;
51753901Smckusick sc->sc_ladhi = *(short *)param;
51853901Smckusick sc->sc_ladlo = *(short *)(param + 2);
51953901Smckusick
52053901Smckusick sc_go(intr, (struct scsi *)sc, ie);
52153901Smckusick }
52253901Smckusick
52353901Smckusick /*
52453901Smckusick * SCOP_WSSRCH request
52553901Smckusick */
scop_wssrch(intr,sc,slave,ie,count,param)52653901Smckusick scop_wssrch(intr, sc, slave, ie, count, param)
52753901Smckusick register int intr;
52853901Smckusick register struct scsi *sc;
52953901Smckusick register int slave;
53053901Smckusick register int ie;
53153901Smckusick register int count;
53253901Smckusick register caddr_t param;
53353901Smckusick {
53453901Smckusick scinit(sc, slave, DEV_BSIZE);
53553901Smckusick
53653901Smckusick sc->sc_cpoint = (u_char *)param;
53753901Smckusick sc->sc_ctrnscnt = count;
53853901Smckusick
53953901Smckusick /* sc_cdb */
54053901Smckusick sc->sc_opcode = SCOP_WSSRCH;
54153901Smckusick sc->sc_ladhi = *(short *)param;
54253901Smckusick sc->sc_ladlo = *(short *)(param + 2);
54353901Smckusick
54453901Smckusick sc_go(intr, (struct scsi *)sc, ie);
54553901Smckusick }
54653901Smckusick
54753901Smckusick /*
54853901Smckusick *
54953901Smckusick * SCOP_EESENSE request
55053901Smckusick * Enable/Disable Eject Request Sense
55153901Smckusick * Write Once only supported.
55253901Smckusick *
55353901Smckusick */
scop_eesense(intr,sc,slave,ie,sw)55453901Smckusick scop_eesense(intr, sc, slave, ie, sw)
55553901Smckusick register int intr;
55653901Smckusick register struct scsi *sc;
55753901Smckusick register int slave;
55853901Smckusick register int ie;
55953901Smckusick register int sw;
56053901Smckusick {
56153901Smckusick scinit(sc, slave, DEV_BSIZE);
56253901Smckusick
56353901Smckusick /* sc_cdb */
56453901Smckusick sc->sc_opcode = SCOP_EESENSE;
56553901Smckusick sc->sc_switch = sw;
56653901Smckusick
56753901Smckusick sc_go(intr, (struct scsi *)sc, ie);
56853901Smckusick }
56953901Smckusick
57053901Smckusick /*
57153901Smckusick * SCOP_EJECT
57253901Smckusick */
scop_eject(intr,sc,slave,ie)57353901Smckusick scop_eject(intr, sc, slave, ie)
57453901Smckusick register int intr;
57553901Smckusick register struct scsi *sc;
57653901Smckusick register int slave;
57753901Smckusick register int ie;
57853901Smckusick {
57953901Smckusick scinit(sc, slave, DEV_BSIZE);
58053901Smckusick
58153901Smckusick /* sc_cdb */
58253901Smckusick sc->sc_opcode = SCOP_EJECT;
58353901Smckusick
58453901Smckusick sc_go(intr, (struct scsi *)sc, ie);
58553901Smckusick }
58653901Smckusick
58753901Smckusick /*
58853901Smckusick * SCOP_RBLIM request
58953901Smckusick */
scop_rblim(intr,sc,slave,ie,count,param)59053901Smckusick scop_rblim(intr, sc, slave, ie, count, param)
59153901Smckusick register int intr;
59253901Smckusick register struct scsi *sc;
59353901Smckusick register int slave;
59453901Smckusick register int ie;
59553901Smckusick register int count;
59653901Smckusick register caddr_t param;
59753901Smckusick {
59853901Smckusick scinit(sc, slave, DEV_BSIZE);
59953901Smckusick
60053901Smckusick sc->sc_cpoint = (u_char *)param;
60153901Smckusick sc->sc_ctrnscnt = count & 0xff;
60253901Smckusick
60353901Smckusick /* sc_cdb */
60453901Smckusick sc->sc_opcode = SCOP_RBLIM;
60553901Smckusick
60653901Smckusick sc_go(intr, (struct scsi *)sc, ie);
60753901Smckusick }
60853901Smckusick
60953901Smckusick /*
61053901Smckusick * SCOP_MSENSE request
61153901Smckusick */
scop_msense(intr,sc,slave,ie,count,param)61253901Smckusick scop_msense(intr, sc, slave, ie, count, param)
61353901Smckusick register int intr;
61453901Smckusick register struct scsi *sc;
61553901Smckusick register int slave;
61653901Smckusick register int ie;
61753901Smckusick register int count;
61853901Smckusick register caddr_t param;
61953901Smckusick {
62053901Smckusick scinit(sc, slave, DEV_BSIZE);
62153901Smckusick
62253901Smckusick sc->sc_cpoint = (u_char *)param;
62353901Smckusick sc->sc_ctrnscnt = count & 0xff;
62453901Smckusick
62553901Smckusick /* sc_cdb */
62653901Smckusick sc->sc_opcode = SCOP_MSENSE;
62753901Smckusick sc->sc_lad = count >> 8;
62853901Smckusick sc->sc_count = count & 0xff;
62953901Smckusick
63053901Smckusick sc_go(intr, (struct scsi *)sc, ie);
63153901Smckusick }
63253901Smckusick
63353901Smckusick /*
63453901Smckusick * SCOP_MSELECT request
63553901Smckusick */
scop_mselect(intr,sc,slave,ie,count,param)63653901Smckusick scop_mselect(intr, sc, slave, ie, count, param)
63753901Smckusick register int intr;
63853901Smckusick register struct scsi *sc;
63953901Smckusick register int slave;
64053901Smckusick register int ie;
64153901Smckusick register int count;
64253901Smckusick register caddr_t param;
64353901Smckusick {
64453901Smckusick u_char psave[20];
64553901Smckusick
64653901Smckusick bcopy((caddr_t)sc->sc_param, (caddr_t)psave, 20);
64753901Smckusick scinit(sc, slave, DEV_BSIZE);
64853901Smckusick bcopy((caddr_t)psave, (caddr_t)sc->sc_param, 20);
64953901Smckusick
65053901Smckusick sc->sc_cpoint = (u_char *)param;
65153901Smckusick sc->sc_ctrnscnt = count & 0xff;
65253901Smckusick
65353901Smckusick /* sc_cdb */
65453901Smckusick sc->sc_opcode = SCOP_MSELECT;
65553901Smckusick sc->sc_lad = count >> 8;
65653901Smckusick sc->sc_count = count & 0xff;
65753901Smckusick
65853901Smckusick sc_go(intr, (struct scsi *)sc, ie);
65953901Smckusick }
66053901Smckusick
66153901Smckusick #ifdef SRD_MSELECT
66253901Smckusick /*
66353901Smckusick * SCOP_MSELECT request
66453901Smckusick */
scop_msense_OTHER_HD(intr,sc,slave,ie,count,param)66553901Smckusick scop_msense_OTHER_HD(intr, sc, slave, ie, count, param)
66653901Smckusick register int intr;
66753901Smckusick register struct scsi *sc;
66853901Smckusick register int slave;
66953901Smckusick register int ie;
67053901Smckusick register int count;
67153901Smckusick register caddr_t param;
67253901Smckusick {
67353901Smckusick scinit(sc, slave, DEV_BSIZE);
67453901Smckusick
67553901Smckusick sc->sc_cpoint = (u_char *)param;
67653901Smckusick sc->sc_ctrnscnt = count;
67753901Smckusick
67853901Smckusick /* sc_cdb */
67953901Smckusick sc->sc_opcode = SCOP_MSENSE;
68053901Smckusick sc->sc_count = count;
68153901Smckusick sc->sc_lad = 0x3f00;
68253901Smckusick
68353901Smckusick sc_go(intr, (struct scsi *)sc, ie);
68453901Smckusick }
68553901Smckusick
68653901Smckusick /*
68753901Smckusick * SCOP_MSELECT request
68853901Smckusick */
scop_mselect_OTHER_HD(intr,sc,slave,ie,count,param)68953901Smckusick scop_mselect_OTHER_HD(intr, sc, slave, ie, count, param)
69053901Smckusick register int intr;
69153901Smckusick register struct scsi *sc;
69253901Smckusick register int slave;
69353901Smckusick register int ie;
69453901Smckusick register int count;
69553901Smckusick register caddr_t param;
69653901Smckusick {
69753901Smckusick u_char psave[20];
69853901Smckusick
69953901Smckusick bcopy((caddr_t)sc->sc_param, (caddr_t)psave, 20);
70053901Smckusick scinit(sc, slave, DEV_BSIZE);
70153901Smckusick bcopy((caddr_t)psave, (caddr_t)sc->sc_param, 20);
70253901Smckusick
70353901Smckusick sc->sc_cpoint = (u_char *)param;
70453901Smckusick sc->sc_ctrnscnt = count;
70553901Smckusick
70653901Smckusick /* sc_cdb */
70753901Smckusick sc->sc_opcode = SCOP_MSELECT;
70853901Smckusick sc->sc_count = count;
70953901Smckusick sc->sc_lad = 0;
71053901Smckusick
71153901Smckusick sc_go(intr, (struct scsi *)sc, ie);
71253901Smckusick }
71353901Smckusick #endif SRD_MSELECT
71453901Smckusick
scop_erase(intr,sc,slave,ie)71553901Smckusick scop_erase(intr, sc, slave, ie)
71653901Smckusick register int intr;
71753901Smckusick register struct scsi *sc;
71853901Smckusick register int slave;
71953901Smckusick register int ie;
72053901Smckusick {
72153901Smckusick scinit(sc, slave, DEV_BSIZE);
72253901Smckusick
72353901Smckusick /* sc_cdb */
72453901Smckusick sc->sc_opcode = SCOP_ERASE;
72553901Smckusick sc->sc_tucode = 1;
72653901Smckusick
72753901Smckusick sc_go(intr, (struct scsi *)sc, ie);
72853901Smckusick }
72953901Smckusick
73053901Smckusick /*
73153901Smckusick * One sector programmed I/O
73253901Smckusick */
scop_rdwr(intr,sc,slave,ie,flag,addr,lba,sectsize)73353901Smckusick scop_rdwr(intr, sc, slave, ie, flag, addr, lba, sectsize)
73453901Smckusick int intr;
73553901Smckusick register struct scsi *sc;
73653901Smckusick int slave;
73753901Smckusick int ie;
73853901Smckusick int flag;
73953901Smckusick caddr_t addr;
74053901Smckusick int lba;
74153901Smckusick int sectsize;
74253901Smckusick {
74353901Smckusick scinit(sc, slave, sectsize);
74453901Smckusick
74553901Smckusick sc->sc_cpoint = (u_char *)addr;
74653901Smckusick sc->sc_ctrnscnt = sectsize;
74753901Smckusick
74853901Smckusick /* sc_cdb */
74953901Smckusick sc->sc_opcode = (flag & B_READ) ? SCOP_READ : SCOP_WRITE;
75053901Smckusick sc->sc_lad = lba;
75153901Smckusick sc->sc_count = 1;
75253901Smckusick
75353901Smckusick sc_go(intr, sc, ie);
75453901Smckusick }
75553901Smckusick
75653901Smckusick /*
75753901Smckusick * Medium allow/prevent removable
75853901Smckusick */
scop_medrmv(intr,sc,slave,ie,sw)75953901Smckusick scop_medrmv(intr, sc, slave, ie, sw)
76053901Smckusick register int intr;
76153901Smckusick register struct scsi *sc;
76253901Smckusick register int slave;
76353901Smckusick register int ie;
76453901Smckusick register int sw;
76553901Smckusick {
76653901Smckusick scinit(sc, slave, DEV_BSIZE);
76753901Smckusick
76853901Smckusick /* sc_cdb */
76953901Smckusick sc->sc_opcode = SCOP_MEDRMV;
77053901Smckusick sc->sc_count = sw;
77153901Smckusick
77253901Smckusick sc_go(intr, (struct scsi *)sc, ie);
77353901Smckusick }
77453901Smckusick
77553901Smckusick /*
77653901Smckusick * initialize struct scsi
77753901Smckusick */
scinit(sc,slave,sectsize)77853901Smckusick scinit(sc, slave, sectsize)
77953901Smckusick register struct scsi *sc;
78053901Smckusick int slave;
78153901Smckusick int sectsize;
78253901Smckusick {
78353901Smckusick bzero((caddr_t)sc, sizeof(struct scsi));
78453901Smckusick
78553901Smckusick sc->sc_identify = MSG_IDENT|Scsi_Disconnect|(slave & IDT_DRMASK);
78653901Smckusick sc->sc_bytesec = sectsize;
78753901Smckusick sc->sc_lun = slave;
78853901Smckusick }
78953901Smckusick
79053901Smckusick
79153901Smckusick /*
79253901Smckusick * ABORT MESSAGE
79353901Smckusick */
scms_abort(intr,sc,slave,ie)79453901Smckusick scms_abort(intr, sc, slave, ie)
79553901Smckusick register int intr;
79653901Smckusick register struct scsi *sc;
79753901Smckusick register int slave;
79853901Smckusick register int ie;
79953901Smckusick {
80053901Smckusick bzero((caddr_t)sc, sizeof(struct scsi));
80153901Smckusick
80253901Smckusick sc->sc_identify = MSG_ABORT;
80353901Smckusick
80453901Smckusick /* sc_cdb */
80553901Smckusick sc->sc_opcode = SCOP_TST;
80653901Smckusick sc->sc_lun = slave;
80753901Smckusick
80853901Smckusick sc_go(intr, (struct scsi *)sc, ie);
80953901Smckusick }
81053901Smckusick
sc_go(intr,sc,ie)81153901Smckusick sc_go(intr, sc, ie)
81253901Smckusick int intr;
81353901Smckusick struct scsi *sc;
81453901Smckusick int ie;
81553901Smckusick {
81653901Smckusick register struct sc_data *scdp;
81753901Smckusick
81853901Smckusick scdp = &sc_data[intr];
81953901Smckusick
82053901Smckusick if (sc->sc_cpoint)
82153901Smckusick scdp->scd_vaddr = (char *)sc->sc_cpoint;
82253901Smckusick else
82353901Smckusick scdp->scd_vaddr = (char *)sc->sc_param;
82453901Smckusick scdp->scd_procp = curproc;
82553901Smckusick scdp->scd_scaddr = (char *)sc;
82653901Smckusick scdp->scd_count = sc->sc_ctrnscnt;
82753901Smckusick sc->sc_cpoint = (u_char *)ipc_phys(scdp->scd_vaddr);
82853901Smckusick
82953901Smckusick _sc_go(intr, sc, ie);
83053901Smckusick
83153901Smckusick if((ie & SCSI_INTEN) == 0) {
83253901Smckusick #ifdef mips
83353901Smckusick /* if (DATAIN_PHASE_FINISHED) */
83453901Smckusick MachFlushDCache(scdp->scd_scaddr, sizeof (struct scsi));
83553901Smckusick if (MACH_IS_USPACE(scdp->scd_vaddr))
83653901Smckusick panic("sc_go: user address is not supported");
83753901Smckusick else if (MACH_IS_CACHED(scdp->scd_vaddr))
83853901Smckusick MachFlushDCache(scdp->scd_vaddr, scdp->scd_count);
83953901Smckusick else if (MACH_IS_MAPPED(scdp->scd_vaddr))
84053901Smckusick #ifdef notyet /* KU:XXX */
84153901Smckusick clean_k2dcache(scdp->scd_vaddr, scdp->scd_count);
84253901Smckusick #else
84353901Smckusick MachFlushCache(); /* Flush all caches */
84453901Smckusick #endif
84553901Smckusick #endif /* mips */
84653901Smckusick }
84753901Smckusick }
84853901Smckusick
84953901Smckusick #ifdef CPU_SINGLE
_sc_go(intr,sc,ie)85053901Smckusick _sc_go(intr, sc, ie)
85153901Smckusick int intr;
85253901Smckusick struct scsi *sc;
85353901Smckusick int ie;
85453901Smckusick {
85553901Smckusick register int i, s;
85653901Smckusick
85753901Smckusick if((ie & SCSI_INTEN) == 0) {
85853901Smckusick scsend(intr, ie|SCSI_NOTWAIT, sc);
85953901Smckusick while (sc_busy(intr)) {
86053901Smckusick splx(splscon()); /* splsc -1 */
86153901Smckusick #ifdef mc68030
86253901Smckusick dcia();
86353901Smckusick #endif
86453901Smckusick }
86553901Smckusick } else {
86653901Smckusick scsend(intr, ie, (caddr_t)sc);
86753901Smckusick }
86853901Smckusick }
86953901Smckusick #endif /* CPU_SINGLE */
87053901Smckusick
screset(chan)87153901Smckusick screset(chan)
87253901Smckusick int chan;
87353901Smckusick {
87453901Smckusick int i, s;
87553901Smckusick
87653901Smckusick s = splsc();
87753901Smckusick printf("SCSI: screset() called ");
87853901Smckusick scop_init(chan / 8);
87953901Smckusick splx(s);
88053901Smckusick
88153901Smckusick for (s = 0; s < 10; s++) {
88253901Smckusick DELAY(100000 * 10);
88353901Smckusick }
88453901Smckusick printf("\n");
88553901Smckusick iop/**/reset();
88653901Smckusick }
88753901Smckusick
88853901Smckusick scsisetup(bp, map, nmap)
88953901Smckusick struct buf *bp;
89053901Smckusick struct sc_map *map;
89153901Smckusick int nmap;
89253901Smckusick {
89353901Smckusick return (iop/**/setup(bp, map, nmap));
89453901Smckusick }
89553901Smckusick
89653901Smckusick
89753901Smckusick /*
89853901Smckusick * transrate skey / ecode into message display ON/OFF value
89953901Smckusick * 1 : display message
90053901Smckusick * 0 : silence
90153901Smckusick */
isdispmsg(code,list,count)90253901Smckusick isdispmsg(code, list, count)
90353901Smckusick register int code;
90453901Smckusick register struct msg_list *list;
90553901Smckusick int count;
90653901Smckusick {
90753901Smckusick register int msglvl = 0;
90853901Smckusick
90953901Smckusick while (list->ml_code >= 0) {
91053901Smckusick if (code == list->ml_code) {
91153901Smckusick msglvl = list->ml_msglvl;
91253901Smckusick break;
91353901Smckusick }
91453901Smckusick list++;
91553901Smckusick }
91653901Smckusick return (count >= msglvl);
91753901Smckusick }
91853901Smckusick
91953901Smckusick #ifdef NO_SHRINK_RSENSE_MSG
92053901Smckusick /*
92153901Smckusick * transrate skey / ecode into message
92253901Smckusick */
92353901Smckusick char *
getmsg(code,list,defmsg)92453901Smckusick getmsg(code, list, defmsg)
92553901Smckusick int code;
92653901Smckusick struct msg_list *list;
92753901Smckusick char *defmsg;
92853901Smckusick {
92953901Smckusick while (list->ml_code >= 0) {
93053901Smckusick if (code == list->ml_code)
93153901Smckusick return (list->ml_msgstr);
93253901Smckusick list++;
93353901Smckusick }
93453901Smckusick return (defmsg);
93553901Smckusick }
93653901Smckusick #endif /* NO_SHRINK_RSENSE_MSG */
93753901Smckusick
check_chan_busy(intr,sc,slave)93853901Smckusick check_chan_busy(intr, sc, slave)
93953901Smckusick register int intr;
94053901Smckusick register struct scsi *sc;
94153901Smckusick register int slave;
94253901Smckusick {
94353901Smckusick register struct sc_extnd *sce = (struct sc_extnd *)sc->sc_param;
94453901Smckusick int i = 0;
94553901Smckusick
94653901Smckusick if (sc->sc_istatus == INST_EP) {
94753901Smckusick switch (sc->sc_tstatus) {
94853901Smckusick
94953901Smckusick case TGST_CC:
95053901Smckusick scop_rsense(intr, sc, slave, SCSI_INTDIS, 18, 0);
95153901Smckusick if (rsense_msg_disp ||
95253901Smckusick isdispmsg(sce->sce_skey, skeylist, 0)) {
95353901Smckusick #ifdef NO_SHRINK_RSENSE_MSG
95453901Smckusick if (sce->sce_advalid) {
95553901Smckusick printf("SCSI%d(block %d): %s (sense key = 0x%x)\n",
95653901Smckusick intr,
95753901Smckusick (sce->sce_infob1 << 24) +
95853901Smckusick (sce->sce_infob2 << 16) +
95953901Smckusick (sce->sce_infob3 << 8) +
96053901Smckusick (sce->sce_infob4),
96153901Smckusick getmsg(sce->sce_skey, skeylist, "(reserved)"),
96253901Smckusick sce->sce_skey);
96353901Smckusick } else {
96453901Smckusick printf("SCSI%d(unknown block): %s (sense key = 0x%x)\n",
96553901Smckusick intr,
96653901Smckusick getmsg(sce->sce_skey, skeylist, "(reserved)"),
96753901Smckusick sce->sce_skey);
96853901Smckusick }
96953901Smckusick #else /* NO_SHRINK_RSENSE_MSG */
97053901Smckusick if (sce->sce_advalid) {
97153901Smckusick printf("SCSI%d(sn %d): skey=0x%x)\n",
97253901Smckusick intr,
97353901Smckusick (sce->sce_infob1 << 24) +
97453901Smckusick (sce->sce_infob2 << 16) +
97553901Smckusick (sce->sce_infob3 << 8) +
97653901Smckusick (sce->sce_infob4),
97753901Smckusick sce->sce_skey);
97853901Smckusick } else {
97953901Smckusick printf("SCSI%d: skey=0x%x)\n",
98053901Smckusick intr, sce->sce_skey);
98153901Smckusick }
98253901Smckusick #endif /* NO_SHRINK_RSENSE_MSG */
98353901Smckusick printf("sense data = ");
98453901Smckusick for (i = 0; i < 18; i++)
98553901Smckusick printf("%x ", sc->sc_param[i]);
98653901Smckusick printf("\n");
98753901Smckusick }
98853901Smckusick break;
98953901Smckusick
99053901Smckusick case TGST_GOOD:
99153901Smckusick break;
99253901Smckusick
99353901Smckusick default:
99453901Smckusick printf("SCSI%d: bad target status 0x%x\n", intr, sc->sc_tstatus);
99553901Smckusick break;
99653901Smckusick }
99753901Smckusick } else {
99853901Smckusick printf("SCSI%d: bad initiator status 0x%x\n", intr, sc->sc_istatus);
99953901Smckusick }
100053901Smckusick
100153901Smckusick while (i++ < 100000) {
100253901Smckusick scop_tst(intr, sc, slave, SCSI_INTDIS);
100353901Smckusick if (sc->sc_tstatus != TGST_BUSY)
100453901Smckusick break;
100553901Smckusick }
100653901Smckusick if (i > 100000)
100753901Smckusick printf("SCSI%d: still busy after rasblk.\n", intr);
100853901Smckusick }
100953901Smckusick
101053901Smckusick /***/
101153901Smckusick struct scsi_berr_bug_table {
101253901Smckusick int model;
101353901Smckusick int serial_l;
101453901Smckusick int serial_h;
101553901Smckusick int value; /* 1:BUG, 0:NOBUG */
101653901Smckusick };
101753901Smckusick /***/
1018