diff options
author | se <se@FreeBSD.org> | 1994-09-01 02:01:45 +0000 |
---|---|---|
committer | se <se@FreeBSD.org> | 1994-09-01 02:01:45 +0000 |
commit | c920f621ff3d184bf420ab8fa035f252bd5c7e84 (patch) | |
tree | 81057aee708a6ca7aa1cbff457dcf7eb0635424c | |
parent | 6f4f06c23c5c38d0d280e37793fbcea5ff2a6924 (diff) | |
download | FreeBSD-src-c920f621ff3d184bf420ab8fa035f252bd5c7e84.zip FreeBSD-src-c920f621ff3d184bf420ab8fa035f252bd5c7e84.tar.gz |
Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de>
Merged in changes required for NetBSD support (by mycroft@gnu.ai.mit.edu)
and support for multiple NCR chips.
-rw-r--r-- | sys/i386/pci/ncr.c | 286 | ||||
-rw-r--r-- | sys/i386/pci/ncr_reg.h | 14 | ||||
-rw-r--r-- | sys/i386/pci/ncrstat.c | 14 | ||||
-rw-r--r-- | sys/pci/ncr.c | 286 |
4 files changed, 523 insertions, 77 deletions
diff --git a/sys/i386/pci/ncr.c b/sys/i386/pci/ncr.c index aa9384f..42817aa 100644 --- a/sys/i386/pci/ncr.c +++ b/sys/i386/pci/ncr.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: ncr.c,v 2.0.0.12 94/08/18 23:02:22 wolf Exp $ +** $Id: ncr.c,v 2.0.0.16 94/08/29 19:33:12 wolf Exp $ ** ** Device driver for the NCR 53C810 PCI-SCSI-Controller. ** @@ -44,6 +44,25 @@ **------------------------------------------------------------------------- ** ** $Log: ncr.c,v $ +** Revision 2.0.0.16 94/08/29 19:33:12 wolf +** Typo removed. :-( +** +** Revision 2.0.0.15 94/08/27 20:10:12 wolf +** New: ncr_lookup(). +** Determine special flags by device name. +** New user commands: WIDE and FLAG +** New: tracing of commands on a per target base. +** +** Revision 2.0.0.14 94/08/25 22:48:52 wolf +** New DEBUG_RESTART. +** treatment field in struct tcb for silly devices. +** repetition of busy-getcc removed. +** --> CR_NOMSG set for target 6 <-- has to be removed. +** +** Revision 2.0.0.13 94/08/21 19:27:51 wolf +** Special handling for Wangdat tape: +** if getcc results with busy, try again without startup message. +** ** Revision 2.0.0.12 94/08/18 23:02:22 wolf ** ATN cleared after send of multibyte message. ** ncr_msgout moved into struct ncb field lastmsg. @@ -276,6 +295,7 @@ #define DEBUG_TAGS (0x0400) #define DEBUG_FREEZE (0x0800) #define DEBUG_NODUMP (0x1000) +#define DEBUG_RESTART (0x2000) int ncr_debug = SCSI_NCR_DEBUG; @@ -428,6 +448,8 @@ struct usrcmd { #define UC_SETTAGS 11 #define UC_SETDEBUG 12 #define UC_SETORDER 13 +#define UC_SETWIDE 14 +#define UC_SETFLAG 15 /*========================================================== ** @@ -544,13 +566,20 @@ struct tcb { u_char usrsync; u_char usrtags; + u_char usrwide; + u_char usrflag; + +#define UF_TRACE (0x01) /* ** negotiation of synch transfer and tagged commands + ** and tagging of criminal devices. */ + u_char _1; /* prepared for wide transfers */ + u_char _2; u_short period; - u_char _1; + u_char criminal; /* has to be longword alligned. */ u_char sval; u_char minsync; u_char maxoffs; @@ -688,8 +717,11 @@ struct head { #define scsi_status phys.header.status[1] #define scs2_status phys.header.status[2] #define sync_status phys.header.status[3] -#define parity_errs phys.header.status[4] +#define treatment phys.header.status[4] +#define parity_errs phys.header.status[5] }; + +#define CR_NOMSG (0x01) /*========================================================== ** @@ -1064,7 +1096,8 @@ struct script { ncrcmd msg_out_abort [ 10]; ncrcmd getcc [ 4]; ncrcmd getcc1 [ 5]; - ncrcmd getcc2 [ 35]; + ncrcmd getcc2 [ 36]; + ncrcmd getcc3 [ 12]; ncrcmd badgetcc [ 6]; ncrcmd reselect [ 12]; ncrcmd reselect2 [ 6]; @@ -1104,12 +1137,13 @@ static int ncr_delta (struct timeval * from, struct timeval * to); static void ncr_exception (ncb_p np); static void ncr_free_ccb (ncb_p np, ccb_p cp, int flags); static void ncr_getclock (ncb_p np); -static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l); +static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l); static U_INT32 ncr_info (int unit); static void ncr_init (ncb_p np, char * msg, u_long code); static void ncr_int_ma (ncb_p np); static void ncr_int_sir (ncb_p np); static void ncr_int_sto (ncb_p np); +static u_long ncr_lookup (char* id); static void ncr_min_phys (struct buf *bp); static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp); static void ncb_profile (ncb_p np, ccb_p cp); @@ -1230,7 +1264,7 @@ static u_long getirr (void) static char ident[] = - "\n$Id: ncr.c,v 2.0.0.12 94/08/18 23:02:22 wolf Exp $\n" + "\n$Id: ncr.c,v 2.0.0.16 94/08/29 19:33:12 wolf Exp $\n" "Copyright (c) 1994, Wolfgang Stanglmeier\n"; u_long ncr_version = NCR_VERSION @@ -1324,11 +1358,11 @@ struct scsi_switch ncr_switch = ** **========================================================== ** -** -** +** NADDR generates a reference to a field of the controller data. ** PADDR generates a reference to another part of the script. -** REG generates a reference to a script processor register. -** +** RADDR generates a reference to a script processor register. +** FADDR generates a reference to a script processor register +** with offset. ** **---------------------------------------------------------- */ @@ -1341,6 +1375,7 @@ struct scsi_switch ncr_switch = #define NADDR(label) (RELOC_SOFTC | offsetof(struct ncb, label)) #define PADDR(label) (RELOC_LABEL | offsetof(struct script, label)) #define RADDR(label) (RELOC_REGISTER | REG(label)) +#define FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs))) static struct script script0 = { /*--------------------------< START >-----------------------*/ { @@ -1748,13 +1783,13 @@ static struct script script0 = { ** count it */ SCR_COPY (1), - NADDR (header.status[4]), - RADDR (scratcha), - SCR_REG_REG (scratcha, SCR_ADD, 0x01), + NADDR (header.status[5]), + FADDR (scratcha, 1), + SCR_REG_REG (scratcha, SCR_ADD, 0x01) | SCR_REG_OFS(1), 0, SCR_COPY (1), - RADDR (scratcha), - NADDR (header.status[4]), + FADDR (scratcha, 1), + NADDR (header.status[5]), /* ** Prepare a M_ID_ERROR message ** (initiator detected error). @@ -2309,7 +2344,6 @@ static struct script script0 = { SCR_JUMP, PADDR (no_data), /*>>>*/ - /* ** The CALL jumps to this point. ** Prepare for a RESTORE_POINTER message. @@ -2327,6 +2361,16 @@ static struct script script0 = { PADDR (startpos), RADDR (scratcha), /* + ** If CR_NOMSG is set, select without ATN. + ** and don't send a message. + */ + SCR_COPY (1), + NADDR (header.status[4]), + RADDR (sfbr), + SCR_JUMP ^ IFTRUE (MASK (CR_NOMSG, CR_NOMSG)), + PADDR(getcc3), + + /* ** Then try to connect to the target. ** If we are reselected, special treatment ** of the current job is required before @@ -2334,21 +2378,24 @@ static struct script script0 = { */ SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), PADDR(badgetcc), - SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)), - 0, + /* + ** save target id. + */ SCR_FROM_REG (sdid), 0, SCR_TO_REG (ctest0), 0, /* - ** and send the IDENTIFY and a SDTM message. + ** Send the IDENTIFY and a SDTM message. + ** In case of short transfer, remove ATN. */ SCR_MOVE_TBL ^ SCR_MSG_OUT, offsetof (struct dsb, smsg2), - SCR_JUMPR ^ IFTRUE ( WHEN (SCR_MSG_OUT) ), - -16, SCR_CLR (SCR_ATN), 0, + /* + ** save the first byte of the message. + */ SCR_COPY (1), RADDR (sfbr), NADDR (lastmsg), @@ -2360,6 +2407,38 @@ static struct script script0 = { SCR_JUMP, PADDR (prepare2), +}/*-------------------------< GETCC3 >----------------------*/,{ + /* + ** Try to connect to the target. + ** If we are reselected, special treatment + ** of the current job is required before + ** accepting the reselection. + ** + ** Silly target won't accept a message. + ** Select without ATN. + */ + SCR_SEL_TBL ^ offsetof (struct dsb, select), + PADDR(badgetcc), + /* + ** save target id. + */ + SCR_FROM_REG (sdid), + 0, + SCR_TO_REG (ctest0), + 0, + /* + ** Force error if selection timeout + */ + SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)), + 0, + /* + ** don't negotiate. + */ + SCR_CLR (SCR_CARRY), + 0, + SCR_JUMP, + PADDR (prepare2), + }/*------------------------< BADGETCC >---------------------*/,{ /* ** If SIGP was set, clear it and try again. @@ -3071,7 +3150,7 @@ static int ncr_attach (pcici_t config_id) ncr_name (np)); DELAY (1000000); #endif - printf ("%s scanning for targets 0..%d ($Revision: 2.0.0.12 $%x$)\n", + printf ("%s scanning for targets 0..%d ($Revision: 2.0.0.16 $%x$)\n", ncr_name (np), MAX_TARGET-1, SCSI_NCR_DEBUG); /* @@ -3563,6 +3642,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) cp->scsi_status = S_ILLEGAL; cp->sync_status = np->target[xp->TARGET].sval; cp->host_status = startcode; + cp->treatment = np->target[xp->TARGET].criminal; cp->parity_errs = 0; /*---------------------------------------------------- @@ -3731,7 +3811,6 @@ void ncr_complete (ncb_p np, ccb_p cp) lp = tp->lp[xp->LUN]; /* - ** @PARITY@ ** Check for parity errors. */ @@ -3774,6 +3853,15 @@ void ncr_complete (ncb_p np, ccb_p cp) sizeof (tp->inqdata)); ncr_setmaxtags (tp, tp->usrtags); tp->period=0; + + /* + ** lookup the device in the speciality table. + */ + tp->criminal = ncr_lookup ((char*) &tp->inqdata[0]); + if (tp->criminal) { + PRINT_ADDR(xp); + printf ("misfeature=%x.\n", tp->criminal); + }; }; if (!tp->sval) { @@ -3858,6 +3946,45 @@ void ncr_complete (ncb_p np, ccb_p cp) xp->flags |= ITSDONE; /* + ** trace output + */ + + if (tp->usrflag & UF_TRACE) { + u_char * p; + int i; + PRINT_ADDR(xp); + printf (" CMD:"); +#ifdef ANCIENT + p = (u_char*) &cp->cmd.opcode; +#else /* ANCIENT */ + p = (u_char*) &xp->cmd->opcode; +#endif /* ANCIENT */ + for (i=0; i<xp->cmdlen; i++) printf (" %x", *p++); + + if (cp->host_status==HS_COMPLETE) { + switch (cp->scsi_status) { + case S_GOOD: + printf (" GOOD"); + break; + case S_CHECK_COND: + printf (" SENSE:"); + p = (u_char*) &xp->sense; +#ifdef ANCIENT + for (i=0; i<sizeof(xp->sense); i++) +#else /* ANCIENT */ + for (i=0; i<xp->req_sense_length; i++) +#endif /* ANCIENT */ + printf (" %x", *p++); + break; + default: + printf (" STAT: %x\n", cp->scsi_status); + break; + }; + } else printf (" HOSTERROR: %x", cp->host_status); + printf ("\n"); + }; + + /* ** Free this ccb */ ncr_free_ccb (np, cp, xp->flags); @@ -4182,6 +4309,22 @@ static void ncr_usercmd (ncb_p np) np->order = np->user.data; break; + case UC_SETWIDE: + for (t=0; t<MAX_TARGET; t++) { + if (!((np->user.target>>t)&1)) continue; + tp = &np->target[t]; + tp->usrwide = np->user.data; + tp->_1 = 0; + }; + break; + + case UC_SETFLAG: + for (t=0; t<MAX_TARGET; t++) { + if (!((np->user.target>>t)&1)) continue; + tp = &np->target[t]; + tp->usrflag = np->user.data; + }; + break; } np->user.cmd=0; } @@ -4902,50 +5045,72 @@ void ncr_int_sir (ncb_p np) **-------------------------------------------------------------------- */ - case 1: /* + case 1: /*------------------------------------------ ** Script processor is idle. ** Look for interrupted "check cond" + **------------------------------------------ */ - printf ("%s: int#%d",ncr_name (np),num); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) + printf ("%s: int#%d",ncr_name (np),num); +#endif /* SCSI_NCR_DEBUG */ cp = (ccb_p) 0; for (i=0; i<MAX_TARGET; i++) { - printf (" t%d", i); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf (" t%d", i); +#endif /* SCSI_NCR_DEBUG */ tp = &np->target[i]; - printf ("+"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf ("+"); +#endif /* SCSI_NCR_DEBUG */ cp = tp->hold_cp; if (!cp) continue; - printf ("+"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf ("+"); +#endif /* SCSI_NCR_DEBUG */ if ((cp->host_status==HS_BUSY) && (cp->scsi_status==S_CHECK_COND) && (cp->scs2_status==S_ILLEGAL)) break; - printf ("- (remove)"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf ("- (remove)"); +#endif /* SCSI_NCR_DEBUG */ tp->hold_cp = cp = (ccb_p) 0; }; if (cp) { - printf ("+ restart job ..\n"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) + printf ("+ restart job ..\n"); +#endif /* SCSI_NCR_DEBUG */ OUTL (nc_dsa, vtophys (&cp->phys)); OUTL (nc_dsp, vtophys (&np->script->getcc)); return; }; - + /* ** no job, resume normal processing */ - printf (" -- remove trap\n"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf (" -- remove trap\n"); +#endif /* SCSI_NCR_DEBUG */ np->script->start0[0] = SCR_INT ^ IFFALSE (0); break; - - case 2: /* + + + case 2: /*------------------------------------------- ** While trying to reselect for ** getting the condition code, ** a target reselected us. + **------------------------------------------- */ PRINT_ADDR(cp->xfer); - printf ("in getcc reselect by t%d.\n", - INB(nc_ssid)&7); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) + printf ("in getcc reselect by t%d.\n", + INB(nc_ssid)&7); +#endif /* SCSI_NCR_DEBUG */ /* ** Mark this job @@ -5640,6 +5805,55 @@ static void ncb_profile (ncb_p np, ccb_p cp) /*========================================================== ** +** +** Device lookup. +** +** +**========================================================== +*/ + +struct table_entry { + char * manufacturer; + char * model; + char * version; + u_long info; +}; + +static struct table_entry device_tab[] = +{ + {"WangDAT", "Model 2600", "01.7", CR_NOMSG}, + {"WangDAT", "Model 3200", "02.2", CR_NOMSG}, + {"", "", "", 0} /* catch all: must be last entry. */ +}; + +static u_long ncr_lookup(char * id) +{ + struct table_entry * p = device_tab; + char *d, *r, c; + + for (;;p++) { + + d = id+8; + r = p->manufacturer; + while (c=*r++) if (c!=*d++) break; + if (c) continue; + + d = id+16; + r = p->model; + while (c=*r++) if (c!=*d++) break; + if (c) continue; + + d = id+32; + r = p->version; + while (c=*r++) if (c!=*d++) break; + if (c) continue; + + return (p->info); + } +} + +/*========================================================== +** ** Determine the ncr's clock frequency. ** This is important for the negotiation ** of the synchronous transfer rate. diff --git a/sys/i386/pci/ncr_reg.h b/sys/i386/pci/ncr_reg.h index ac563a4..f76cdba 100644 --- a/sys/i386/pci/ncr_reg.h +++ b/sys/i386/pci/ncr_reg.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: ncr_reg.h,v 2.0.0.4 94/08/09 23:10:10 wolf Exp $ +** $Id: ncr_reg.h,v 2.0.0.5 94/08/25 22:51:04 wolf Exp $ ** ** Device driver for the NCR 53C810 PCI-SCSI-Controller. ** @@ -44,6 +44,9 @@ **------------------------------------------------------------------------- ** ** $Log: ncr_reg.h,v $ +** Revision 2.0.0.5 94/08/25 22:51:04 wolf +** New SCR_REG_OFS() macro. +** ** Revision 2.0.0.4 94/08/09 23:10:10 wolf ** new message. ** @@ -365,14 +368,17 @@ struct scr_tblsel { **----------------------------------------------------------- */ +#define SCR_REG_OFS(ofs) ((ofs) << 16ul) + #define SCR_SFBR_REG(reg,op,data) \ - (0x68000000 | (REG(reg) << 16ul) | (op) | ((data)<<8ul)) + (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | ((data)<<8ul)) #define SCR_REG_SFBR(reg,op,data) \ - (0x70000000 | (REG(reg) << 16ul) | (op) | ((data)<<8ul)) + (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | ((data)<<8ul)) #define SCR_REG_REG(reg,op,data) \ - (0x78000000 | (REG(reg) << 16ul) | (op) | ((data)<<8ul)) + (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | ((data)<<8ul)) + #define SCR_LOAD 0x00000000 #define SCR_SHL 0x01000000 diff --git a/sys/i386/pci/ncrstat.c b/sys/i386/pci/ncrstat.c index 0e1a89d..f173938 100644 --- a/sys/i386/pci/ncrstat.c +++ b/sys/i386/pci/ncrstat.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: ncrstat.c,v 2.0.0.6 94/08/10 19:36:32 wolf Exp $ +** $Id: ncrstat.c,v 2.0.0.7 94/08/27 20:13:42 wolf Exp $ ** ** Utility for NCR 53C810 device driver. ** @@ -45,6 +45,10 @@ **------------------------------------------------------------------------- ** ** $Log: ncrstat.c,v $ +** Revision 2.0.0.7 94/08/27 20:13:42 wolf +** New: "-sflags=xxx" +** flags=1: command tracing. +** ** Revision 2.0.0.6 94/08/10 19:36:32 wolf ** Multiple "-s" options per line supported. ** Ported to NetBSD. @@ -767,6 +771,14 @@ void do_set (char * arg) }; }; + if (!strncmp(arg, "flags=", 6)) { + u_char t = strtoul (arg+6, (char**)0, 0); + if (t<=0xff) { + user.data = t; + user.cmd = UC_SETFLAG; + }; + }; + if (!strncmp(arg, "debug=", 6)) { user.data = strtoul (arg+6, (char**)0, 0); user.cmd = UC_SETDEBUG; diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c index aa9384f..42817aa 100644 --- a/sys/pci/ncr.c +++ b/sys/pci/ncr.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: ncr.c,v 2.0.0.12 94/08/18 23:02:22 wolf Exp $ +** $Id: ncr.c,v 2.0.0.16 94/08/29 19:33:12 wolf Exp $ ** ** Device driver for the NCR 53C810 PCI-SCSI-Controller. ** @@ -44,6 +44,25 @@ **------------------------------------------------------------------------- ** ** $Log: ncr.c,v $ +** Revision 2.0.0.16 94/08/29 19:33:12 wolf +** Typo removed. :-( +** +** Revision 2.0.0.15 94/08/27 20:10:12 wolf +** New: ncr_lookup(). +** Determine special flags by device name. +** New user commands: WIDE and FLAG +** New: tracing of commands on a per target base. +** +** Revision 2.0.0.14 94/08/25 22:48:52 wolf +** New DEBUG_RESTART. +** treatment field in struct tcb for silly devices. +** repetition of busy-getcc removed. +** --> CR_NOMSG set for target 6 <-- has to be removed. +** +** Revision 2.0.0.13 94/08/21 19:27:51 wolf +** Special handling for Wangdat tape: +** if getcc results with busy, try again without startup message. +** ** Revision 2.0.0.12 94/08/18 23:02:22 wolf ** ATN cleared after send of multibyte message. ** ncr_msgout moved into struct ncb field lastmsg. @@ -276,6 +295,7 @@ #define DEBUG_TAGS (0x0400) #define DEBUG_FREEZE (0x0800) #define DEBUG_NODUMP (0x1000) +#define DEBUG_RESTART (0x2000) int ncr_debug = SCSI_NCR_DEBUG; @@ -428,6 +448,8 @@ struct usrcmd { #define UC_SETTAGS 11 #define UC_SETDEBUG 12 #define UC_SETORDER 13 +#define UC_SETWIDE 14 +#define UC_SETFLAG 15 /*========================================================== ** @@ -544,13 +566,20 @@ struct tcb { u_char usrsync; u_char usrtags; + u_char usrwide; + u_char usrflag; + +#define UF_TRACE (0x01) /* ** negotiation of synch transfer and tagged commands + ** and tagging of criminal devices. */ + u_char _1; /* prepared for wide transfers */ + u_char _2; u_short period; - u_char _1; + u_char criminal; /* has to be longword alligned. */ u_char sval; u_char minsync; u_char maxoffs; @@ -688,8 +717,11 @@ struct head { #define scsi_status phys.header.status[1] #define scs2_status phys.header.status[2] #define sync_status phys.header.status[3] -#define parity_errs phys.header.status[4] +#define treatment phys.header.status[4] +#define parity_errs phys.header.status[5] }; + +#define CR_NOMSG (0x01) /*========================================================== ** @@ -1064,7 +1096,8 @@ struct script { ncrcmd msg_out_abort [ 10]; ncrcmd getcc [ 4]; ncrcmd getcc1 [ 5]; - ncrcmd getcc2 [ 35]; + ncrcmd getcc2 [ 36]; + ncrcmd getcc3 [ 12]; ncrcmd badgetcc [ 6]; ncrcmd reselect [ 12]; ncrcmd reselect2 [ 6]; @@ -1104,12 +1137,13 @@ static int ncr_delta (struct timeval * from, struct timeval * to); static void ncr_exception (ncb_p np); static void ncr_free_ccb (ncb_p np, ccb_p cp, int flags); static void ncr_getclock (ncb_p np); -static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l); +static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l); static U_INT32 ncr_info (int unit); static void ncr_init (ncb_p np, char * msg, u_long code); static void ncr_int_ma (ncb_p np); static void ncr_int_sir (ncb_p np); static void ncr_int_sto (ncb_p np); +static u_long ncr_lookup (char* id); static void ncr_min_phys (struct buf *bp); static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp); static void ncb_profile (ncb_p np, ccb_p cp); @@ -1230,7 +1264,7 @@ static u_long getirr (void) static char ident[] = - "\n$Id: ncr.c,v 2.0.0.12 94/08/18 23:02:22 wolf Exp $\n" + "\n$Id: ncr.c,v 2.0.0.16 94/08/29 19:33:12 wolf Exp $\n" "Copyright (c) 1994, Wolfgang Stanglmeier\n"; u_long ncr_version = NCR_VERSION @@ -1324,11 +1358,11 @@ struct scsi_switch ncr_switch = ** **========================================================== ** -** -** +** NADDR generates a reference to a field of the controller data. ** PADDR generates a reference to another part of the script. -** REG generates a reference to a script processor register. -** +** RADDR generates a reference to a script processor register. +** FADDR generates a reference to a script processor register +** with offset. ** **---------------------------------------------------------- */ @@ -1341,6 +1375,7 @@ struct scsi_switch ncr_switch = #define NADDR(label) (RELOC_SOFTC | offsetof(struct ncb, label)) #define PADDR(label) (RELOC_LABEL | offsetof(struct script, label)) #define RADDR(label) (RELOC_REGISTER | REG(label)) +#define FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs))) static struct script script0 = { /*--------------------------< START >-----------------------*/ { @@ -1748,13 +1783,13 @@ static struct script script0 = { ** count it */ SCR_COPY (1), - NADDR (header.status[4]), - RADDR (scratcha), - SCR_REG_REG (scratcha, SCR_ADD, 0x01), + NADDR (header.status[5]), + FADDR (scratcha, 1), + SCR_REG_REG (scratcha, SCR_ADD, 0x01) | SCR_REG_OFS(1), 0, SCR_COPY (1), - RADDR (scratcha), - NADDR (header.status[4]), + FADDR (scratcha, 1), + NADDR (header.status[5]), /* ** Prepare a M_ID_ERROR message ** (initiator detected error). @@ -2309,7 +2344,6 @@ static struct script script0 = { SCR_JUMP, PADDR (no_data), /*>>>*/ - /* ** The CALL jumps to this point. ** Prepare for a RESTORE_POINTER message. @@ -2327,6 +2361,16 @@ static struct script script0 = { PADDR (startpos), RADDR (scratcha), /* + ** If CR_NOMSG is set, select without ATN. + ** and don't send a message. + */ + SCR_COPY (1), + NADDR (header.status[4]), + RADDR (sfbr), + SCR_JUMP ^ IFTRUE (MASK (CR_NOMSG, CR_NOMSG)), + PADDR(getcc3), + + /* ** Then try to connect to the target. ** If we are reselected, special treatment ** of the current job is required before @@ -2334,21 +2378,24 @@ static struct script script0 = { */ SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), PADDR(badgetcc), - SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)), - 0, + /* + ** save target id. + */ SCR_FROM_REG (sdid), 0, SCR_TO_REG (ctest0), 0, /* - ** and send the IDENTIFY and a SDTM message. + ** Send the IDENTIFY and a SDTM message. + ** In case of short transfer, remove ATN. */ SCR_MOVE_TBL ^ SCR_MSG_OUT, offsetof (struct dsb, smsg2), - SCR_JUMPR ^ IFTRUE ( WHEN (SCR_MSG_OUT) ), - -16, SCR_CLR (SCR_ATN), 0, + /* + ** save the first byte of the message. + */ SCR_COPY (1), RADDR (sfbr), NADDR (lastmsg), @@ -2360,6 +2407,38 @@ static struct script script0 = { SCR_JUMP, PADDR (prepare2), +}/*-------------------------< GETCC3 >----------------------*/,{ + /* + ** Try to connect to the target. + ** If we are reselected, special treatment + ** of the current job is required before + ** accepting the reselection. + ** + ** Silly target won't accept a message. + ** Select without ATN. + */ + SCR_SEL_TBL ^ offsetof (struct dsb, select), + PADDR(badgetcc), + /* + ** save target id. + */ + SCR_FROM_REG (sdid), + 0, + SCR_TO_REG (ctest0), + 0, + /* + ** Force error if selection timeout + */ + SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)), + 0, + /* + ** don't negotiate. + */ + SCR_CLR (SCR_CARRY), + 0, + SCR_JUMP, + PADDR (prepare2), + }/*------------------------< BADGETCC >---------------------*/,{ /* ** If SIGP was set, clear it and try again. @@ -3071,7 +3150,7 @@ static int ncr_attach (pcici_t config_id) ncr_name (np)); DELAY (1000000); #endif - printf ("%s scanning for targets 0..%d ($Revision: 2.0.0.12 $%x$)\n", + printf ("%s scanning for targets 0..%d ($Revision: 2.0.0.16 $%x$)\n", ncr_name (np), MAX_TARGET-1, SCSI_NCR_DEBUG); /* @@ -3563,6 +3642,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) cp->scsi_status = S_ILLEGAL; cp->sync_status = np->target[xp->TARGET].sval; cp->host_status = startcode; + cp->treatment = np->target[xp->TARGET].criminal; cp->parity_errs = 0; /*---------------------------------------------------- @@ -3731,7 +3811,6 @@ void ncr_complete (ncb_p np, ccb_p cp) lp = tp->lp[xp->LUN]; /* - ** @PARITY@ ** Check for parity errors. */ @@ -3774,6 +3853,15 @@ void ncr_complete (ncb_p np, ccb_p cp) sizeof (tp->inqdata)); ncr_setmaxtags (tp, tp->usrtags); tp->period=0; + + /* + ** lookup the device in the speciality table. + */ + tp->criminal = ncr_lookup ((char*) &tp->inqdata[0]); + if (tp->criminal) { + PRINT_ADDR(xp); + printf ("misfeature=%x.\n", tp->criminal); + }; }; if (!tp->sval) { @@ -3858,6 +3946,45 @@ void ncr_complete (ncb_p np, ccb_p cp) xp->flags |= ITSDONE; /* + ** trace output + */ + + if (tp->usrflag & UF_TRACE) { + u_char * p; + int i; + PRINT_ADDR(xp); + printf (" CMD:"); +#ifdef ANCIENT + p = (u_char*) &cp->cmd.opcode; +#else /* ANCIENT */ + p = (u_char*) &xp->cmd->opcode; +#endif /* ANCIENT */ + for (i=0; i<xp->cmdlen; i++) printf (" %x", *p++); + + if (cp->host_status==HS_COMPLETE) { + switch (cp->scsi_status) { + case S_GOOD: + printf (" GOOD"); + break; + case S_CHECK_COND: + printf (" SENSE:"); + p = (u_char*) &xp->sense; +#ifdef ANCIENT + for (i=0; i<sizeof(xp->sense); i++) +#else /* ANCIENT */ + for (i=0; i<xp->req_sense_length; i++) +#endif /* ANCIENT */ + printf (" %x", *p++); + break; + default: + printf (" STAT: %x\n", cp->scsi_status); + break; + }; + } else printf (" HOSTERROR: %x", cp->host_status); + printf ("\n"); + }; + + /* ** Free this ccb */ ncr_free_ccb (np, cp, xp->flags); @@ -4182,6 +4309,22 @@ static void ncr_usercmd (ncb_p np) np->order = np->user.data; break; + case UC_SETWIDE: + for (t=0; t<MAX_TARGET; t++) { + if (!((np->user.target>>t)&1)) continue; + tp = &np->target[t]; + tp->usrwide = np->user.data; + tp->_1 = 0; + }; + break; + + case UC_SETFLAG: + for (t=0; t<MAX_TARGET; t++) { + if (!((np->user.target>>t)&1)) continue; + tp = &np->target[t]; + tp->usrflag = np->user.data; + }; + break; } np->user.cmd=0; } @@ -4902,50 +5045,72 @@ void ncr_int_sir (ncb_p np) **-------------------------------------------------------------------- */ - case 1: /* + case 1: /*------------------------------------------ ** Script processor is idle. ** Look for interrupted "check cond" + **------------------------------------------ */ - printf ("%s: int#%d",ncr_name (np),num); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) + printf ("%s: int#%d",ncr_name (np),num); +#endif /* SCSI_NCR_DEBUG */ cp = (ccb_p) 0; for (i=0; i<MAX_TARGET; i++) { - printf (" t%d", i); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf (" t%d", i); +#endif /* SCSI_NCR_DEBUG */ tp = &np->target[i]; - printf ("+"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf ("+"); +#endif /* SCSI_NCR_DEBUG */ cp = tp->hold_cp; if (!cp) continue; - printf ("+"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf ("+"); +#endif /* SCSI_NCR_DEBUG */ if ((cp->host_status==HS_BUSY) && (cp->scsi_status==S_CHECK_COND) && (cp->scs2_status==S_ILLEGAL)) break; - printf ("- (remove)"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf ("- (remove)"); +#endif /* SCSI_NCR_DEBUG */ tp->hold_cp = cp = (ccb_p) 0; }; if (cp) { - printf ("+ restart job ..\n"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) + printf ("+ restart job ..\n"); +#endif /* SCSI_NCR_DEBUG */ OUTL (nc_dsa, vtophys (&cp->phys)); OUTL (nc_dsp, vtophys (&np->script->getcc)); return; }; - + /* ** no job, resume normal processing */ - printf (" -- remove trap\n"); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) printf (" -- remove trap\n"); +#endif /* SCSI_NCR_DEBUG */ np->script->start0[0] = SCR_INT ^ IFFALSE (0); break; - - case 2: /* + + + case 2: /*------------------------------------------- ** While trying to reselect for ** getting the condition code, ** a target reselected us. + **------------------------------------------- */ PRINT_ADDR(cp->xfer); - printf ("in getcc reselect by t%d.\n", - INB(nc_ssid)&7); +#ifdef NCR_DEBUG + if (ncr_debug & DEBUG_RESTART) + printf ("in getcc reselect by t%d.\n", + INB(nc_ssid)&7); +#endif /* SCSI_NCR_DEBUG */ /* ** Mark this job @@ -5640,6 +5805,55 @@ static void ncb_profile (ncb_p np, ccb_p cp) /*========================================================== ** +** +** Device lookup. +** +** +**========================================================== +*/ + +struct table_entry { + char * manufacturer; + char * model; + char * version; + u_long info; +}; + +static struct table_entry device_tab[] = +{ + {"WangDAT", "Model 2600", "01.7", CR_NOMSG}, + {"WangDAT", "Model 3200", "02.2", CR_NOMSG}, + {"", "", "", 0} /* catch all: must be last entry. */ +}; + +static u_long ncr_lookup(char * id) +{ + struct table_entry * p = device_tab; + char *d, *r, c; + + for (;;p++) { + + d = id+8; + r = p->manufacturer; + while (c=*r++) if (c!=*d++) break; + if (c) continue; + + d = id+16; + r = p->model; + while (c=*r++) if (c!=*d++) break; + if (c) continue; + + d = id+32; + r = p->version; + while (c=*r++) if (c!=*d++) break; + if (c) continue; + + return (p->info); + } +} + +/*========================================================== +** ** Determine the ncr's clock frequency. ** This is important for the negotiation ** of the synchronous transfer rate. |