unhd (Roger Gonzalez ) (06/04/90)
Here's the SCSI driver that was requested. I'm not sure if the interest of only 6 people warrants a post instead of mail, but I don't have much choice, since mail to all but one bounced. # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by root on Mon Jun 4 1990 12:04:00 # Contents: LICENSE.MSEL SCSI.DOC iv3273.h parse_args.c scsi.c scsi.h # scsi_aux.c scsi_bus.c scsi_cmds.c scsi_defs.h scsi_psos.c scsi_types.h # scsi_vars.h scsimon.c echo x - LICENSE.MSEL sed 's/^@//' > "LICENSE.MSEL" <<'@//E*O*F LICENSE.MSEL//' -------------------------------------------------------------------------------- MSEL Software General Public License Because the software produced at the Marine Systems Engineering Laboratory (MSEL) is entirely in the public domain, the purpose of this license is to ensure that prospective users of this software may only use, modify, or redistribute it for non-profit applications in the public domain. MSEL software is available at distribution cost. Comments, suggestions, and criticisms about our software and licensing policies are welcome and encouraged. Marine Systems Engineering Laboratory UNH Marine Programs Building Durham, N.H. 03824 (603) 862-4600 -------------------------------------------------------------------------------- 1) Use, modification, or distribution of MSEL software implies agreement with this license. 2) Every distribution of MSEL software must be accompanied by this licensing agreement, which is Copyright (c) 1990, Marine Systems Engineering Laboratory, and may not be altered. 3) MSEL software, and any software that uses or includes MSEL code, must be distributed at no cost, and entirely in the public domain. 4) MSEL software may be freely modified, as long as valid MSEL copyright notice appears prominently in every file containing MSEL code, and in any documentation that pertains to software containing MSEL code. 5) No warranties are provided to users of MSEL software, to the extent permitted by applicable state laws. Except when otherwise stated in writing by MSEL, the software is provided "as is", without warranty of any kind, expressed or implied. -------------------------------------------------------------------------------- @//E*O*F LICENSE.MSEL// chmod u=rw,g=rw,o=rw LICENSE.MSEL echo x - SCSI.DOC sed 's/^@//' > "SCSI.DOC" <<'@//E*O*F SCSI.DOC//' First of all, if you are expecting a nice tight package ready to run, this isn't it. You will need lots of pizza and coke before even looking through this stuff. This SCSI driver software was designed to be used with a WORM optical drive, controlled by an Ironics iv3273 VME system controller board, and thus there are many reflections of this in the code: - The code is not particularly optimized, because WORM devices are slow. - The command set implemented contains some WORM specific commands. - Although most ANSI-1 WORM commands are in the code, many are untested. - Since our application requires only one device, arbitration is not implemented. - The code controls a NCR5380, a buggy SCSI controller chip. - This code will be a big chore to alter if the NCR5380 registers are not mapped into system memory. - The code is sparsely commented, but was written to be readable to C programmers. - This code is written to run on Unix, or on pSOS with Unix C libraries mapped to pSOS equivilents (I trust most people have done this..!) Fortunately, at the driver level, the C routines called are minimal. - Not all necessary include files are bundled with the package, but the required typedefs or #defines should be obvious (i.e. U_int is unsigned int) So. You aren't discouraged so far, because you have a VME machine, with a SCSI controller board with a NCR5380 mapped into VME memory. How do you get this to run. Here's the recipe: 1) Change all occurences of IV3273 to some variable that you have #defined to be the base address of your NCR5380 chip. If you are running from a Unix development environment, this should be a virtual address as reflected by a phys() in your application code. If a pSOS target, then use the physical address. 2) Change the structure definitions of the '5380 registers (if necessary) to reflect whatever E.E. weenie scheme they implemented on your board. If you're lucky, you can take out all the dummy byte references. 3) Compile, and fix all the little things that you (or I) forgot. With luck, they should be self-documenting. I suggest building a library with the .o files; I use 3 libraries: a pSOS version, a Unix version, and a version for PROMming. 4) Write a quick and dirty routine to call scsi_reset(). Build the "scsimon" program to watch the scsi bus. Leave it running whild you run your reset program. You should see the "R" bit highlight, and then go dim. 5) Buy a new real-time OS that gives you a commercial SCSI driver so that you don't have to do work like this and reinvent the wheel. Well, thats that. Feel free to call me, but don't expect much. I prefer email so that I can just file it make bugfixes at my leisure. If you are having problems not directly related to my code, don't ask me. If you find the SCSI code difficult to understand, well, it *is*. Buy the SCSI spec from Global Engineering Documents 2805 McGraw Drive, Irvine CA 92714 (800) 854-7179. I'm willing to help you *only* if you are running a fairly similar system to mine, and understand C, SCSI, the NCR5380, VME addressing, pSOS/Unix, and are running my code with little modification. Driver code is very subtle stuff, and can be affected by little things. I don't have the time to track down little buggies in your system; it was bad enough doing it on mine. My suggestion is to use this code as a *reference*, and not to try to use it until you completely understand it. If you run this on a Unix development system as root, and screw up, you're probably going to take the system down, cause data loss, and generally make lots of sparks. Be careful, and have fun. The SCSI driver animal is a very satisfying beast to grind beneath your heel! :-) -Roger @//E*O*F SCSI.DOC// chmod u=rw,g=rw,o=rw SCSI.DOC echo x - iv3273.h sed 's/^@//' > "iv3273.h" <<'@//E*O*F iv3273.h//' /* @(#)iv3273.h 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez 10/89 Modification History: ******************************************************************/ /* Board description of Ironics IV3273 System Controller board */ /* References: IV3273 Manual (pp6.1-6.54), NCR5380 Manual (pp10-17). */ /* This section defines the templates for the NCR5380 SCSI interface chip */ typedef struct { /* READ mode (IOR pulse) */ byte curr_data; /* Read active SCSI data bus */ byte dummy1; /* The iv3273 puts "empty" spots in */ byte init_cmd; /* Assert SCSI bus signals (see below) */ byte dummy2; byte mode; /* Controls chip operation (see below) */ byte dummy3; byte target_cmd; /* Target command register */ byte dummy4; byte status_1; /* 7 bus sigs + parity bit */ byte dummy5; byte status_2; /* 2 bus sigs + 6 status bits */ byte dummy6; byte input_data; /* used to read latched data from bus */ byte dummy7; byte reset_status; /* a read resets ParErr/IntReq/BusyErr */ } ncr5380_rd; typedef struct { /* WRITE mode (IOW pulse) */ byte output_data; /* sends data to scsi bus */ byte dummy1; byte init_cmd; /* ditto as read */ byte dummy2; byte mode; /* ditto as read */ byte dummy3; byte target_cmd; /* ditto as read */ byte dummy4; byte select_enable; /* see manual - mondo strange */ byte dummy5; byte dma_send; /* initiate dma send (set dma mode 1st) */ byte dummy6; byte dma_target_rec; /* start dma receive in target mode */ byte dummy7; byte dma_init_rec; /* start dma receive in initiator mode */ } ncr5380_wr; @//E*O*F iv3273.h// chmod u=rw,g=rw,o=rw iv3273.h echo x - parse_args.c sed 's/^@//' > "parse_args.c" <<'@//E*O*F parse_args.c//' #include <stdio.h> #include <string.h> char active_flags[10]; int parse_args(legal_flags, p_argc, p_argv, inputfile, outputfile) char *legal_flags; int p_argc; char *p_argv[]; char *inputfile; char *outputfile; { int c, flag, argnum; char f; *inputfile = NULL; *outputfile = NULL; *active_flags = NULL; c = 0; for (argnum = 1; argnum < p_argc; argnum++) { if (p_argv[argnum][0] == '-') { for (flag = 1; flag <= strlen(p_argv[argnum]) - 1; flag++) { f = p_argv[argnum][flag]; if (strchr(legal_flags, f) == NULL) { fprintf(stderr, "%s: bad flag -%c.\n",p_argv[0], f); return -1; } active_flags[c] = f; c++; } } else { if (*inputfile == NULL) strncpy(inputfile, p_argv[argnum], 80); else if (*outputfile == NULL) strncpy(outputfile, p_argv[argnum], 80); else fprintf(stderr, "%s: extra argument ignored: %s\n", p_argv[0], p_argv[argnum]); } } active_flags[c] = NULL; return 0; } int on(flag) char flag; { if (strchr(active_flags, flag) == NULL) { return 0; } else { return 1; } } int turn_on(flags) char *flags; { strcat(active_flags, flags); } @//E*O*F parse_args.c// chmod u=rw,g=rw,o=rw parse_args.c echo x - scsi.c sed 's/^@//' > "scsi.c" <<'@//E*O*F scsi.c//' /* @(#)scsi.c 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ #include "../include/scsi.h" #include "../include/scsi_vars.h" /*----------------------------------------------------------------------------*/ /* traverse - given a scsi command, traverses a state table of bus states */ /*----------------------------------------------------------------------------*/ Exit_packet traverse(cmd, cmdlen, data, datalen, rs, dt) Byte *cmd; /* SCSI command packet */ short cmdlen; /* length of packet */ Byte *data; /* data packet */ short datalen; /* length of packet */ Byte rs; /* true if req sen on error */ Byte dt; /* flag for data transfer */ { Byte status; /* status byte returned from scsi transfer */ Byte message; /* message byte returned from scsi */ Byte exit_val; /* exit value from scsi transfer */ Byte sense[16]; /* 16 byte request sense storage space */ Byte retries; /* # of retries counter */ Byte state, newstate;/* state table variables */ Byte rsflag; /* true if a request sense will be used */ Byte resets; /* # of bus resets counter */ Exit_packet ep, rep; /* exit packet variables */ rsflag = FALSE; newstate = START; state = START; retries = 0; resets = 0; ep.type = SUCCESS; ep.scsi = SUCCESS; ep.status = SUCCESS; ep.message = 0; ep.sense = NO_SENSE; ep.xsense = NO_SENSE; rep.type = SUCCESS; exit_val = 0; #ifdef DEBUG printf("States: "); #endif while ((state & EXIT) != EXIT) { newstate = find_next_state(state, exit_val, dt, retries); #ifdef DEBUG printf("%d-", newstate); #endif switch(newstate) { case BUSFREE: exit_val = scsi_bus_free(); if (exit_val) ep.scsi = BUS_FREE_FAILURE; break; case SELECT: exit_val = scsi_select(); if (exit_val) ep.scsi = SELECT_FAILURE; break; case COMMAND: exit_val = scsi_put(COMMAND_PHASE, cmd, cmdlen); if (exit_val) ep.scsi = COMMAND_FAILURE; while (scsi_phase() == COMMAND_PHASE) ; break; case DATAIN: if (scsi_phase() == STATUS_PHASE) { rsflag = TRUE; /* uh oh, we'd better reqsen */ exit_val = 0; } else { exit_val = scsi_get(DATA_IN_PHASE, data, datalen); if (exit_val) ep.scsi = DATA_FAILURE; } break; case DATAOUT: if (scsi_phase() == STATUS_PHASE) { rsflag = TRUE; /* uh oh, we'd better reqsen */ exit_val = 0; } else { exit_val = scsi_put(DATA_OUT_PHASE, data, datalen); if (exit_val) ep.scsi = DATA_FAILURE; } break; case STATUS: exit_val = scsi_get(STATUS_PHASE, &status, 1); if (exit_val) ep.scsi = STATUS_FAILURE; if (!exit_val && status) rsflag = TRUE; ep.status = status; while (scsi_phase() == STATUS_PHASE) ; break; case MESSAGE: ep.sense = NO_SENSE; ep.xsense = NO_SENSE; exit_val = scsi_get(MSG_IN_PHASE, &message, 1); if (exit_val) ep.scsi = MESSAGE_FAILURE; else { ep.scsi = SUCCESS; retries = 0; } ep.message = message; if (rs && rsflag && !exit_val) { #ifdef DEBUG printf("\nRequesting sense data... "); #endif rep = request_sense(0, sense, 16); /* note: this is */ if (rep.type == SUCCESS) { /* recursing here */ ep.sense = sense[2]; ep.xsense = sense[12]; rsflag = FALSE; } else { printf("\nrequest sense did not work.\n"); newstate = DEATH; } } switch(ep.sense) { case NO_SENSE: newstate = COMPLETED; break; case RECOVERED_ERROR: newstate = COMPLETED; ep.type = CORRECTED; break; case NOT_READY: newstate = operator(ep); ep.type = OPERATOR; break; case MEDIUM_ERROR: newstate = operator(ep); ep.type = OPERATOR; break; case HARDWARE_ERROR: newstate = operator(ep); ep.type = OPERATOR; break; case ILLEGAL_REQUEST: newstate = operator(ep); ep.type = OPERATOR; break; case UNIT_ATTENTION: if (ep.xsense == 28) { ep.type = NEWMEDIA; newstate = DEATH; } else { newstate = START; ep.type = SUCCESS; } break; case DATA_PROTECT: ep.type = OPERATOR; newstate = operator(ep); break; case BLANK_CHECK: newstate = DEATH; ep.type = FAIL; break; case ABORTED_COMMAND: newstate = START; ep.type = RETRY; break; } #ifdef DEBUG printf("\n"); #endif break; case ERROR: printf("Too many SCSI errors.. wait for soft reset.\n"); exit_val = scsi_reset(); if (resets++ > 2) { /* this isn't working right. */ newstate = DEATH; /* the intention is to quit */ ep.type = FATAL; /* after 3, but it doesn't. */ } /* but then, if you have to */ else /* reset more than twice, there */ newstate = START; /* are *big* problems! */ break; } if (state == newstate) { retries++; } state = newstate; } if (ep.scsi != SUCCESS) ep.type = SCSIFAIL; return(ep); } /*----------------------------------------------------------------------------*/ @//E*O*F scsi.c// chmod u=rw,g=rw,o=rw scsi.c echo x - scsi.h sed 's/^@//' > "scsi.h" <<'@//E*O*F scsi.h//' /* @(#)scsi.h 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ #include "/usr/usr1/include/types.h" #include "/usr/usr1/include/defs.h" #include "/usr/usr1/maxtor/src/rg/include/scsi_types.h" #include "/usr/usr1/maxtor/src/rg/include/scsi_defs.h" extern Byte it_went_high(); extern Byte it_went_low(); extern U_int scsi_reset(); extern U_int scsi_select(); extern U_int scsi_get(); extern U_int scsi_put(); extern Exit_packet traverse(); extern Exit_packet read_blocks(); extern Exit_packet write_blocks(); extern Exit_packet request_sense(); extern Exit_packet inquiry(); extern Exit_packet mode_sense(); extern Exit_packet medium_removal(); extern char states[9][16]; @//E*O*F scsi.h// chmod u=rw,g=rw,o=rw scsi.h echo x - scsi_aux.c sed 's/^@//' > "scsi_aux.c" <<'@//E*O*F scsi_aux.c//' /* @(#)scsi_aux.c 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ #include "../include/scsi.h" /*--------------------------------------------------------------------------*/ /* find_next_state - auxillary routine for "traverse". */ /*--------------------------------------------------------------------------*/ Byte find_next_state(state, exit_val, data, retries) Byte state, exit_val, data, retries; { short x; x = ((exit_val == SUCCESS)? (data) :( ((retries + 1) << 2) | data)); return(states[state][x]); } /*--------------------------------------------------------------------------*/ /* it_went_high - return true if the register bits go high before timeout */ /*--------------------------------------------------------------------------*/ Byte it_went_high(regaddr, bitmap) Byte *regaddr; Byte bitmap; { U_int counter = 0; while ((++counter < LIMIT) && ((*regaddr & bitmap) != bitmap)) ; return ((counter < LIMIT)? TRUE : FALSE); } /*--------------------------------------------------------------------------*/ /* it_went_low - return true if the register bits go low before timeout */ /*--------------------------------------------------------------------------*/ Byte it_went_low(regaddr, bitmap) Byte *regaddr; Byte bitmap; { U_int counter = 0; while ((++counter < LIMIT) && ((~(*regaddr) & bitmap) != bitmap)) ; return((counter < LIMIT)? TRUE : FALSE); } /*--------------------------------------------------------------------------*/ @//E*O*F scsi_aux.c// chmod u=rw,g=rw,o=rw scsi_aux.c echo x - scsi_bus.c sed 's/^@//' > "scsi_bus.c" <<'@//E*O*F scsi_bus.c//' /* @(#)scsi_bus.c 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ #include "../include/scsi.h" #include "/usr/usr1/include/iv3273.h" /*--------------------------------------------------------------------------*/ /* scsi_bus_free - return true if the bus becomes free before timeout */ /*--------------------------------------------------------------------------*/ U_int scsi_bus_free() { Ncr5380_rd *sread = (Ncr5380_rd *) IV3273; if (!it_went_low(&sread->status_1, SEL | BSY)) { #ifdef DEBUG printf("scsi_bus_free: bus is selected or busy\n"); #endif return(TIMEOUT); } else return(SUCCESS); } /*--------------------------------------------------------------------------*/ /* scsi_reset - toggle the reset control bit of the scsi bus */ /*--------------------------------------------------------------------------*/ U_int scsi_reset() { Ncr5380_rd *sread = (Ncr5380_rd *) IV3273; Ncr5380_wr *swrite = (Ncr5380_wr *) IV3273; Byte dummy; swrite->init_cmd = ASSERT_RST; sleep(1); swrite->init_cmd = 0x00; dummy = sread->reset_status; sleep(10); return(SUCCESS); } /*--------------------------------------------------------------------------*/ /* scsi_phase - returns the current phase of the scsi bus */ /*--------------------------------------------------------------------------*/ U_int scsi_phase() { Ncr5380_rd *sread = (Ncr5380_rd *) IV3273; return((sread->status_1 & 0x1c) >> 2); } /*--------------------------------------------------------------------------*/ /* scsi_select - select a target (NO ARBITRATION SUPPORTED!) */ /*--------------------------------------------------------------------------*/ U_int scsi_select() { Ncr5380_rd *sread = (Ncr5380_rd *) IV3273; Ncr5380_wr *swrite = (Ncr5380_wr *) IV3273; swrite->output_data = 0x01; /* Put target ID on bus */ swrite->init_cmd = ASSERT_DB; swrite->init_cmd = ASSERT_SEL | ASSERT_DB; swrite->target_cmd = 0x00; if (!it_went_high(&sread->status_1, BSY)) { /* Did target respond? */ #ifdef DEBUG printf("scsi_select timeout: no response from target\n"); #endif return(TIMEOUT); /* No. */ } swrite->init_cmd = 0x00; return(SUCCESS); /* go home. */ } /*--------------------------------------------------------------------------*/ /* scsi_put - transfer bytes to the scsi bus. the target must be ready to */ /* receive the bytes, or an error will be returned. */ /*--------------------------------------------------------------------------*/ U_int scsi_put(phase_cmd, buffer, count) Byte phase_cmd; Byte *buffer; U_int count; { Ncr5380_rd *sread = (Ncr5380_rd *) IV3273; Ncr5380_wr *swrite = (Ncr5380_wr *) IV3273; U_int c; Byte r; swrite->target_cmd = phase_cmd; if (!it_went_high(&sread->status_2, PHASE_MATCH)) { #ifdef DEBUG printf("phase %d scsi_put timeout: mismatch with target phase %d.\n",phase_cmd, (sread->status_1 & 0x1c) >> 2); #endif return(TIMEOUT); } for (c = 0; c < count; c++) { if (!it_went_high(&sread->status_1, REQ)) { #ifdef DEBUG printf("phase %d scsi_put timeout: no request on Byte %d.\n", phase_cmd, c); #endif return(TIMEOUT); } if (sread->status_2 == IRQ_ACTIVE) { r = sread->reset_status; } swrite->output_data = buffer[c]; swrite->init_cmd = ASSERT_DB; swrite->init_cmd = ASSERT_DB | ASSERT_ACK; if (!it_went_low(&sread->status_1, REQ)) { #ifdef DEBUG printf("phase %d scsi_put timeout: no acknowledge on Byte %d.\n", phase_cmd, c); #endif return(TIMEOUT); } swrite->init_cmd = 0x00; } return(SUCCESS); } /*--------------------------------------------------------------------------*/ /* scsi_get - read bytes from the scsi bus */ /*--------------------------------------------------------------------------*/ U_int scsi_get(phase_cmd, buffer, count) Byte phase_cmd; Byte *buffer; U_int count; { Ncr5380_rd *sread = (Ncr5380_rd *) IV3273; Ncr5380_wr *swrite = (Ncr5380_wr *) IV3273; Byte r; U_int c = 0; swrite->target_cmd = phase_cmd; if (!it_went_high(&sread->status_2, PHASE_MATCH)) { #ifdef DEBUG printf("phase %d scsi_get timeout: mismatch with target phase %d.\n", phase_cmd, (sread->status_1 & 0x1c) >> 2); #endif return(TIMEOUT); } while ((c < count) && ((sread->status_2 & PHASE_MATCH) == PHASE_MATCH)) { if (!it_went_high(&sread->status_1, REQ)) { #ifdef DEBUG printf("phase %d scsi_get timeout: no request on Byte %d.\n", phase_cmd, c); #endif return(TIMEOUT); } if (sread->status_2 == IRQ_ACTIVE) r = sread->reset_status; buffer[c++] = sread->curr_data; swrite->init_cmd = ASSERT_ACK; if (!it_went_low(&sread->status_1, REQ)) { #ifdef DEBUG printf("phase %d scsi_get timeout: no acknowledge on Byte %d.\n", phase_cmd, c); #endif return(TIMEOUT); } swrite->init_cmd = 0x00; } if (c != count) { #ifdef DEBUG printf("phase %d scsi_get failure: only read %d Bytes, expected %d.\n", phase_cmd, c, count); #endif return(FAILURE); } return(SUCCESS); } /*--------------------------------------------------------------------------*/ @//E*O*F scsi_bus.c// chmod u=rw,g=rw,o=rw scsi_bus.c echo x - scsi_cmds.c sed 's/^@//' > "scsi_cmds.c" <<'@//E*O*F scsi_cmds.c//' /* @(#)scsi_cmds.c 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ #include "../include/scsi.h" /*--------------------------------------------------------------------------*/ /* These routines exercise the SCSI transactions supported by the Maxtor */ /* RXT-800s worm optical drive, an ANSI SCSI-I device */ /*--------------------------------------------------------------------------*/ Exit_packet test_unit_ready(lun) Byte lun; { Byte command[6], data; command[0] = TEST_UNIT_READY; command[1] = lun << 5; command[2] = RESERVED; command[3] = RESERVED; command[4] = RESERVED; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet rezero_unit(lun) Byte lun; { Byte command[6], data; command[0] = REZERO_UNIT; command[1] = lun << 0x05; command[2] = RESERVED; command[3] = RESERVED; command[4] = RESERVED; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet request_sense(lun, data, length) Byte lun; Byte *data; Byte length; { Byte command[6]; command[0] = REQUEST_SENSE; command[1] = lun << 5; command[2] = RESERVED; command[3] = RESERVED; command[4] = length; command[5] = 0x00; return(traverse(command, 6, data, length, NS, DI)); } /*--------------------------------------------------------------------------*/ Exit_packet format_unit(lun, fmt, cmp, dlf, interleave) Byte lun; Byte fmt; Byte cmp; Byte dlf; long interleave; { Byte command[6], data; command[0] = FORMAT_UNIT; command[1] = (lun << 5) + (fmt << 4) + (cmp << 3) + dlf; command[2] = RESERVED; command[3] = (interleave & 0xff00) >> 4; command[4] = interleave & 0xff; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet reassign_blocks(lun) Byte lun; { Byte command[6], data; command[0] = REASSIGN_BLOCKS; command[1] = lun << 5; command[2] = RESERVED; command[3] = RESERVED; command[4] = RESERVED; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet read_blocks(lun, start, blocks, data, length) Byte lun; long start; Byte blocks; Byte *data; short length; { Byte command[6]; command[0] = READ; command[1] = (lun << 5) + ((start & 0x1f0000) >> 16); command[2] = (start & 0xff00) >> 0x08; command[3] = (start & 0xff); command[4] = blocks; command[5] = 0x00; return(traverse(command, 6, data, length, RS, DI)); } /*--------------------------------------------------------------------------*/ Exit_packet write_blocks(lun, start, blocks, data, length) Byte lun; long start; Byte blocks; Byte *data; short length; { Byte command[6]; command[0] = WRITE; command[1] = (lun << 5) + ((start & 0x1f0000) >> 16); command[2] = (start & 0xff00) >> 0x08; command[3] = (start & 0xff); command[4] = blocks; command[5] = 0x00; return(traverse(command, 6, data, length, RS, DO)); } /*--------------------------------------------------------------------------*/ Exit_packet seek(lun, lbn) Byte lun; long lbn; { Byte command[6], data; command[0] = SEEK; command[1] = (lun << 5) + ((lbn & 0xff0000) >> 16); command[2] = (lbn & 0xff00) >> 8; command[3] = lbn & 0xff; command[4] = RESERVED; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet inquiry(lun, data, length) Byte lun; Byte *data; Byte length; { Byte command[6]; command[0] = INQUIRY; command[1] = lun << 5; command[2] = RESERVED; command[3] = RESERVED; command[4] = length; command[5] = 0x00; return(traverse(command, 6, data, length, RS, DI)); } /*--------------------------------------------------------------------------*/ Exit_packet mode_select(lun, pf, data, length) Byte lun; Byte pf; Byte length; { Byte command[6]; command[0] = MODE_SELECT; command[1] = (lun << 5) + ((pf & 0x01) << 4); command[2] = RESERVED; command[3] = RESERVED; command[4] = length; command[5] = 0x00; return(traverse(command, 6, data, length, RS, DO)); } /*--------------------------------------------------------------------------*/ Exit_packet reserve(lun, tp, tpid) Byte lun; Byte tp; Byte tpid; { Byte command[6], data; command[0] = RESERVE; command[1] = (lun << 5) + ((tp & 0x01) << 0x04) + (tpid << 0x01); command[2] = RESERVED; command[3] = RESERVED; command[4] = RESERVED; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ /* I'm commented out because of name conflicts with mascon. Fix me someday. Exit_packet release(lun, tp, tpid) Byte lun, tp, tpid; { Byte command[6], data; command[0] = RELEASE; command[1] = (lun << 5) + ((tp & 0x01) << 0x04) + (tpid << 0x01); command[2] = RESERVED; command[3] = RESERVED; command[4] = RESERVED; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } */ /*--------------------------------------------------------------------------*/ Exit_packet copy(lun, length) Byte lun; long length; { Byte command[6], data; command[0] = COPY; command[1] = lun << 5; command[2] = (length & 0xff0000) >> 16; command[3] = (length & 0xff00) >> 8; command[4] = length & 0xff; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet mode_sense(lun, pcf, pc, data, length) Byte lun; Byte pcf; Byte pc; Byte *data; Byte length; { Byte command[6]; command[0] = MODE_SENSE; command[1] = lun << 5; command[2] = ((pcf & 0x03) << 6) + pc; command[3] = RESERVED; command[4] = length; command[5] = 0x00; return(traverse(command, 6, data, length, RS, DI)); } /*--------------------------------------------------------------------------*/ Exit_packet unit_motor(lun, staddr, imm) Byte lun; Byte staddr; Byte imm; { Byte command[6], data; command[0] = UNIT_MOTOR; command[1] = (lun << 5) + (imm & 0x01); command[2] = RESERVED; command[3] = RESERVED; command[4] = staddr & 0x01; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet send_diagnostic(lun, st) Byte lun; Byte st; { Byte command[6], data; command[0] = SEND_DIAGNOSTICS; command[1] = (lun << 5) + ((st & 0x01) << 0x02); command[2] = RESERVED; command[3] = RESERVED; command[4] = RESERVED; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet medium_removal(lun, prevent) Byte lun; Byte prevent; { Byte command[6], data; command[0] = MEDIUM_REMOVAL; command[1] = (lun << 5); command[2] = RESERVED; command[3] = RESERVED; command[4] = prevent & 0x01; command[5] = 0x00; return(traverse(command, 6, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ Exit_packet read_capacity(lun, addr, pmi, data) Byte lun; long addr; Byte pmi; Byte *data; { Byte command[10]; command[0] = READ_CAPACITY; command[1] = lun << 5; command[2] = ((addr & 0xff000000) >> 32); command[3] = ((addr & 0xff0000) >> 16); command[4] = ((addr & 0xff00) >> 8); command[5] = addr & 0xff; command[6] = RESERVED; command[7] = RESERVED; command[8] = pmi & 0x01; command[9] = 0x00; return(traverse(command, 10, data, 8, RS, DI)); } /*--------------------------------------------------------------------------*/ Exit_packet extended_read(lun, staddr, data, length) Byte lun; long staddr; Byte *data; long length; { Byte command[10]; command[0] = EXTENDED_READ, command[1] = (lun << 5); command[2] = ((staddr & 0xff000000) >> 32); command[3] = ((staddr & 0xff0000) >> 16); command[4] = ((staddr & 0xff00) >> 8); command[5] = staddr & 0xff; command[6] = RESERVED; command[7] = ((length & 0xff00) >> 8); command[8] = length & 0xff; command[9] = 0x00; return(traverse(command, 10, data, length, RS, DI)); } /*--------------------------------------------------------------------------*/ Exit_packet extended_write(lun, staddr, data, length) Byte lun; long staddr; Byte *data; long length; { Byte command[10]; command[0] = EXTENDED_WRITE; command[1] = lun << 5; command[2] = ((staddr & 0xff000000) >> 32); command[3] = ((staddr & 0xff0000) >> 16); command[4] = ((staddr & 0xff00) >> 8); command[5] = (staddr & 0xff); command[6] = RESERVED; command[7] = ((length & 0xff00) >> 0x08); command[8] = (length & 0xff); command[9] = 0x00; return(traverse(command, 10, data, length, RS, DO)); } /*--------------------------------------------------------------------------*/ Exit_packet extended_seek(lun, addr) Byte lun; long addr; { Byte command[10], data; command[0] = EXTENDED_SEEK; command[1] = (lun << 5); command[2] = ((addr & 0xff000000) >> 32); command[3] = ((addr & 0xff0000) >> 16); command[4] = ((addr & 0xff00) >> 8); command[5] = (addr & 0xff); command[6] = RESERVED; command[7] = RESERVED; command[8] = RESERVED; command[9] = 0x00; return(traverse(command, 10, &data, 0, RS, ND)); } /*--------------------------------------------------------------------------*/ @//E*O*F scsi_cmds.c// chmod u=rw,g=rw,o=rw scsi_cmds.c echo x - scsi_defs.h sed 's/^@//' > "scsi_defs.h" <<'@//E*O*F scsi_defs.h//' /* @(#)scsi_defs.h 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ /*----------------------------------------------------------------------------*/ /* IRONICS IV3273 - REGISTER BITMASK DEFINITIONS */ /*----------------------------------------------------------------------------*/ #define DATA_OUT_PHASE 0x00 /* Target Command register */ #define DATA_IN_PHASE 0x01 #define COMMAND_PHASE 0x02 #define STATUS_PHASE 0x03 #define MSG_OUT_PHASE 0x06 #define MSG_IN_PHASE 0x07 #define REQ 0x20 /* Current SCSI Bus Status register */ #define BSY 0x40 #define SEL 0x02 #define PHASE_MATCH 0x08 /* Bus and Status register */ #define ACK 0x01 #define IRQ_ACTIVE 0x10 #define ASSERT_DB 0x01 /* Initiator Command register */ #define ASSERT_SEL 0x04 #define ASSERT_BSY 0x08 #define ASSERT_ACK 0x10 #define ASSERT_RST 0x80 #define TARGET_MODE 0x40 /* Mode register */ /*----------------------------------------------------------------------------*/ /* SYSTEM CONTROLLER BOARD ADDRESSES (AFTER PHYS) */ /*----------------------------------------------------------------------------*/ #ifdef UNIX #define IV3273 0xfffa01 /* Slave 3273 (Unix, virtual address) */ #define IV3273_U 0xfffc01 /* Master 3273 (Unix, virtual address) */ #endif #ifdef PSOS #define IV3273 0xfffffa01 /* Master 3273 (pSOS, physical address) */ #endif /*----------------------------------------------------------------------------*/ /* EXIT PACKET SCSI REPORT */ /*----------------------------------------------------------------------------*/ #define COMMAND_COMPLETE 0 /* Operation succeeded */ #define BUS_FREE_FAILURE 1 /* Timeout on SEL or BSY */ #define SELECT_FAILURE 2 /* Couldn't SEL */ #define COMMAND_FAILURE 3 /* Command phase failed */ #define DATA_FAILURE 4 /* REQ/ACK timeout or data count wrong */ #define STATUS_FAILURE 5 /* Couldn't get status */ #define MESSAGE_FAILURE 6 /* Couldn't get message */ /*----------------------------------------------------------------------------*/ /* LEGAL STATES */ /*----------------------------------------------------------------------------*/ #define START 0 /* States that are traversed in scsi_aux.c. These */ #define BUSFREE 1 /* states dictate which SCSI phase to enter, as well */ #define SELECT 2 /* as error handling ability. */ #define COMMAND 3 #define DATAIN 4 #define DATAOUT 5 #define STATUS 6 #define MESSAGE 7 #define ERROR 8 #define COMPLETED 16 #define EXIT 16 #define DEATH 17 /*----------------------------------------------------------------------------*/ /* STATE TABLE DEFINITIONS */ /*----------------------------------------------------------------------------*/ #define RS 1 /* Request sense true */ #define NS 0 /* Request sense false */ #define ND 0 /* No data */ #define DI 1 /* Data in */ #define DO 2 /* Data out */ /*----------------------------------------------------------------------------*/ /* EXIT PACKET TYPE */ /*----------------------------------------------------------------------------*/ #define CORRECTED 1 /* There was an error that was corrected */ #define OPERATOR 2 /* An error was passed to the operator */ #define NEWMEDIA 3 /* Optical disk in drive has changed */ #define RETRY 4 /* Operation may succeed if retried */ #define SCSIFAIL 5 /* Something was wrong with the SCSI protocol */ #define FAIL 6 /* Current operation did not succeed */ #define FATAL 7 /* Major failure; all worm/scsi code affected */ /*----------------------------------------------------------------------------*/ /* EXIT PACKET STATUS */ /*----------------------------------------------------------------------------*/ #define GOOD 0x00 /* Operation succeeded */ #define CHECK_CONDITION 0x02 /* Operation ignored; do reqsen and retry */ #define BUSY 0x08 /* Drive is busy.. retry later */ #define INTERMEDIATE_GOOD 0x10 /* Success in one part of multipart op */ #define RESERVE_CONFLICT 0x18 /* Shouldn't happen (no arbitration) */ /*----------------------------------------------------------------------------*/ /* EXIT PACKET SENSE */ /*----------------------------------------------------------------------------*/ #define NO_SENSE 0x0 /* No sense information */ #define RECOVERED_ERROR 0x1 /* Internal correction of error */ #define NOT_READY 0x2 /* No disk in drive, or drive not connected */ #define MEDIUM_ERROR 0x3 /* Physical problem with disk */ #define HARDWARE_ERROR 0x4 /* See extended sense bytes for more info */ #define ILLEGAL_REQUEST 0x5 /* Command packet contained illegal info */ #define UNIT_ATTENTION 0x6 /* Power on, reset, or drive info changed */ #define DATA_PROTECT 0x7 /* Tried to write to protected block */ #define BLANK_CHECK 0x8 /* Read an empty block, or wrote a written */ #define ABORTED_COMMAND 0xB /* Drive aborted. Retry operation */ /*----------------------------------------------------------------------------*/ /* SCSI TYPES */ /*----------------------------------------------------------------------------*/ #define TEST_UNIT_READY 0x00 /* Group 0 SCSI commands */ #define REZERO_UNIT 0x01 #define REQUEST_SENSE 0x03 #define FORMAT_UNIT 0x04 #define REASSIGN_BLOCKS 0x07 #define READ 0x08 #define WRITE 0x0A #define SEEK 0x0B #define INQUIRY 0x12 #define MODE_SELECT 0x15 #define RESERVE 0x16 #define RELEASE 0x17 #define COPY 0x18 #define MODE_SENSE 0x1A #define UNIT_MOTOR 0x1B #define SEND_DIAGNOSTICS 0x1D #define MEDIUM_REMOVAL 0x1E #define READ_CAPACITY 0x25 /* Group 1 SCSI Commands */ #define EXTENDED_READ READ + 0x20 #define EXTENDED_WRITE WRITE + 0x20 #define EXTENDED_SEEK SEEK + 0x20 #define VERIFY 0x2F #define READ_DEFECT_DATA 0x37 #define COMPARE 0x39 #define COPY_AND_VERIFY 0x3A #define WRITE_DATA_BUFFER 0x3B #define READ_DATA_BUFFER 0x3C /*----------------------------------------------------------------------------*/ /* MISC */ /*----------------------------------------------------------------------------*/ #define TIMEOUT 2 /* Error number for timeout */ #define LIMIT 100000 /* Timeout maximum count */ #define RESERVED 0 /* Used to fill SCSI commands */ #define LUN 0 #define LOCK 1 #define UNLOCK 0 @//E*O*F scsi_defs.h// chmod u=rw,g=rw,o=rw scsi_defs.h echo x - scsi_psos.c sed 's/^@//' > "scsi_psos.c" <<'@//E*O*F scsi_psos.c//' /* @(#)scsi_psos.c 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ #include "../include/scsi.h" /*--------------------------------------------------------------------------*/ /* operator - prompt the operator for error correction procedure */ /*--------------------------------------------------------------------------*/ Byte operator(ep) /* I should be replaced with something more */ Exit_packet ep; /* apropos to an autonomous vehicle with only */ { /* occasional operator interaction. Oh well. */ char c; if (ep.sense == NOT_READY) printf("Optical drive not ready. (R)etry or (F)ail? "); else if (ep.sense == DATA_PROTECT) printf("Protected data. (R)etry or (F)ail? "); else { printf("Optical drive error:\n"); /* note that %02X is */ printf(" Status: %02X\n", ep.status); /* different here */ printf(" Message: %02X\n", ep.message); /* than unix */ printf(" Sense: %02X\n", ep.sense); printf(" XSense: %02X\n", ep.xsense); printf("\n(R)etry or (F)ail? "); } c = getchar(); if ((c == 'f') || (c == 'F')) return DEATH; else return START; } /*--------------------------------------------------------------------------*/ @//E*O*F scsi_psos.c// chmod u=rw,g=rw,o=rw scsi_psos.c echo x - scsi_types.h sed 's/^@//' > "scsi_types.h" <<'@//E*O*F scsi_types.h//' /* @(#)scsi_types.h 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ typedef struct { Byte type; Byte scsi; Byte status; Byte message; Byte sense; Byte xsense; } Exit_packet; @//E*O*F scsi_types.h// chmod u=rw,g=rw,o=rw scsi_types.h echo x - scsi_vars.h sed 's/^@//' > "scsi_vars.h" <<'@//E*O*F scsi_vars.h//' /* @(#)scsi_vars.h 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez 1/90 Modification History: ******************************************************************/ /* s=success, f=failure w/0 retries, F=failure w/1, Q=failure w/2 */ /* n=no data, i=data in, o=data out, e=bad error state */ char states[9][16] = { /* sn si so se fn fi fo fe Fn Fi Fo Fe Qn Qi Qo Qe*/ /* 0start */ { 1, 1, 1, 17, 1, 1, 1, 17, 1, 1, 1, 17, 1, 1, 1, 17}, /* 1busfree */ { 2, 2, 2, 17, 1, 1, 1, 17, 1, 1, 1, 17, 8, 8, 8, 17}, /* 2select */ { 3, 3, 3, 17, 2, 2, 2, 17, 2, 2, 2, 17, 8, 8, 8, 17}, /* 3command */ { 6, 4, 5, 17, 3, 3, 3, 17, 3, 3, 3, 17, 8, 8, 8, 17}, /* 4datain */ {17, 6, 17, 17, 17, 4, 17, 17, 17, 4, 17, 17, 8, 8, 8, 17}, /* 5dataout */ {17, 17, 6, 17, 17, 17, 5, 17, 17, 17, 5, 17, 8, 8, 8, 17}, /* 6status */ { 7, 7, 7, 17, 6, 6, 6, 17, 6, 6, 6, 17, 8, 8, 8, 17}, /* 7message */ {16, 16, 16, 17, 7, 7, 7, 17, 7, 7, 7, 17, 8, 8, 8, 17}, /* 8error */ { 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17} }; @//E*O*F scsi_vars.h// chmod u=rw,g=rw,o=rw scsi_vars.h echo x - scsimon.c sed 's/^@//' > "scsimon.c" <<'@//E*O*F scsimon.c//' /* @(#)scsimon.c 1.0 ****************************************************************** * Copyright (c) 1990, Marine Systems Engineering Laboratory * * Use, modification, or distribution of this software is * * permitted only with express permission of MSEL. * ****************************************************************** Author(s): Roger Gonzalez Modification History: ******************************************************************/ /* This program monitors the SCSI bus, and displays interesting information */ /* by highlighting bits that are turned on. The NCR5380 documentation is a */ /* must-read. Note that a great deal of space is taken up doing termcap */ /* and argument decoding stuff. The code is ugly, but it runs purty :-) */ /* The command line termcap options were sucked in from a different program */ /* and are thus bordering on overkill. Believe me, if your terminal can */ /* highlight, this program can do it. */ #include <stdio.h> #include <string.h> #include <termcap.h> #include "../include/scsi.h" #include "/usr/usr1/include/iv3273.h" #define NORMAL 0 #define HILITE 1 char termtype[10]; char *temp; char *hilite[2]; char bp[1024]; char capbuf[512]; char *area; byte drawstate; setdrawmode(state) byte state; { if (state == drawstate) return; else { printf("%s", hilite[state]); drawstate = state; } } prstr(string, chkbyte, bit) char *string; byte chkbyte; byte bit; { byte c, res; for (c = 0; c <= 7; c++) { res = 1 << (7 - c); if ((chkbyte & res) == res) { setdrawmode(HILITE); putchar(string[c]); } else { setdrawmode(NORMAL); putchar(string[c]); } } } main(argc, argv) int argc; char *argv[]; { char inputfile[80]; char outputfile[80]; ncr5380_rd *sread; byte init, targ, s1, s2, mode, indata, outdata; byte oldinit, oldtarg, olds1, olds2, oldmode, oldindata, oldoutdata; oldinit = oldtarg = olds1 = olds2 = oldmode = oldindata = oldoutdata = 0x00; if (parse_args("bdfhrsuvx", argc, argv, inputfile, outputfile) != 0) { fprintf(stderr, "usage: scsimon [-bdfhrsuv]\n"); exit(1); } if (!on('s') && !on('b') && !on('d') && !on('f') && !on('u')) turn_on("s"); if (on('x')) sread = (ncr5380_rd *) IV3273_U; else sread = (ncr5380_rd *) IV3273; area = capbuf; if (*strcpy(termtype, getenv("TERM")) == NULL) { fprintf(stderr, "%s: TERM not set.\n", argv[0]); exit(1); } else { if (tgetent(bp, termtype) != 1) { fprintf(stderr, "%s: terminal '%s' not found.\n", argv[0], termtype); exit(1); } if (on('f')) { if (((hilite[HILITE] = tgetstr("mb", &area)) == NULL) || ((hilite[NORMAL] = tgetstr("me", &area)) == NULL)) { fprintf(stderr, "%s: your terminal can't flash.\n", argv[0]); exit(1); } } if (on('b')) { if (((hilite[HILITE] = tgetstr("md", &area)) == NULL) || ((hilite[NORMAL] = tgetstr("me", &area)) == NULL)) { fprintf(stderr, "%s: your terminal can't display bold.\n", argv[0]); exit(1); } } if (on('d')) { if (((hilite[HILITE] = tgetstr("mh", &area)) == NULL) || ((hilite[NORMAL] = tgetstr("me", &area)) == NULL)) { fprintf(stderr, "%s: your terminal can't display dim.\n", argv[0]); exit(1); } } if (on('u')) { if (((hilite[HILITE] = tgetstr("us", &area)) == NULL) || ((hilite[NORMAL] = tgetstr("ue", &area)) == NULL)) { fprintf(stderr, "%s: your terminal can't underline.\n", argv[0]); exit(1); } if (tgetnum("ug") != -1) { fprintf(stderr, "%s: your terminal leaves magic underline cookies!\n", argv[0]); exit(1); } } if (on('s')) { if (((hilite[HILITE] = tgetstr("so", &area)) == NULL) || ((hilite[NORMAL] = tgetstr("se", &area)) == NULL)) { fprintf(stderr, "%s: your terminal can't standout.\n", argv[0]); exit(1); } if (tgetnum("sg") != -1) { fprintf(stderr, "%s: your terminal leaves magic standout cookies!\n", argv[0]); exit(1); } } if (on('r')) { hilite[2] = hilite[HILITE]; hilite[HILITE] = hilite[NORMAL]; hilite[NORMAL] = hilite[2]; } } if (on('v')) { printf("scsimon v1.0 - R. Gonzalez 10/89\n"); } drawstate = HILITE; setdrawmode(NORMAL); if (phys(0, 0xfc0000, 0x40000, 0xfffc0000) != 0) { fprintf(stderr, "%s: must be root to access physical memory.\n", argv[0]); exit(1); } while(1) { oldinit = init; oldtarg = targ; olds1 = s1; olds2 = s2; oldmode = mode; oldindata = indata; oldoutdata = outdata; init = sread->init_cmd; targ = sread->target_cmd; s1 = sread->status_1; s2 = sread->status_2; mode = sread->mode; if (((oldinit^init)|(oldtarg^targ)|(olds1^s1)|(olds2^s2)| (oldmode^mode)) != 0x00) { if ((mode & 0x40) == 0x00) { setdrawmode(NORMAL); printf("M(I) IC("); } else { printf("M("); setdrawmode(HILITE); printf("T"); setdrawmode(NORMAL); printf(") IC("); } prstr("RxxABSxD", init); setdrawmode(NORMAL); printf(") TC("); prstr("xxxxRMCI", targ); setdrawmode(NORMAL); printf(") S1("); prstr("RBRMCISD", s1); setdrawmode(NORMAL); printf(") S2("); prstr("xxPIMBxA", s2); setdrawmode(NORMAL); /* printf(") ID(%02X) OD(%02X) ", indata, outdata);*/ printf(") "); switch((s1 >> 2) & 0x07) { case 0: {printf("dataout\n"); break;} case 1: {printf("datain \n"); break;} case 2: {printf("command\n"); break;} case 3: {printf("status \n"); break;} case 6: {printf("messout\n"); break;} case 7: {printf("messin \n"); break;} default:{printf(".......\n"); break;} } } } } @//E*O*F scsimon.c// chmod u=rw,g=rw,o=rw scsimon.c exit 0 -- UUCP: ..!uunet!unhd!rg | USPS: Marine Systems Engineering Laboratory BITNET: r_gonzalez at unhh | University of New Hampshire PHONE: (603) 862-4600 | Marine Programs Building FAX: (603) 862-4399 | Durham, NH 03824-3525