📄 ncr53c8xx.c
字号:
PADDR (cleanup_ok),}/*-------------------------< COMPLETE >-----------------*/,{ /* ** Complete message. ** ** Copy TEMP register to LASTP in header. */ 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_OK >----------------*/,{ /* ** Save host status to header. */ 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,}/*-------------------------< SIGNAL >----------------------*/,{ /* ** if job not completed ... */ SCR_FROM_REG (HS_REG), 0, /* ** ... start the next command. */ SCR_JUMP ^ IFTRUE (MASK (0, (HS_DONEMASK|HS_SKIPMASK))), PADDR(start), /* ** If command resulted in not GOOD status, ** call the C code if needed. */ SCR_FROM_REG (SS_REG), 0, SCR_CALL ^ IFFALSE (DATA (S_GOOD)), PADDRH (bad_status),#ifndef SCSI_NCR_CCB_DONE_SUPPORT /* ** ... signal completion to the host */ SCR_INT_FLY, 0, /* ** Auf zu neuen Schandtaten! */ SCR_JUMP, PADDR(start),#else /* defined SCSI_NCR_CCB_DONE_SUPPORT */ /* ** ... signal completion to the host */ SCR_JUMP,}/*------------------------< DONE_POS >---------------------*/,{ PADDRH (done_queue),}/*------------------------< DONE_PLUG >--------------------*/,{ SCR_INT, SIR_DONE_OVERFLOW,}/*------------------------< DONE_END >---------------------*/,{ SCR_INT_FLY, 0, SCR_COPY (4), RADDR (temp), PADDR (done_pos), SCR_JUMP, PADDR (start),#endif /* SCSI_NCR_CCB_DONE_SUPPORT */}/*-------------------------< SAVE_DP >------------------*/,{ /* ** SAVE_DP message: ** Copy TEMP register to SAVEP in header. */ SCR_COPY (4), RADDR (temp), NADDR (header.savep), SCR_CLR (SCR_ACK), 0, SCR_JUMP, PADDR (dispatch),}/*-------------------------< 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 >---------------*/,{ /* ** 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,#ifdef SCSI_NCR_PROFILE_SUPPORT /* ** Profiling: ** Set a time stamp, ** and count the disconnects. */ SCR_COPY (sizeof (u_long)), NADDR (ktime), NADDR (header.stamp.disconnect), SCR_COPY (4), NADDR (disc_phys), RADDR (scratcha), SCR_REG_REG (scratcha, SCR_ADD, 0x01), 0, SCR_COPY (4), RADDR (scratcha), NADDR (disc_phys),#endif /* ** Status is: DISCONNECTED. */ SCR_LOAD_REG (HS_REG, HS_DISCONNECT), 0, /* ** If QUIRK_AUTOSAVE is set, ** do an "save pointer" operation. */ SCR_FROM_REG (QU_REG), 0, SCR_JUMP ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)), PADDR (cleanup_ok), /* ** like SAVE_DP message: ** Copy TEMP register to SAVEP in header. */ SCR_COPY (4), RADDR (temp), NADDR (header.savep), SCR_JUMP, PADDR (cleanup_ok),}/*-------------------------< MSG_OUT >-------------------*/,{ /* ** The target requests a message. */ SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, NADDR (msgout), SCR_COPY (1), NADDR (msgout), 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),}/*-------------------------< IDLE >------------------------*/,{ /* ** Nothing to do? ** Wait for reselect. ** This NOP will be patched with LED OFF ** SCR_REG_REG (gpreg, SCR_OR, 0x01) */ SCR_NO_OP, 0,}/*-------------------------< RESELECT >--------------------*/,{ /* ** make the DSA invalid. */ SCR_LOAD_REG (dsa, 0xff), 0, SCR_CLR (SCR_TRG), 0, SCR_LOAD_REG (HS_REG, HS_IN_RESELECT), 0, /* ** Sleep waiting for a reselection. ** If SIGP is set, special treatment. ** ** Zu allem bereit .. */ SCR_WAIT_RESEL, PADDR(start),}/*-------------------------< RESELECTED >------------------*/,{ /* ** 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 (sdid), 0, SCR_JUMP, NADDR (jump_tcb),}/*-------------------------< RESEL_DSA >-------------------*/,{ /* ** Ack the IDENTIFY or TAG previously received. */ SCR_CLR (SCR_ACK), 0, /* ** The ncr doesn't have an indirect load ** or store command. So we have to ** copy part of the control block to a ** fixed place, where we can access it. ** ** We patch the address part of a ** COPY command with the DSA-register. */ SCR_COPY_F (4), RADDR (dsa), PADDR (loadpos1), /* ** then we do the actual copy. */ SCR_COPY (sizeof (struct head)), /* ** continued after the next label ... */}/*-------------------------< LOADPOS1 >-------------------*/,{ 0, NADDR (header),#ifdef SCSI_NCR_PROFILE_SUPPORT /* ** Set a time stamp for this reselection */ SCR_COPY (sizeof (u_long)), NADDR (ktime), NADDR (header.stamp.reselect),#endif /* ** The DSA contains the data structure address. */ SCR_JUMP, PADDR (prepare),}/*-------------------------< RESEL_LUN >-------------------*/,{ /* ** come back to this point ** to get an IDENTIFY message ** Wait for a msg_in phase. */ SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)), SIR_RESEL_NO_MSG_IN, /* ** message phase. ** Read the data directly from the BUS DATA lines. ** This helps to support very old SCSI devices that ** may reselect without sending an IDENTIFY. */ SCR_FROM_REG (sbdl), 0, /* ** It should be an Identify message. */ SCR_RETURN, 0,}/*-------------------------< RESEL_TAG >-------------------*/,{ /* ** Read IDENTIFY + SIMPLE + TAG using a single MOVE. ** Agressive optimization, is'nt it? ** No need to test the SIMPLE TAG message, since the ** driver only supports conformant devices for tags. ;-) */ SCR_MOVE_ABS (3) ^ SCR_MSG_IN, NADDR (msgin), /* ** Read the TAG from the SIDL. ** Still an aggressive optimization. ;-) ** Compute the CCB indirect jump address which ** is (#TAG*2 & 0xfc) due to tag numbering using ** 1,3,5..MAXTAGS*2+1 actual values. */ SCR_REG_SFBR (sidl, SCR_SHL, 0), 0, SCR_SFBR_REG (temp, SCR_AND, 0xfc), 0,}/*-------------------------< JUMP_TO_NEXUS >-------------------*/,{ SCR_COPY_F (4), RADDR (temp), PADDR (nexus_indirect), SCR_COPY (4),}/*-------------------------< NEXUS_INDIRECT >-------------------*/,{ 0, RADDR (temp), SCR_RETURN, 0,}/*-------------------------< RESEL_NOTAG >-------------------*/,{ /* ** No tag expected. ** Read an throw away the IDENTIFY. */ SCR_MOVE_ABS (1) ^ SCR_MSG_IN, NADDR (msgin), SCR_JUMP, PADDR (jump_to_nexus),}/*-------------------------< DATA_IN >--------------------*/,{/*** Because the size depends on the** #define MAX_SCATTERL parameter,** it is filled in at runtime.**** ##===========< i=0; i<MAX_SCATTERL >=========** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN)),** || PADDR (dispatch),** || SCR_MOVE_TBL ^ SCR_DATA_IN,** || offsetof (struct dsb, data[ i]),** ##==========================================****---------------------------------------------------------*/0}/*-------------------------< DATA_IN2 >-------------------*/,{ SCR_CALL, PADDR (dispatch), SCR_JUMP, PADDR (no_data),}/*-------------------------< DATA_OUT >--------------------*/,{/*** Because the size depends on the** #define MAX_SCATTERL parameter,** it is filled in at runtime.**** ##===========< i=0; i<MAX_SCATTERL >=========** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT)),** || PADDR (dispatch),** || SCR_MOVE_TBL ^ SCR_DATA_OUT,** || offsetof (struct dsb, data[ i]),** ##==========================================****---------------------------------------------------------*/0}/*-------------------------< DATA_OUT2 >-------------------*/,{ SCR_CALL, PADDR (dispatch), SCR_JUMP, PADDR (no_data),}/*--------------------------------------------------------*/};static struct scripth scripth0 __initdata = {/*-------------------------< TRYLOOP >---------------------*/{/*** Start the next entry.** Called addresses point to the launch script in the CCB.** They are patched by the main processor.**** Because the size depends on the** #define MAX_START parameter, it is filled** in at runtime.****-----------------------------------------------------------**** ##===========< I=0; i<MAX_START >===========** || SCR_CALL,** || PADDR (idle),** ##==========================================****-----------------------------------------------------------*/0}/*------------------------< TRYLOOP2 >---------------------*/,{ SCR_JUMP, PADDRH(tryloop),#ifdef SCSI_NCR_CCB_DONE_SUPPORT}/*------------------------< DONE_QUEUE >-------------------*/,{/*** Copy the CCB address to the next done entry.** Because the size depends on the** #define MAX_DONE parameter, it is filled** in at runtime.****-----------------------------------------------------------**** ##===========< I=0; i<MAX_DONE >===========** || SCR_COPY (sizeof(ccb_p)),** || NADDR (header.cp),** || NADDR (ccb_done[i]),** || SCR_CALL,** || PADDR (done_end),** ##==========================================****-----------------------------------------------------------*/0}/*------------------------< DONE_QUEUE2 >-----
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -