From 24ea9e632e6d68fb03d0ef389ce92815a9eaf448 Mon Sep 17 00:00:00 2001 From: se Date: Mon, 28 Jul 1997 21:32:05 +0000 Subject: Add support for loading the SCRIPTS microcode into the on-chip RAM of the Symbios 53c825A, 53c875 and 53c895 SCSI chips. Submitted by: Gerard Roudier --- sys/pci/ncr.c | 1841 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 1019 insertions(+), 822 deletions(-) (limited to 'sys/pci') diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c index 3be6a0d..1a0a1e81 100644 --- a/sys/pci/ncr.c +++ b/sys/pci/ncr.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: ncr.c,v 1.99 1997/07/18 19:33:56 se Exp $ +** $Id: ncr.c,v 1.100 1997/07/25 20:45:05 se Exp $ ** ** Device driver for the NCR 53C810 PCI-SCSI-Controller. ** @@ -311,6 +311,10 @@ #define OUTW(r, val) outw (np->port+offsetof(struct ncr_reg,r),(val)) #define OUTL(r, val) outl (np->port+offsetof(struct ncr_reg,r),(val)) +#define INB_OFF(o) inb (np->port + (o)) +#define INW_OFF(o) inw (np->port + (o)) +#define INL_OFF(o) inl (np->port + (o)) + #else #define INB(r) (np->reg->r) @@ -321,6 +325,10 @@ #define OUTW(r, val) np->reg->r = (val) #define OUTL(r, val) np->reg->r = (val) +#define INB_OFF(o) *( ((u_char *) np->reg) + (o) ) +#define INW_OFF(o) *((u_short *) ( ((u_char *) np->reg) + (o)) ) +#define INL_OFF(o) *((u_long *) ( ((u_char *) np->reg) + (o)) ) + #endif /* @@ -1023,6 +1031,9 @@ struct ncb { vm_offset_t vaddr; vm_offset_t paddr; + vm_offset_t vaddr2; + vm_offset_t paddr2; + /* ** pointer to the chip's registers. */ @@ -1030,14 +1041,22 @@ struct ncb { struct ncr_reg* reg; /* - ** A copy of the script, relocated for this ncb. + ** A copy of the scripts, relocated for this ncb. + */ + struct script *script0; + struct scripth *scripth0; + + /* + ** Scripts instance virtual address. */ struct script *script; + struct scripth *scripth; /* - ** Physical address of this instance of ncb->script + ** Scripts instance physical address. */ u_long p_script; + u_long p_scripth; /* ** The SCSI address of the host adapter. @@ -1165,6 +1184,7 @@ struct ncb { }; #define NCB_SCRIPT_PHYS(np,lbl) (np->p_script + offsetof (struct script, lbl)) +#define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth,lbl)) /*========================================================== ** @@ -1187,12 +1207,15 @@ struct ncb { **---------------------------------------------------------- */ +/* +** Script fragments which are loaded into the on-board RAM +** of 825A, 875 and 895 chips. +*/ struct script { ncrcmd start [ 7]; ncrcmd start0 [ 2]; ncrcmd start1 [ 3]; ncrcmd startpos [ 1]; - ncrcmd tryloop [MAX_START*5+2]; ncrcmd trysel [ 8]; ncrcmd skip [ 8]; ncrcmd skip2 [ 3]; @@ -1210,14 +1233,6 @@ struct script { ncrcmd status [ 27]; ncrcmd msg_in [ 26]; ncrcmd msg_bad [ 6]; - ncrcmd msg_parity [ 6]; - ncrcmd msg_reject [ 8]; - ncrcmd msg_ign_residue [ 32]; - ncrcmd msg_extended [ 18]; - ncrcmd msg_ext_2 [ 18]; - ncrcmd msg_wdtr [ 27]; - ncrcmd msg_ext_3 [ 18]; - ncrcmd msg_sdtr [ 27]; ncrcmd complete [ 13]; ncrcmd cleanup [ 12]; ncrcmd cleanup0 [ 11]; @@ -1229,15 +1244,6 @@ struct script { ncrcmd disconnect1 [ 23]; ncrcmd msg_out [ 9]; ncrcmd msg_out_done [ 7]; - ncrcmd msg_out_abort [ 10]; - ncrcmd getcc [ 4]; - ncrcmd getcc1 [ 5]; -#ifdef NCR_GETCC_WITHMSG - ncrcmd getcc2 [ 33]; -#else - ncrcmd getcc2 [ 14]; -#endif - ncrcmd getcc3 [ 10]; ncrcmd badgetcc [ 6]; ncrcmd reselect [ 8]; ncrcmd reselect1 [ 8]; @@ -1247,6 +1253,30 @@ struct script { ncrcmd resel_tag [ 24]; ncrcmd data_in [MAX_SCATTER * 4 + 7]; ncrcmd data_out [MAX_SCATTER * 4 + 7]; +}; + +/* +** Script fragments which stay in main memory for all chips. +*/ +struct scripth { + ncrcmd tryloop [MAX_START*5+2]; + ncrcmd msg_parity [ 6]; + ncrcmd msg_reject [ 8]; + ncrcmd msg_ign_residue [ 32]; + ncrcmd msg_extended [ 18]; + ncrcmd msg_ext_2 [ 18]; + ncrcmd msg_wdtr [ 27]; + ncrcmd msg_ext_3 [ 18]; + ncrcmd msg_sdtr [ 27]; + ncrcmd msg_out_abort [ 10]; + ncrcmd getcc [ 4]; + ncrcmd getcc1 [ 5]; +#ifdef NCR_GETCC_WITHMSG + ncrcmd getcc2 [ 33]; +#else + ncrcmd getcc2 [ 14]; +#endif + ncrcmd getcc3 [ 10]; ncrcmd aborttag [ 4]; ncrcmd abort [ 22]; ncrcmd snooptest [ 9]; @@ -1282,8 +1312,8 @@ static void ncr_negotiate (struct ncb* np, struct tcb* tp); static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp); static void ncb_profile (ncb_p np, ccb_p cp); static void ncr_script_copy_and_bind - (struct script * script, ncb_p np); -static void ncr_script_fill (struct script * scr); + (ncb_p np, ncrcmd *src, ncrcmd *dst, int len); +static void ncr_script_fill (struct script * scr, struct scripth *scrh); static int ncr_scatter (struct dsb* phys, vm_offset_t vaddr, vm_size_t datalen); static void ncr_setmaxtags (tcb_p tp, u_long usrtags); @@ -1320,7 +1350,7 @@ static void ncr_attach (pcici_t tag, int unit); static char ident[] = - "\n$Id: ncr.c,v 1.99 1997/07/18 19:33:56 se Exp $\n"; + "\n$Id: ncr.c,v 1.100 1997/07/25 20:45:05 se Exp $\n"; static const u_long ncr_version = NCR_VERSION * 11 + (u_long) sizeof (struct ncb) * 7 @@ -1438,12 +1468,30 @@ static char *ncr_name (ncb_p np) #define RELOC_SOFTC 0x40000000 #define RELOC_LABEL 0x50000000 #define RELOC_REGISTER 0x60000000 +#define RELOC_KVAR 0x70000000 +#define RELOC_LABELH 0x80000000 #define RELOC_MASK 0xf0000000 #define NADDR(label) (RELOC_SOFTC | offsetof(struct ncb, label)) #define PADDR(label) (RELOC_LABEL | offsetof(struct script, label)) +#define PADDRH(label) (RELOC_LABELH | offsetof(struct scripth, label)) #define RADDR(label) (RELOC_REGISTER | REG(label)) #define FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs))) +#define KVAR(which) (RELOC_KVAR | (which)) + +#define KVAR_TIME_TV_SEC (0) +#define KVAR_TIME (1) +#define KVAR_NCR_CACHE (2) + +#define SCRIPT_KVAR_FIRST (0) +#define SCRIPT_KVAR_LAST (3) + +/* + * Kernel variables referenced in the scripts. + * THESE MUST ALL BE ALIGNED TO A 4-BYTE BOUNDARY. + */ +static void *script_kvars[] = + { &time.tv_sec, &time, &ncr_cache }; static struct script script0 = { /*--------------------------< START >-----------------------*/ { @@ -1451,7 +1499,7 @@ static struct script script0 = { ** Claim to be still alive ... */ SCR_COPY (sizeof (((struct ncb *)0)->heartbeat)), - (ncrcmd) &time.tv_sec, + KVAR (KVAR_TIME_TV_SEC), NADDR (heartbeat), /* ** Make data structure address invalid. @@ -1484,32 +1532,7 @@ static struct script script0 = { */ SCR_JUMP, }/*-------------------------< STARTPOS >--------------------*/,{ - PADDR(tryloop), -}/*-------------------------< TRYLOOP >---------------------*/,{ -/* -** Load an entry of the start queue into dsa -** and try to start it by jumping to TRYSEL. -** -** Because the size depends on the -** #define MAX_START parameter, it is filled -** in at runtime. -** -**----------------------------------------------------------- -** -** ##===========< I=0; i=========== -** || SCR_COPY (4), -** || NADDR (squeue[i]), -** || RADDR (dsa), -** || SCR_CALL, -** || PADDR (trysel), -** ##========================================== -** -** SCR_JUMP, -** PADDR(tryloop), -** -**----------------------------------------------------------- -*/ -0 + PADDRH(tryloop), }/*-------------------------< TRYSEL >----------------------*/,{ /* @@ -1695,7 +1718,7 @@ static struct script script0 = { ** Set a time stamp for this selection */ SCR_COPY (sizeof (struct timeval)), - (ncrcmd) &time, + KVAR (KVAR_TIME), NADDR (header.stamp.select), /* ** load the savep (saved pointer) into @@ -1748,7 +1771,7 @@ static struct script script0 = { SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), PADDR (msg_in), SCR_JUMP ^ IFTRUE (DATA (M_REJECT)), - PADDR (msg_reject), + PADDRH (msg_reject), /* ** normal processing */ @@ -1877,7 +1900,7 @@ static struct script script0 = { ** ... set a timestamp ... */ SCR_COPY (sizeof (struct timeval)), - (ncrcmd) &time, + KVAR (KVAR_TIME), NADDR (header.stamp.command), /* ** ... and send the command @@ -1899,7 +1922,7 @@ static struct script script0 = { ** set the timestamp. */ SCR_COPY (sizeof (struct timeval)), - (ncrcmd) &time, + KVAR (KVAR_TIME), NADDR (header.stamp.status), /* ** If this is a GETCC transfer, @@ -1965,7 +1988,7 @@ static struct script script0 = { SCR_FROM_REG (socl), 0, SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), - PADDR (msg_parity), + PADDRH (msg_parity), SCR_FROM_REG (scratcha), 0, /* @@ -1980,13 +2003,13 @@ static struct script script0 = { SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)), PADDR (disconnect), SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), - PADDR (msg_extended), + PADDRH (msg_extended), SCR_JUMP ^ IFTRUE (DATA (M_NOOP)), PADDR (clrack), SCR_JUMP ^ IFTRUE (DATA (M_REJECT)), - PADDR (msg_reject), + PADDRH (msg_reject), SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)), - PADDR (msg_ign_residue), + PADDRH (msg_ign_residue), /* ** Rest of the messages left as ** an exercise ... @@ -2005,123 +2028,643 @@ static struct script script0 = { SCR_JUMP, PADDR (setmsg), -}/*-------------------------< MSG_PARITY >---------------*/,{ +}/*-------------------------< COMPLETE >-----------------*/,{ /* - ** count it + ** Complete message. + ** + ** If it's not the get condition code, + ** copy TEMP register to LASTP in header. */ - SCR_REG_REG (PS_REG, SCR_ADD, 0x01), + SCR_FROM_REG (SS_REG), 0, - /* - ** send a "message parity error" message. +/*<<<*/ SCR_JUMPR ^ IFTRUE (MASK (S_SENSE, S_SENSE)), + 12, + SCR_COPY (4), + RADDR (temp), + NADDR (header.lastp), +/*>>>*/ /* + ** When we terminate the cycle by clearing ACK, + ** the target may disconnect immediately. + ** + ** We don't want to be told of an + ** "unexpected disconnect", + ** so we disable this feature. */ - SCR_LOAD_REG (scratcha, M_PARITY), + SCR_REG_REG (scntl2, SCR_AND, 0x7f), 0, - SCR_JUMP, - PADDR (setmsg), -}/*-------------------------< MSG_REJECT >---------------*/,{ /* - ** If a negotiation was in progress, - ** negotiation failed. + ** Terminate cycle ... */ - SCR_FROM_REG (HS_REG), + SCR_CLR (SCR_ACK|SCR_ATN), 0, - SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), - SIR_NEGO_FAILED, /* - ** else make host log this message + ** ... and wait for the disconnect. */ - SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)), - SIR_REJECT_RECEIVED, - SCR_JUMP, - PADDR (clrack), - -}/*-------------------------< MSG_IGN_RESIDUE >----------*/,{ + SCR_WAIT_DISC, + 0, +}/*-------------------------< CLEANUP >-------------------*/,{ /* - ** Terminate cycle + ** dsa: Pointer to ccb + ** or xxxxxxFF (no ccb) + ** + ** HS_REG: Host-Status (<>0!) */ - SCR_CLR (SCR_ACK), + SCR_FROM_REG (dsa), 0, - SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), - PADDR (dispatch), + SCR_JUMP ^ IFTRUE (DATA (0xff)), + PADDR (signal), /* - ** get residue size. + ** dsa is valid. + ** save the status registers */ - SCR_MOVE_ABS (1) ^ SCR_MSG_IN, - NADDR (msgin[1]), + SCR_COPY (4), + RADDR (scr0), + NADDR (header.status), /* - ** Check for message parity error. + ** and copy back the header to the ccb. */ - SCR_TO_REG (scratcha), + SCR_COPY_F (4), + RADDR (dsa), + PADDR (cleanup0), + SCR_COPY (sizeof (struct head)), + NADDR (header), +}/*-------------------------< CLEANUP0 >--------------------*/,{ 0, - SCR_FROM_REG (socl), + + /* + ** If command resulted in "check condition" + ** status and is not yet completed, + ** try to get the condition code. + */ + SCR_FROM_REG (HS_REG), 0, - SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), - PADDR (msg_parity), - SCR_FROM_REG (scratcha), +/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (0, HS_DONEMASK)), + 16, + SCR_FROM_REG (SS_REG), 0, + SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)), + PADDRH(getcc2), /* - ** Size is 0 .. ignore message. + ** And make the DSA register invalid. */ - SCR_JUMP ^ IFTRUE (DATA (0)), - PADDR (clrack), +/*>>>*/ SCR_LOAD_REG (dsa, 0xff), /* invalid */ + 0, +}/*-------------------------< SIGNAL >----------------------*/,{ /* - ** Size is not 1 .. have to interrupt. + ** if status = queue full, + ** reinsert in startqueue and stall queue. */ -/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (1)), - 40, + SCR_FROM_REG (SS_REG), + 0, + SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)), + SIR_STALL_QUEUE, /* - ** Check for residue byte in swide register + ** if job completed ... */ - SCR_FROM_REG (scntl2), + SCR_FROM_REG (HS_REG), 0, -/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)), - 16, /* - ** There IS data in the swide register. - ** Discard it. + ** ... signal completion to the host */ - SCR_REG_REG (scntl2, SCR_OR, WSR), + SCR_INT_FLY ^ IFFALSE (MASK (0, HS_DONEMASK)), 0, + /* + ** Auf zu neuen Schandtaten! + */ + SCR_JUMP, + PADDR(start), + +}/*-------------------------< SAVE_DP >------------------*/,{ + /* + ** SAVE_DP message: + ** Copy TEMP register to SAVEP in header. + */ + SCR_COPY (4), + RADDR (temp), + NADDR (header.savep), SCR_JUMP, PADDR (clrack), +}/*-------------------------< RESTORE_DP >---------------*/,{ /* - ** Load again the size to the sfbr register. + ** RESTORE_DP message: + ** Copy SAVEP in header to TEMP register. */ -/*>>>*/ SCR_FROM_REG (scratcha), - 0, -/*>>>*/ SCR_INT, - SIR_IGN_RESIDUE, + SCR_COPY (4), + NADDR (header.savep), + RADDR (temp), SCR_JUMP, PADDR (clrack), -}/*-------------------------< MSG_EXTENDED >-------------*/,{ +}/*-------------------------< DISCONNECT >---------------*/,{ /* - ** Terminate cycle + ** If QUIRK_AUTOSAVE is set, + ** do an "save pointer" operation. */ - SCR_CLR (SCR_ACK), + SCR_FROM_REG (QU_REG), 0, - SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), - PADDR (dispatch), +/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)), + 12, /* - ** get length. + ** like SAVE_DP message: + ** Copy TEMP register to SAVEP in header. */ - SCR_MOVE_ABS (1) ^ SCR_MSG_IN, - NADDR (msgin[1]), - /* - ** Check for message parity error. + SCR_COPY (4), + RADDR (temp), + NADDR (header.savep), +/*>>>*/ /* + ** Check if temp==savep or temp==goalp: + ** if not, log a missing save pointer message. + ** In fact, it's a comparison mod 256. + ** + ** Hmmm, I hadn't thought that I would be urged to + ** write this kind of ugly self modifying code. + ** + ** It's unbelievable, but the ncr53c8xx isn't able + ** to subtract one register from another. */ - SCR_TO_REG (scratcha), - 0, - SCR_FROM_REG (socl), - 0, - SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), - PADDR (msg_parity), - SCR_FROM_REG (scratcha), + SCR_FROM_REG (temp), 0, /* - */ - SCR_JUMP ^ IFTRUE (DATA (3)), - PADDR (msg_ext_3), + ** You are not expected to understand this .. + ** + ** CAUTION: only little endian architectures supported! XXX + */ + SCR_COPY_F (1), + NADDR (header.savep), + PADDR (disconnect0), +}/*-------------------------< DISCONNECT0 >--------------*/,{ +/*<<<*/ SCR_JUMPR ^ IFTRUE (DATA (1)), + 20, + /* + ** neither this + */ + SCR_COPY_F (1), + NADDR (header.goalp), + PADDR (disconnect1), +}/*-------------------------< DISCONNECT1 >--------------*/,{ + SCR_INT ^ IFFALSE (DATA (1)), + SIR_MISSING_SAVE, +/*>>>*/ + + /* + ** DISCONNECTing ... + ** + ** disable the "unexpected disconnect" feature, + ** and remove the ACK signal. + */ + SCR_REG_REG (scntl2, SCR_AND, 0x7f), + 0, + SCR_CLR (SCR_ACK|SCR_ATN), + 0, + /* + ** Wait for the disconnect. + */ + SCR_WAIT_DISC, + 0, + /* + ** Profiling: + ** Set a time stamp, + ** and count the disconnects. + */ + SCR_COPY (sizeof (struct timeval)), + KVAR (KVAR_TIME), + NADDR (header.stamp.disconnect), + SCR_COPY (4), + NADDR (disc_phys), + RADDR (temp), + SCR_REG_REG (temp, SCR_ADD, 0x01), + 0, + SCR_COPY (4), + RADDR (temp), + NADDR (disc_phys), + /* + ** Status is: DISCONNECTED. + */ + SCR_LOAD_REG (HS_REG, HS_DISCONNECT), + 0, + SCR_JUMP, + PADDR (cleanup), + +}/*-------------------------< MSG_OUT >-------------------*/,{ + /* + ** The target requests a message. + */ + SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, + NADDR (msgout), + SCR_COPY (1), + RADDR (sfbr), + NADDR (lastmsg), + /* + ** If it was no ABORT message ... + */ + SCR_JUMP ^ IFTRUE (DATA (M_ABORT)), + PADDRH (msg_out_abort), + /* + ** ... wait for the next phase + ** if it's a message out, send it again, ... + */ + SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), + PADDR (msg_out), +}/*-------------------------< MSG_OUT_DONE >--------------*/,{ + /* + ** ... else clear the message ... + */ + SCR_LOAD_REG (scratcha, M_NOOP), + 0, + SCR_COPY (4), + RADDR (scratcha), + NADDR (msgout), + /* + ** ... and process the next phase + */ + SCR_JUMP, + PADDR (dispatch), + +}/*------------------------< BADGETCC >---------------------*/,{ + /* + ** If SIGP was set, clear it and try again. + */ + SCR_FROM_REG (ctest2), + 0, + SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)), + PADDRH (getcc2), + SCR_INT, + SIR_SENSE_FAILED, +}/*-------------------------< RESELECT >--------------------*/,{ + /* + ** This NOP will be patched with LED OFF + ** SCR_REG_REG (gpreg, SCR_OR, 0x01) + */ + SCR_NO_OP, + 0, + + /* + ** make the DSA invalid. + */ + SCR_LOAD_REG (dsa, 0xff), + 0, + SCR_CLR (SCR_TRG), + 0, + /* + ** Sleep waiting for a reselection. + ** If SIGP is set, special treatment. + ** + ** Zu allem bereit .. + */ + SCR_WAIT_RESEL, + PADDR(reselect2), +}/*-------------------------< RESELECT1 >--------------------*/,{ + /* + ** This NOP will be patched with LED ON + ** SCR_REG_REG (gpreg, SCR_AND, 0xfe) + */ + SCR_NO_OP, + 0, + /* + ** ... zu nichts zu gebrauchen ? + ** + ** load the target id into the SFBR + ** and jump to the control block. + ** + ** Look at the declarations of + ** - struct ncb + ** - struct tcb + ** - struct lcb + ** - struct ccb + ** to understand what's going on. + */ + SCR_REG_SFBR (ssid, SCR_AND, 0x8F), + 0, + SCR_TO_REG (ctest0), + 0, + SCR_JUMP, + NADDR (jump_tcb), +}/*-------------------------< RESELECT2 >-------------------*/,{ + /* + ** This NOP will be patched with LED ON + ** SCR_REG_REG (gpreg, SCR_AND, 0xfe) + */ + SCR_NO_OP, + 0, + /* + ** If it's not connected :( + ** -> interrupted by SIGP bit. + ** Jump to start. + */ + SCR_FROM_REG (ctest2), + 0, + SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)), + PADDR (start), + SCR_JUMP, + PADDR (reselect), + +}/*-------------------------< RESEL_TMP >-------------------*/,{ + /* + ** The return address in TEMP + ** is in fact the data structure address, + ** so copy it to the DSA register. + */ + SCR_COPY (4), + RADDR (temp), + RADDR (dsa), + SCR_JUMP, + PADDR (prepare), + +}/*-------------------------< RESEL_LUN >-------------------*/,{ + /* + ** come back to this point + ** to get an IDENTIFY message + ** Wait for a msg_in phase. + */ +/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), + 48, + /* + ** message phase + ** It's not a sony, it's a trick: + ** read the data without acknowledging it. + */ + SCR_FROM_REG (sbdl), + 0, +/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (M_IDENTIFY, 0x98)), + 32, + /* + ** It WAS an Identify message. + ** get it and ack it! + */ + SCR_MOVE_ABS (1) ^ SCR_MSG_IN, + NADDR (msgin), + SCR_CLR (SCR_ACK), + 0, + /* + ** Mask out the lun. + */ + SCR_REG_REG (sfbr, SCR_AND, 0x07), + 0, + SCR_RETURN, + 0, + /* + ** No message phase or no IDENTIFY message: + ** return 0. + */ +/*>>>*/ SCR_LOAD_SFBR (0), + 0, + SCR_RETURN, + 0, + +}/*-------------------------< RESEL_TAG >-------------------*/,{ + /* + ** come back to this point + ** to get a SIMPLE_TAG message + ** Wait for a MSG_IN phase. + */ +/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), + 64, + /* + ** message phase + ** It's a trick - read the data + ** without acknowledging it. + */ + SCR_FROM_REG (sbdl), + 0, +/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (M_SIMPLE_TAG)), + 48, + /* + ** It WAS a SIMPLE_TAG message. + ** get it and ack it! + */ + SCR_MOVE_ABS (1) ^ SCR_MSG_IN, + NADDR (msgin), + SCR_CLR (SCR_ACK), + 0, + /* + ** Wait for the second byte (the tag) + */ +/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), + 24, + /* + ** Get it and ack it! + */ + SCR_MOVE_ABS (1) ^ SCR_MSG_IN, + NADDR (msgin), + SCR_CLR (SCR_ACK|SCR_CARRY), + 0, + SCR_RETURN, + 0, + /* + ** No message phase or no SIMPLE_TAG message + ** or no second byte: return 0. + */ +/*>>>*/ SCR_LOAD_SFBR (0), + 0, + SCR_SET (SCR_CARRY), + 0, + SCR_RETURN, + 0, + +}/*-------------------------< DATA_IN >--------------------*/,{ +/* +** Because the size depends on the +** #define MAX_SCATTER parameter, +** it is filled in at runtime. +** +** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), +** PADDR (no_data), +** SCR_COPY (sizeof (struct timeval)), +** KVAR (KVAR_TIME), +** NADDR (header.stamp.data), +** SCR_MOVE_TBL ^ SCR_DATA_IN, +** offsetof (struct dsb, data[ 0]), +** +** ##===========< i=1; i========= +** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN)), +** || PADDR (checkatn), +** || SCR_MOVE_TBL ^ SCR_DATA_IN, +** || offsetof (struct dsb, data[ i]), +** ##========================================== +** +** SCR_CALL, +** PADDR (checkatn), +** SCR_JUMP, +** PADDR (no_data), +*/ +0 +}/*-------------------------< DATA_OUT >-------------------*/,{ +/* +** Because the size depends on the +** #define MAX_SCATTER parameter, +** it is filled in at runtime. +** +** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT)), +** PADDR (no_data), +** SCR_COPY (sizeof (struct timeval)), +** KVAR (KVAR_TIME), +** NADDR (header.stamp.data), +** SCR_MOVE_TBL ^ SCR_DATA_OUT, +** offsetof (struct dsb, data[ 0]), +** +** ##===========< i=1; i========= +** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT)), +** || PADDR (dispatch), +** || SCR_MOVE_TBL ^ SCR_DATA_OUT, +** || offsetof (struct dsb, data[ i]), +** ##========================================== +** +** SCR_CALL, +** PADDR (dispatch), +** SCR_JUMP, +** PADDR (no_data), +** +**--------------------------------------------------------- +*/ +(u_long)&ident + +}/*--------------------------------------------------------*/ +}; + + +static struct scripth scripth0 = { +/*-------------------------< TRYLOOP >---------------------*/{ +/* +** Load an entry of the start queue into dsa +** and try to start it by jumping to TRYSEL. +** +** Because the size depends on the +** #define MAX_START parameter, it is filled +** in at runtime. +** +**----------------------------------------------------------- +** +** ##===========< I=0; i=========== +** || SCR_COPY (4), +** || NADDR (squeue[i]), +** || RADDR (dsa), +** || SCR_CALL, +** || PADDR (trysel), +** ##========================================== +** +** SCR_JUMP, +** PADDRH(tryloop), +** +**----------------------------------------------------------- +*/ +0 +}/*-------------------------< MSG_PARITY >---------------*/,{ + /* + ** count it + */ + SCR_REG_REG (PS_REG, SCR_ADD, 0x01), + 0, + /* + ** send a "message parity error" message. + */ + SCR_LOAD_REG (scratcha, M_PARITY), + 0, + SCR_JUMP, + PADDR (setmsg), +}/*-------------------------< MSG_REJECT >---------------*/,{ + /* + ** If a negotiation was in progress, + ** negotiation failed. + */ + SCR_FROM_REG (HS_REG), + 0, + SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), + SIR_NEGO_FAILED, + /* + ** else make host log this message + */ + SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)), + SIR_REJECT_RECEIVED, + SCR_JUMP, + PADDR (clrack), + +}/*-------------------------< MSG_IGN_RESIDUE >----------*/,{ + /* + ** Terminate cycle + */ + SCR_CLR (SCR_ACK), + 0, + SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), + PADDR (dispatch), + /* + ** get residue size. + */ + SCR_MOVE_ABS (1) ^ SCR_MSG_IN, + NADDR (msgin[1]), + /* + ** Check for message parity error. + */ + SCR_TO_REG (scratcha), + 0, + SCR_FROM_REG (socl), + 0, + SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), + PADDRH (msg_parity), + SCR_FROM_REG (scratcha), + 0, + /* + ** Size is 0 .. ignore message. + */ + SCR_JUMP ^ IFTRUE (DATA (0)), + PADDR (clrack), + /* + ** Size is not 1 .. have to interrupt. + */ +/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (1)), + 40, + /* + ** Check for residue byte in swide register + */ + SCR_FROM_REG (scntl2), + 0, +/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)), + 16, + /* + ** There IS data in the swide register. + ** Discard it. + */ + SCR_REG_REG (scntl2, SCR_OR, WSR), + 0, + SCR_JUMP, + PADDR (clrack), + /* + ** Load again the size to the sfbr register. + */ +/*>>>*/ SCR_FROM_REG (scratcha), + 0, +/*>>>*/ SCR_INT, + SIR_IGN_RESIDUE, + SCR_JUMP, + PADDR (clrack), + +}/*-------------------------< MSG_EXTENDED >-------------*/,{ + /* + ** Terminate cycle + */ + SCR_CLR (SCR_ACK), + 0, + SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), + PADDR (dispatch), + /* + ** get length. + */ + SCR_MOVE_ABS (1) ^ SCR_MSG_IN, + NADDR (msgin[1]), + /* + ** Check for message parity error. + */ + SCR_TO_REG (scratcha), + 0, + SCR_FROM_REG (socl), + 0, + SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), + PADDRH (msg_parity), + SCR_FROM_REG (scratcha), + 0, + /* + */ + SCR_JUMP ^ IFTRUE (DATA (3)), + PADDRH (msg_ext_3), SCR_JUMP ^ IFFALSE (DATA (2)), PADDR (msg_bad), }/*-------------------------< MSG_EXT_2 >----------------*/,{ @@ -2142,11 +2685,11 @@ static struct script script0 = { SCR_FROM_REG (socl), 0, SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), - PADDR (msg_parity), + PADDRH (msg_parity), SCR_FROM_REG (scratcha), 0, SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)), - PADDR (msg_wdtr), + PADDRH (msg_wdtr), /* ** unknown extended message */ @@ -2165,7 +2708,7 @@ static struct script script0 = { SCR_FROM_REG (socl), 0, SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), - PADDR (msg_parity), + PADDRH (msg_parity), /* ** let the host do the real work. */ @@ -2212,310 +2755,59 @@ static struct script script0 = { SCR_FROM_REG (socl), 0, SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), - PADDR (msg_parity), + PADDRH (msg_parity), SCR_FROM_REG (scratcha), 0, SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)), - PADDR (msg_sdtr), - /* - ** unknown extended message - */ - SCR_JUMP, - PADDR (msg_bad) - -}/*-------------------------< MSG_SDTR >-----------------*/,{ - SCR_CLR (SCR_ACK), - 0, - SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), - PADDR (dispatch), - /* - ** get period and offset - */ - SCR_MOVE_ABS (2) ^ SCR_MSG_IN, - NADDR (msgin[3]), - SCR_FROM_REG (socl), - 0, - SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), - PADDR (msg_parity), - /* - ** let the host do the real work. - */ - SCR_INT, - SIR_NEGO_SYNC, - /* - ** let the target fetch our answer. - */ - SCR_SET (SCR_ATN), - 0, - SCR_CLR (SCR_ACK), - 0, - - SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), - SIR_NEGO_PROTO, - /* - ** Send the M_X_SYNC_REQ - */ - SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, - NADDR (msgout), - SCR_CLR (SCR_ATN), - 0, - SCR_COPY (1), - RADDR (sfbr), - NADDR (lastmsg), - SCR_JUMP, - PADDR (msg_out_done), - -}/*-------------------------< COMPLETE >-----------------*/,{ - /* - ** Complete message. - ** - ** If it's not the get condition code, - ** copy TEMP register to LASTP in header. - */ - SCR_FROM_REG (SS_REG), - 0, -/*<<<*/ SCR_JUMPR ^ IFTRUE (MASK (S_SENSE, S_SENSE)), - 12, - SCR_COPY (4), - RADDR (temp), - NADDR (header.lastp), -/*>>>*/ /* - ** When we terminate the cycle by clearing ACK, - ** the target may disconnect immediately. - ** - ** We don't want to be told of an - ** "unexpected disconnect", - ** so we disable this feature. - */ - SCR_REG_REG (scntl2, SCR_AND, 0x7f), - 0, - /* - ** Terminate cycle ... - */ - SCR_CLR (SCR_ACK|SCR_ATN), - 0, - /* - ** ... and wait for the disconnect. - */ - SCR_WAIT_DISC, - 0, -}/*-------------------------< CLEANUP >-------------------*/,{ - /* - ** dsa: Pointer to ccb - ** or xxxxxxFF (no ccb) - ** - ** HS_REG: Host-Status (<>0!) - */ - SCR_FROM_REG (dsa), - 0, - SCR_JUMP ^ IFTRUE (DATA (0xff)), - PADDR (signal), - /* - ** dsa is valid. - ** save the status registers - */ - SCR_COPY (4), - RADDR (scr0), - NADDR (header.status), - /* - ** and copy back the header to the ccb. - */ - SCR_COPY_F (4), - RADDR (dsa), - PADDR (cleanup0), - SCR_COPY (sizeof (struct head)), - NADDR (header), -}/*-------------------------< CLEANUP0 >--------------------*/,{ - 0, - - /* - ** If command resulted in "check condition" - ** status and is not yet completed, - ** try to get the condition code. - */ - SCR_FROM_REG (HS_REG), - 0, -/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (0, HS_DONEMASK)), - 16, - SCR_FROM_REG (SS_REG), - 0, - SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)), - PADDR(getcc2), - /* - ** And make the DSA register invalid. - */ -/*>>>*/ SCR_LOAD_REG (dsa, 0xff), /* invalid */ - 0, -}/*-------------------------< SIGNAL >----------------------*/,{ - /* - ** if status = queue full, - ** reinsert in startqueue and stall queue. - */ - SCR_FROM_REG (SS_REG), - 0, - SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)), - SIR_STALL_QUEUE, - /* - ** if job completed ... - */ - SCR_FROM_REG (HS_REG), - 0, - /* - ** ... signal completion to the host - */ - SCR_INT_FLY ^ IFFALSE (MASK (0, HS_DONEMASK)), - 0, - /* - ** Auf zu neuen Schandtaten! - */ - SCR_JUMP, - PADDR(start), - -}/*-------------------------< SAVE_DP >------------------*/,{ - /* - ** SAVE_DP message: - ** Copy TEMP register to SAVEP in header. - */ - SCR_COPY (4), - RADDR (temp), - NADDR (header.savep), - SCR_JUMP, - PADDR (clrack), -}/*-------------------------< RESTORE_DP >---------------*/,{ - /* - ** RESTORE_DP message: - ** Copy SAVEP in header to TEMP register. - */ - SCR_COPY (4), - NADDR (header.savep), - RADDR (temp), - SCR_JUMP, - PADDR (clrack), - -}/*-------------------------< DISCONNECT >---------------*/,{ - /* - ** If QUIRK_AUTOSAVE is set, - ** do an "save pointer" operation. - */ - SCR_FROM_REG (QU_REG), - 0, -/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)), - 12, - /* - ** like SAVE_DP message: - ** Copy TEMP register to SAVEP in header. - */ - SCR_COPY (4), - RADDR (temp), - NADDR (header.savep), -/*>>>*/ /* - ** Check if temp==savep or temp==goalp: - ** if not, log a missing save pointer message. - ** In fact, it's a comparison mod 256. - ** - ** Hmmm, I hadn't thought that I would be urged to - ** write this kind of ugly self modifying code. - ** - ** It's unbelievable, but the ncr53c8xx isn't able - ** to subtract one register from another. - */ - SCR_FROM_REG (temp), - 0, - /* - ** You are not expected to understand this .. - ** - ** CAUTION: only little endian architectures supported! XXX - */ - SCR_COPY_F (1), - NADDR (header.savep), - PADDR (disconnect0), -}/*-------------------------< DISCONNECT0 >--------------*/,{ -/*<<<*/ SCR_JUMPR ^ IFTRUE (DATA (1)), - 20, - /* - ** neither this - */ - SCR_COPY_F (1), - NADDR (header.goalp), - PADDR (disconnect1), -}/*-------------------------< DISCONNECT1 >--------------*/,{ - SCR_INT ^ IFFALSE (DATA (1)), - SIR_MISSING_SAVE, -/*>>>*/ - - /* - ** DISCONNECTing ... - ** - ** disable the "unexpected disconnect" feature, - ** and remove the ACK signal. - */ - SCR_REG_REG (scntl2, SCR_AND, 0x7f), - 0, - SCR_CLR (SCR_ACK|SCR_ATN), - 0, + PADDRH (msg_sdtr), /* - ** Wait for the disconnect. + ** unknown extended message */ - SCR_WAIT_DISC, + SCR_JUMP, + PADDR (msg_bad) + +}/*-------------------------< MSG_SDTR >-----------------*/,{ + SCR_CLR (SCR_ACK), 0, + SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), + PADDR (dispatch), /* - ** Profiling: - ** Set a time stamp, - ** and count the disconnects. + ** get period and offset */ - SCR_COPY (sizeof (struct timeval)), - (ncrcmd) &time, - NADDR (header.stamp.disconnect), - SCR_COPY (4), - NADDR (disc_phys), - RADDR (temp), - SCR_REG_REG (temp, SCR_ADD, 0x01), + SCR_MOVE_ABS (2) ^ SCR_MSG_IN, + NADDR (msgin[3]), + SCR_FROM_REG (socl), 0, - SCR_COPY (4), - RADDR (temp), - NADDR (disc_phys), + SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), + PADDRH (msg_parity), /* - ** Status is: DISCONNECTED. + ** let the host do the real work. */ - SCR_LOAD_REG (HS_REG, HS_DISCONNECT), + SCR_INT, + SIR_NEGO_SYNC, + /* + ** let the target fetch our answer. + */ + SCR_SET (SCR_ATN), + 0, + SCR_CLR (SCR_ACK), 0, - SCR_JUMP, - PADDR (cleanup), -}/*-------------------------< MSG_OUT >-------------------*/,{ + SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), + SIR_NEGO_PROTO, /* - ** The target requests a message. + ** Send the M_X_SYNC_REQ */ - SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, + SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, NADDR (msgout), + SCR_CLR (SCR_ATN), + 0, SCR_COPY (1), RADDR (sfbr), NADDR (lastmsg), - /* - ** If it was no ABORT message ... - */ - SCR_JUMP ^ IFTRUE (DATA (M_ABORT)), - PADDR (msg_out_abort), - /* - ** ... wait for the next phase - ** if it's a message out, send it again, ... - */ - SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), - PADDR (msg_out), -}/*-------------------------< MSG_OUT_DONE >--------------*/,{ - /* - ** ... else clear the message ... - */ - SCR_LOAD_REG (scratcha, M_NOOP), - 0, - SCR_COPY (4), - RADDR (scratcha), - NADDR (msgout), - /* - ** ... and process the next phase - */ SCR_JUMP, - PADDR (dispatch), + PADDR (msg_out_done), + }/*-------------------------< MSG_OUT_ABORT >-------------*/,{ /* ** After ABORT message, @@ -2548,7 +2840,7 @@ static struct script script0 = { */ SCR_COPY_F (4), RADDR (dsa), - PADDR (getcc1), + PADDRH (getcc1), /* ** ... then we do the actual copy. */ @@ -2601,321 +2893,82 @@ static struct script script0 = { /* ** Load scratcha, because in case of a selection timeout, ** the host will expect a new value for startpos in - ** the scratcha register. - */ - SCR_COPY (4), - PADDR (startpos), - RADDR (scratcha), -#ifdef NCR_GETCC_WITHMSG - /* - ** If QUIRK_NOMSG is set, select without ATN. - ** and don't send a message. - */ - SCR_FROM_REG (QU_REG), - 0, - SCR_JUMP ^ IFTRUE (MASK (QUIRK_NOMSG, QUIRK_NOMSG)), - PADDR(getcc3), - /* - ** Then try to connect to the target. - ** If we are reselected, special treatment - ** of the current job is required before - ** accepting the reselection. - */ - SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), - PADDR(badgetcc), - /* - ** save target id. - */ - SCR_FROM_REG (sdid), - 0, - SCR_TO_REG (ctest0), - 0, - /* - ** Send the IDENTIFY message. - ** In case of short transfer, remove ATN. - */ - SCR_MOVE_TBL ^ SCR_MSG_OUT, - offsetof (struct dsb, smsg2), - SCR_CLR (SCR_ATN), - 0, - /* - ** save the first byte of the message. - */ - SCR_COPY (1), - RADDR (sfbr), - NADDR (lastmsg), - SCR_JUMP, - PADDR (prepare2), - -#endif -}/*-------------------------< 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_JUMP, - PADDR (prepare2), - -}/*------------------------< BADGETCC >---------------------*/,{ - /* - ** If SIGP was set, clear it and try again. - */ - SCR_FROM_REG (ctest2), - 0, - SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)), - PADDR (getcc2), - SCR_INT, - SIR_SENSE_FAILED, -}/*-------------------------< RESELECT >--------------------*/,{ - /* - ** This NOP will be patched with LED OFF - ** SCR_REG_REG (gpreg, SCR_OR, 0x01) - */ - SCR_NO_OP, - 0, - - /* - ** make the DSA invalid. - */ - SCR_LOAD_REG (dsa, 0xff), - 0, - SCR_CLR (SCR_TRG), - 0, - /* - ** Sleep waiting for a reselection. - ** If SIGP is set, special treatment. - ** - ** Zu allem bereit .. - */ - SCR_WAIT_RESEL, - PADDR(reselect2), -}/*-------------------------< RESELECT1 >--------------------*/,{ - /* - ** This NOP will be patched with LED ON - ** SCR_REG_REG (gpreg, SCR_AND, 0xfe) - */ - SCR_NO_OP, - 0, - /* - ** ... zu nichts zu gebrauchen ? - ** - ** load the target id into the SFBR - ** and jump to the control block. - ** - ** Look at the declarations of - ** - struct ncb - ** - struct tcb - ** - struct lcb - ** - struct ccb - ** to understand what's going on. - */ - SCR_REG_SFBR (ssid, SCR_AND, 0x8F), - 0, - SCR_TO_REG (ctest0), - 0, - SCR_JUMP, - NADDR (jump_tcb), -}/*-------------------------< RESELECT2 >-------------------*/,{ - /* - ** This NOP will be patched with LED ON - ** SCR_REG_REG (gpreg, SCR_AND, 0xfe) - */ - SCR_NO_OP, - 0, - /* - ** If it's not connected :( - ** -> interrupted by SIGP bit. - ** Jump to start. - */ - SCR_FROM_REG (ctest2), - 0, - SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)), - PADDR (start), - SCR_JUMP, - PADDR (reselect), - -}/*-------------------------< RESEL_TMP >-------------------*/,{ - /* - ** The return address in TEMP - ** is in fact the data structure address, - ** so copy it to the DSA register. - */ - SCR_COPY (4), - RADDR (temp), - RADDR (dsa), - SCR_JUMP, - PADDR (prepare), - -}/*-------------------------< RESEL_LUN >-------------------*/,{ - /* - ** come back to this point - ** to get an IDENTIFY message - ** Wait for a msg_in phase. - */ -/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), - 48, - /* - ** message phase - ** It's not a sony, it's a trick: - ** read the data without acknowledging it. - */ - SCR_FROM_REG (sbdl), - 0, -/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (M_IDENTIFY, 0x98)), - 32, + ** the scratcha register. + */ + SCR_COPY (4), + PADDR (startpos), + RADDR (scratcha), +#ifdef NCR_GETCC_WITHMSG /* - ** It WAS an Identify message. - ** get it and ack it! + ** If QUIRK_NOMSG is set, select without ATN. + ** and don't send a message. */ - SCR_MOVE_ABS (1) ^ SCR_MSG_IN, - NADDR (msgin), - SCR_CLR (SCR_ACK), + SCR_FROM_REG (QU_REG), 0, + SCR_JUMP ^ IFTRUE (MASK (QUIRK_NOMSG, QUIRK_NOMSG)), + PADDRH(getcc3), /* - ** Mask out the lun. + ** Then try to connect to the target. + ** If we are reselected, special treatment + ** of the current job is required before + ** accepting the reselection. */ - SCR_REG_REG (sfbr, SCR_AND, 0x07), - 0, - SCR_RETURN, - 0, + SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), + PADDR(badgetcc), /* - ** No message phase or no IDENTIFY message: - ** return 0. + ** save target id. */ -/*>>>*/ SCR_LOAD_SFBR (0), + SCR_FROM_REG (sdid), 0, - SCR_RETURN, + SCR_TO_REG (ctest0), 0, - -}/*-------------------------< RESEL_TAG >-------------------*/,{ - /* - ** come back to this point - ** to get a SIMPLE_TAG message - ** Wait for a MSG_IN phase. - */ -/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), - 64, /* - ** message phase - ** It's a trick - read the data - ** without acknowledging it. + ** Send the IDENTIFY message. + ** In case of short transfer, remove ATN. */ - SCR_FROM_REG (sbdl), + SCR_MOVE_TBL ^ SCR_MSG_OUT, + offsetof (struct dsb, smsg2), + SCR_CLR (SCR_ATN), 0, -/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (M_SIMPLE_TAG)), - 48, /* - ** It WAS a SIMPLE_TAG message. - ** get it and ack it! + ** save the first byte of the message. */ - SCR_MOVE_ABS (1) ^ SCR_MSG_IN, - NADDR (msgin), - SCR_CLR (SCR_ACK), - 0, + SCR_COPY (1), + RADDR (sfbr), + NADDR (lastmsg), + SCR_JUMP, + PADDR (prepare2), + +#endif +}/*-------------------------< GETCC3 >----------------------*/,{ /* - ** Wait for the second byte (the tag) + ** 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_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), - 24, + SCR_SEL_TBL ^ offsetof (struct dsb, select), + PADDR(badgetcc), /* - ** Get it and ack it! + ** save target id. */ - SCR_MOVE_ABS (1) ^ SCR_MSG_IN, - NADDR (msgin), - SCR_CLR (SCR_ACK|SCR_CARRY), + SCR_FROM_REG (sdid), 0, - SCR_RETURN, + SCR_TO_REG (ctest0), 0, /* - ** No message phase or no SIMPLE_TAG message - ** or no second byte: return 0. + ** Force error if selection timeout */ -/*>>>*/ SCR_LOAD_SFBR (0), - 0, - SCR_SET (SCR_CARRY), - 0, - SCR_RETURN, + SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)), 0, - -}/*-------------------------< DATA_IN >--------------------*/,{ -/* -** Because the size depends on the -** #define MAX_SCATTER parameter, -** it is filled in at runtime. -** -** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), -** PADDR (no_data), -** SCR_COPY (sizeof (struct timeval)), -** (ncrcmd) &time, -** NADDR (header.stamp.data), -** SCR_MOVE_TBL ^ SCR_DATA_IN, -** offsetof (struct dsb, data[ 0]), -** -** ##===========< i=1; i========= -** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN)), -** || PADDR (checkatn), -** || SCR_MOVE_TBL ^ SCR_DATA_IN, -** || offsetof (struct dsb, data[ i]), -** ##========================================== -** -** SCR_CALL, -** PADDR (checkatn), -** SCR_JUMP, -** PADDR (no_data), -*/ -0 -}/*-------------------------< DATA_OUT >-------------------*/,{ -/* -** Because the size depends on the -** #define MAX_SCATTER parameter, -** it is filled in at runtime. -** -** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), -** PADDR (no_data), -** SCR_COPY (sizeof (struct timeval)), -** (ncrcmd) &time, -** NADDR (header.stamp.data), -** SCR_MOVE_TBL ^ SCR_DATA_OUT, -** offsetof (struct dsb, data[ 0]), -** -** ##===========< i=1; i========= -** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT)), -** || PADDR (dispatch), -** || SCR_MOVE_TBL ^ SCR_DATA_OUT, -** || offsetof (struct dsb, data[ i]), -** ##========================================== -** -** SCR_CALL, -** PADDR (dispatch), -** SCR_JUMP, -** PADDR (no_data), -** -**--------------------------------------------------------- -*/ -(u_long)&ident - + /* + ** don't negotiate. + */ + SCR_JUMP, + PADDR (prepare2), }/*-------------------------< ABORTTAG >-------------------*/,{ /* ** Abort a bad reselection. @@ -2957,19 +3010,19 @@ static struct script script0 = { ** Read the variable. */ SCR_COPY (4), - (ncrcmd) &ncr_cache, + KVAR (KVAR_NCR_CACHE), RADDR (scratcha), /* ** Write the variable. */ SCR_COPY (4), RADDR (temp), - (ncrcmd) &ncr_cache, + KVAR (KVAR_NCR_CACHE), /* ** Read back the variable. */ SCR_COPY (4), - (ncrcmd) &ncr_cache, + KVAR (KVAR_NCR_CACHE), RADDR (temp), }/*-------------------------< SNOOPEND >-------------------*/,{ /* @@ -2980,6 +3033,7 @@ static struct script script0 = { }/*--------------------------------------------------------*/ }; + /*========================================================== ** ** @@ -2989,12 +3043,12 @@ static struct script script0 = { **========================================================== */ -void ncr_script_fill (struct script * scr) +void ncr_script_fill (struct script * scr, struct scripth * scrh) { int i; ncrcmd *p; - p = scr->tryloop; + p = scrh->tryloop; for (i=0; itryloop + sizeof (scr->tryloop)); + assert ((u_long)p == (u_long)&scrh->tryloop + sizeof (scrh->tryloop)); p = scr->data_in; *p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)); *p++ =PADDR (no_data); *p++ =SCR_COPY (sizeof (struct timeval)); - *p++ =(ncrcmd) &time; + *p++ =(ncrcmd) KVAR (KVAR_TIME); *p++ =NADDR (header.stamp.data); *p++ =SCR_MOVE_TBL ^ SCR_DATA_IN; *p++ =offsetof (struct dsb, data[ 0]); @@ -3036,7 +3090,7 @@ void ncr_script_fill (struct script * scr) *p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT)); *p++ =PADDR (no_data); *p++ =SCR_COPY (sizeof (struct timeval)); - *p++ =(ncrcmd) &time; + *p++ =(ncrcmd) KVAR (KVAR_TIME); *p++ =NADDR (header.stamp.data); *p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT; *p++ =offsetof (struct dsb, data[ 0]); @@ -3065,27 +3119,14 @@ void ncr_script_fill (struct script * scr) **========================================================== */ -static void ncr_script_copy_and_bind (struct script *script, ncb_p np) +void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int len) { - ncrcmd opcode, new, old; - ncrcmd *src, *dst, *start, *end; + ncrcmd opcode, new, old, tmp1, tmp2; + ncrcmd *start, *end; int relocs; -#ifndef __NetBSD__ - np->script = (struct script*) vm_page_alloc_contig - (round_page(sizeof (struct script)), 0x100000, 0xffffffff, PAGE_SIZE); -#else /* !__NetBSD___ */ - np->script = (struct script *) - malloc (sizeof (struct script), M_DEVBUF, M_WAITOK); -#endif /* __NetBSD__ */ - - np->p_script = vtophys(np->script); - - src = script->start; - dst = np->script->start; - start = src; - end = src + (sizeof (struct script) / 4); + end = src + len/4; while (src < end) { @@ -3100,13 +3141,13 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) if (opcode == 0) { printf ("%s: ERROR0 IN SCRIPT at %d.\n", - ncr_name(np), src-start-1); + ncr_name(np), (int) (src-start-1)); DELAY (1000000); }; if (DEBUG_FLAGS & DEBUG_SCRIPT) - printf ("%x: <%x>\n", - (unsigned)(src-1), (unsigned)opcode); + printf ("%p: <%x>\n", + (src-1), (unsigned)opcode); /* ** We don't have to decode ALL commands @@ -3118,17 +3159,22 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) ** COPY has TWO arguments. */ relocs = 2; - if ((src[0] ^ src[1]) & 3) { + tmp1 = src[0]; + if ((tmp1 & RELOC_MASK) == RELOC_KVAR) + tmp1 = 0; + tmp2 = src[1]; + if ((tmp2 & RELOC_MASK) == RELOC_KVAR) + tmp2 = 0; + if ((tmp1 ^ tmp2) & 3) { printf ("%s: ERROR1 IN SCRIPT at %d.\n", - ncr_name(np), src-start-1); + ncr_name(np), (int) (src-start-1)); DELAY (1000000); - }; - + } /* - ** If PREFETCH feature is not enabled/supported - ** remove the NO FLUSH bit if present. + ** If PREFETCH feature not enabled, remove + ** the NO FLUSH bit if present. */ - if ((opcode & SCR_NO_FLUSH)&&!(np->features & FE_PFEN)) + if ((opcode & SCR_NO_FLUSH) && !(np->features&FE_PFEN)) dst[-1] = (opcode & ~SCR_NO_FLUSH); break; @@ -3173,9 +3219,21 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) case RELOC_LABEL: new = (old & ~RELOC_MASK) + np->p_script; break; + case RELOC_LABELH: + new = (old & ~RELOC_MASK) + np->p_scripth; + break; case RELOC_SOFTC: new = (old & ~RELOC_MASK) + vtophys(np); break; + case RELOC_KVAR: + if (((old & ~RELOC_MASK) < + SCRIPT_KVAR_FIRST) || + ((old & ~RELOC_MASK) > + SCRIPT_KVAR_LAST)) + panic("ncr KVAR out of range"); + new = vtophys(script_kvars[old & + ~RELOC_MASK]); + break; case 0: /* Don't relocate a 0 address. */ if (old == 0) { @@ -3184,7 +3242,7 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) } /* fall through */ default: - new = vtophys(old); + panic("ncr_script_copy_and_bind: weird relocation %x @ %d\n", old, (src - start)); break; } @@ -3493,6 +3551,33 @@ static void ncr_attach (pcici_t config_id, int unit) np->unit = unit; /* + ** Allocate structure for script relocation. + */ +#ifdef __FreeBSD__ + if (sizeof (struct script) > PAGE_SIZE) { + np->script0 = (struct script*) vm_page_alloc_contig + (round_page(sizeof (struct script)), + 0x100000, 0xffffffff, PAGE_SIZE); + } else { + np->script0 = (struct script *) + malloc (sizeof (struct script), M_DEVBUF, M_WAITOK); + } + if (sizeof (struct scripth) > PAGE_SIZE) { + np->scripth0 = (struct scripth*) vm_page_alloc_contig + (round_page(sizeof (struct scripth)), + 0x100000, 0xffffffff, PAGE_SIZE); + } else { + np->scripth0 = (struct scripth *) + malloc (sizeof (struct scripth), M_DEVBUF, M_WAITOK); + } +#else /* __FreeBSD___ */ + np->script0 = (struct script *) + malloc (sizeof (struct script), M_DEVBUF, M_WAITOK); + np->scripth0 = (struct scripth *) + malloc (sizeof (struct scripth), M_DEVBUF, M_WAITOK); +#endif /* __FreeBSD__ */ + + /* ** Try to map the controller chip to ** virtual and physical memory. */ @@ -3532,7 +3617,7 @@ static void ncr_attach (pcici_t config_id, int unit) np->rv_gpcntl = INB(nc_gpcntl); np->rv_stest2 = INB(nc_stest2) & 0x20; - if (bootverbose) { + if (bootverbose >= 2) { printf ("\tBIOS values: SCNTL3:%02x DMODE:%02x DCNTL:%02x\n", np->rv_scntl3, np->rv_dmode, np->rv_dcntl); printf ("\t CTEST3:%02x CTEST4:%02x CTEST5:%02x\n", @@ -3690,6 +3775,46 @@ static void ncr_attach (pcici_t config_id, int unit) burst_code(np->rv_dmode, np->rv_ctest4, np->rv_ctest5); } +#ifndef NCR_IOMAPPED + /* + ** Get on-board RAM bus address when supported + */ + if ((np->features & FE_RAM) && sizeof(struct script) <= 4096) +#ifdef __NetBSD__ + (void)pci_map_mem(pa->pa_tag, 0x18, &np->vaddr2, &np->paddr2)); +#else /* !__NetBSD__ */ + (void)(!pci_map_mem (config_id,0x18, &np->vaddr2, &np->paddr2)); +#endif /* __NetBSD */ +#endif /* !NCR_IOMAPPED */ + +#ifdef SCSI_NCR_PCI_CONFIG_FIXUP + /* + ** If cache line size is enabled, check PCI config space and + ** try to fix it up if necessary. + */ +#ifdef PCIR_CACHELNSZ /* To be sure that new PCI stuff is present */ + do { + u_char cachelnsz = pci_cfgread(config_id, PCIR_CACHELNSZ, 1); + u_short command = pci_cfgread(config_id, PCIR_COMMAND, 2); + + if (!cachelnsz) { + cachelnsz = 8; + printf("%s: setting PCI cache line size register to %d.\n", + ncr_name(np), (int)cachelnsz); + pci_cfgwrite(config_id, PCIR_CACHELNSZ, cachelnsz, 1); + } + + if (!(command & (1<<4))) { + command |= (1<<4); + printf("%s: setting PCI command write and invalidate.\n", + ncr_name(np)); + pci_cfgwrite(config_id, PCIR_COMMAND, command, 2); + } + } while (0); +#endif /* PCIR_CACHELNSZ */ + +#endif /* SCSI_NCR_PCI_CONFIG_FIXUP */ + /* ** Bells and whistles ;-) */ @@ -3699,11 +3824,32 @@ static void ncr_attach (pcici_t config_id, int unit) (np->rv_ctest5 & DFS) ? "large" : "normal"); /* - ** Patch script to physical addresses + ** Print some complementary information that can be helpfull. + */ + if (bootverbose) + printf("%s: %s, %s IRQ driver%s\n", + ncr_name(np), + np->rv_stest2 & 0x20 ? "differential" : "single-ended", + np->rv_dcntl & IRQM ? "totem pole" : "open drain", + np->vaddr2 ? ", using on-board RAM" : ""); + + /* + ** Patch scripts to physical addresses */ + ncr_script_fill (&script0, &scripth0); + + np->scripth = np->scripth0; + np->p_scripth = vtophys(np->scripth); + + np->script = np->vaddr2 ? (struct script *) np->vaddr2:np->script0; + np->p_script = np->vaddr2 ? np->paddr2 : vtophys(np->script0); + + ncr_script_copy_and_bind (np, (ncrcmd *) &script0, + (ncrcmd *) np->script0, sizeof(struct script)); + + ncr_script_copy_and_bind (np, (ncrcmd *) &scripth0, + (ncrcmd *) np->scripth0, sizeof(struct scripth)); - ncr_script_fill (&script0); - ncr_script_copy_and_bind (&script0, np); np->ccb->p_ccb = vtophys (np->ccb); /* @@ -3711,9 +3857,9 @@ static void ncr_attach (pcici_t config_id, int unit) */ if (np->features & FE_LED0) { - np->script->reselect[0] = SCR_REG_REG(gpreg, SCR_OR, 0x01); - np->script->reselect1[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe); - np->script->reselect2[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe); + np->script0->reselect[0] = SCR_REG_REG(gpreg, SCR_OR, 0x01); + np->script0->reselect1[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe); + np->script0->reselect2[0] = SCR_REG_REG(gpreg, SCR_AND, 0xfe); } /* @@ -3721,7 +3867,7 @@ static void ncr_attach (pcici_t config_id, int unit) */ np->jump_tcb.l_cmd = SCR_JUMP; - np->jump_tcb.l_paddr = NCB_SCRIPT_PHYS (np, abort); + np->jump_tcb.l_paddr = NCB_SCRIPTH_PHYS (np, abort); /* ** Get SCSI addr of host adapter (set by bios?). @@ -4351,7 +4497,7 @@ static int32_t ncr_start (struct scsi_xfer * xp) printf ("%s: queuepos=%d tryoffset=%d.\n", ncr_name (np), np->squeueput, (unsigned)(np->script->startpos[0]- - (NCB_SCRIPT_PHYS (np, tryloop)))); + (NCB_SCRIPTH_PHYS (np, tryloop)))); /* ** Script processor may be waiting for reselect. @@ -4777,7 +4923,7 @@ void ncr_init (ncb_p np, char * msg, u_long code) */ np->squeueput = 0; - np->script->startpos[0] = NCB_SCRIPT_PHYS (np, tryloop); + np->script->startpos[0] = NCB_SCRIPTH_PHYS (np, tryloop); np->script->start0 [0] = SCR_INT ^ IFFALSE (0); /* @@ -4806,7 +4952,7 @@ void ncr_init (ncb_p np, char * msg, u_long code) OUTB (nc_stest3, TE ); /* TolerANT enable */ OUTB (nc_stime0, 0x0b ); /* HTH = disabled, STO = 0.1 sec. */ - if (bootverbose) { + if (bootverbose >= 2) { printf ("\tACTUAL values:SCNTL3:%02x DMODE:%02x DCNTL:%02x\n", np->rv_scntl3, np->rv_dmode, np->rv_dcntl); printf ("\t CTEST3:%02x CTEST4:%02x CTEST5:%02x\n", @@ -4822,6 +4968,15 @@ void ncr_init (ncb_p np, char * msg, u_long code) } /* + ** Upload the script into on-board RAM + */ + if (np->vaddr2) { + if (bootverbose) + printf ("%s: copying script fragments into the on-board RAM ...\n", ncr_name(np)); + bcopy(np->script0, np->script, sizeof(struct script)); + } + + /* ** Reinitialize usrsync. ** Have to renegotiate synch mode. */ @@ -5064,6 +5219,16 @@ static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer) mb10 / 10, mb10 % 10, tp->period / 10, sxfer & 0x1f); } else printf ("asynchronous.\n"); +#if 1 + /* + ** Convert tp->period in nano-seconds since ncrcontrol + ** is expecting nano-seconds. It should be better to + ** update ncrcontrol. + */ + if (tp->period != 0xffff) + tp->period = (tp->period + 9) / 10; +#endif + /* ** set actual value and sync_status */ @@ -5410,6 +5575,78 @@ static void ncr_timeout (void *arg) /*========================================================== ** +** log message for real hard errors +** +** "ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ name (dsp:dbc)." +** " reg: r0 r1 r2 r3 r4 r5 r6 ..... rf." +** +** exception register: +** ds: dstat +** si: sist +** +** SCSI bus lines: +** so: control lines as driver by NCR. +** si: control lines as seen by NCR. +** sd: scsi data lines as seen by NCR. +** +** wide/fastmode: +** sxfer: (see the manual) +** scntl3: (see the manual) +** +** current script command: +** dsp: script adress (relative to start of script). +** dbc: first word of script command. +** +** First 16 register of the chip: +** r0..rf +** +**========================================================== +*/ + +static void ncr_log_hard_error(ncb_p np, u_short sist, u_char dstat) +{ + u_long dsp; + int script_ofs; + int script_size; + char *script_name; + u_char *script_base; + int i; + + dsp = INL (nc_dsp); + + if (dsp > np->p_script && dsp <= np->p_script + sizeof(struct script)) { + script_ofs = dsp - np->p_script; + script_size = sizeof(struct script); + script_base = (u_char *) np->script; + script_name = "script"; + } + else { + script_ofs = dsp - np->p_scripth; + script_size = sizeof(struct scripth); + script_base = (u_char *) np->scripth; + script_name = "scripth"; + } + + printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ %s (%x:%08x).\n", + ncr_name (np), (unsigned)INB (nc_ctest0)&0x0f, dstat, sist, + (unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl), (unsigned)INB (nc_sbdl), + (unsigned)INB (nc_sxfer),(unsigned)INB (nc_scntl3), script_name, script_ofs, + (unsigned)INL (nc_dbc)); + + if (((script_ofs & 3) == 0) && + (unsigned)script_ofs < script_size) { + printf ("%s: script cmd = %08x\n", ncr_name(np), + (int) *(ncrcmd *)(script_base + script_ofs)); + } + + printf ("%s: regdump:", ncr_name(np)); + for (i=0; i<16;i++) + printf (" %02x", (unsigned)INB_OFF(i)); + printf (".\n"); +} + +/*========================================================== +** ** ** ncr chip exception handler. ** @@ -5528,6 +5765,13 @@ void ncr_exception (ncb_p np) }; /*======================================== + ** log message for real hard errors + **======================================== + */ + + ncr_log_hard_error(np, sist, dstat); + + /*======================================== ** do the register dump **======================================== */ @@ -5536,62 +5780,11 @@ void ncr_exception (ncb_p np) int i; gettime(&np->regtime); for (i=0; iregdump); i++) - ((char*)&np->regdump)[i] = ((volatile char*)np->reg)[i]; + ((char*)&np->regdump)[i] = INB_OFF(i); np->regdump.nc_dstat = dstat; np->regdump.nc_sist = sist; }; - /*========================================= - ** log message for real hard errors - **========================================= - - "ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ (dsp:dbc)." - " reg: r0 r1 r2 r3 r4 r5 r6 ..... rf." - - exception register: - ds: dstat - si: sist - - SCSI bus lines: - so: control lines as driver by NCR. - si: control lines as seen by NCR. - sd: scsi data lines as seen by NCR. - - wide/fastmode: - sxfer: (see the manual) - scntl3: (see the manual) - - current script command: - dsp: script adress (relative to start of script). - dbc: first word of script command. - - First 16 register of the chip: - r0..rf - - ============================================= - */ - - dsp = (unsigned) INL (nc_dsp); - dsa = (unsigned) INL (nc_dsa); - - script_ofs = dsp - np->p_script; - - printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%x:%08x).\n", - ncr_name (np), INB (nc_ctest0)&0x0f, dstat, sist, - INB (nc_socl), INB (nc_sbcl), INB (nc_sbdl), - INB (nc_sxfer),INB (nc_scntl3), script_ofs, - (unsigned) INL (nc_dbc)); - - if (((script_ofs & 3) == 0) && - (unsigned)script_ofs < sizeof(struct script)) { - printf ("\tscript cmd = %08x\n", - *(ncrcmd *)((char*)np->script +script_ofs)); - } - - printf ("\treg:\t"); - for (i=0; i<16;i++) - printf (" %02x", ((volatile u_char*)np->reg)[i]); - printf (".\n"); /*---------------------------------------- ** clean up the dma fifo @@ -5787,7 +5980,7 @@ void ncr_int_sto (ncb_p np) */ scratcha = INL (nc_scratcha); - diff = scratcha - NCB_SCRIPT_PHYS (np, tryloop); + diff = scratcha - NCB_SCRIPTH_PHYS (np, tryloop); /* assert ((diff <= MAX_START * 20) && !(diff % 20));*/ @@ -5891,8 +6084,12 @@ static void ncr_int_ma (ncb_p np, u_char dstat) } else if (dsp == vtophys (&cp->patch[6])) { vdsp = &cp->patch[4]; nxtdsp = vdsp[3]; + } else if (dsp > np->p_script && + dsp <= np->p_script + sizeof(struct script)) { + vdsp = (u_long *) ((char*)np->script - np->p_script + dsp -8); + nxtdsp = dsp; } else { - vdsp = (u_long*) ((char*)np->script - np->p_script + dsp -8); + vdsp = (u_long *) ((char*)np->scripth - np->p_scripth+ dsp -8); nxtdsp = dsp; }; @@ -6090,7 +6287,7 @@ void ncr_int_sir (ncb_p np) if (DEBUG_FLAGS & DEBUG_RESTART) printf ("+ restart job ..\n"); OUTL (nc_dsa, CCB_PHYS (cp, phys)); - OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, getcc)); + OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, getcc)); return; }; @@ -6736,7 +6933,7 @@ static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun) tp->call_lun.l_paddr = NCB_SCRIPT_PHYS (np, resel_lun); tp->jump_lcb.l_cmd = (SCR_JUMP); - tp->jump_lcb.l_paddr = NCB_SCRIPT_PHYS (np, abort); + tp->jump_lcb.l_paddr = NCB_SCRIPTH_PHYS (np, abort); np->jump_tcb.l_paddr = vtophys (&tp->jump_tcb); tp->usrtags = SCSI_NCR_DFLT_TAGS; @@ -6765,7 +6962,7 @@ static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun) lp->call_tag.l_paddr = NCB_SCRIPT_PHYS (np, resel_tag); lp->jump_ccb.l_cmd = (SCR_JUMP); - lp->jump_ccb.l_paddr = NCB_SCRIPT_PHYS (np, aborttag); + lp->jump_ccb.l_paddr = NCB_SCRIPTH_PHYS (np, aborttag); lp->actlink = 1; @@ -7060,7 +7257,7 @@ static int ncr_snooptest (struct ncb* np) /* ** init */ - pc = NCB_SCRIPT_PHYS (np, snooptest); + pc = NCB_SCRIPTH_PHYS (np, snooptest); host_wr = 1; ncr_wr = 2; /* @@ -7104,11 +7301,11 @@ static int ncr_snooptest (struct ncb* np) /* ** Check termination position. */ - if (pc != NCB_SCRIPT_PHYS (np, snoopend)+8) { + if (pc != NCB_SCRIPTH_PHYS (np, snoopend)+8) { printf ("CACHE TEST FAILED: script execution failed.\n"); printf ("\tstart=%08x, pc=%08x, end=%08x\n", - NCB_SCRIPT_PHYS (np, snooptest), pc, - NCB_SCRIPT_PHYS (np, snoopend) +8); + NCB_SCRIPTH_PHYS (np, snooptest), pc, + NCB_SCRIPTH_PHYS (np, snoopend) +8); return (0x40); }; /* @@ -7289,7 +7486,7 @@ ncrgetfreq (ncb_p np, int gen) */ OUTB (nc_scntl3, 0); - if (bootverbose) + if (bootverbose >= 2) printf ("\tDelay (GEN=%d): %lu msec\n", gen, ms); /* * adjust for prescaler, and convert into KHz @@ -7317,7 +7514,7 @@ static void ncr_getclock (ncb_p np, u_char multiplier) f1 = ncrgetfreq (np, 11); f2 = ncrgetfreq (np, 11); - if (bootverbose) + if (bootverbose >= 2) printf ("\tNCR clock is %luKHz, %luKHz\n", f1, f2); if (f1 > f2) f1 = f2; /* trust lower result */ if (f1 > 45000) { -- cgit v1.1