sym_fw1.h

来自「linux 内核源代码」· C头文件 代码 · 共 1,791 行 · 第 1/3 页

H
1,791
字号
}/*-------------------------< MSG_IN2 >--------------------------*/,{	/*	 *  Check first against 1 byte messages 	 *  that we handle from SCRIPTS.	 */	SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),		PADDR_A (complete),	SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),		PADDR_A (disconnect),	SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),		PADDR_A (save_dp),	SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),		PADDR_A (restore_dp),	/*	 *  We handle all other messages from the 	 *  C code, so no need to waste on-chip RAM 	 *  for those ones.	 */	SCR_JUMP,		PADDR_B (msg_in_etc),}/*-------------------------< STATUS >---------------------------*/,{	/*	 *  get the status	 */	SCR_MOVE_ABS (1) ^ SCR_STATUS,		HADDR_1 (scratch),#ifdef SYM_CONF_IARB_SUPPORT	/*	 *  If STATUS is not GOOD, clear IMMEDIATE ARBITRATION, 	 *  since we may have to tamper the start queue from 	 *  the C code.	 */	SCR_JUMPR ^ IFTRUE (DATA (S_GOOD)),		8,	SCR_REG_REG (scntl1, SCR_AND, ~IARB),		0,#endif	/*	 *  save status to scsi_status.	 *  mark as complete.	 */	SCR_TO_REG (SS_REG),		0,	SCR_LOAD_REG (HS_REG, HS_COMPLETE),		0,	/*	 *  Anticipate the MESSAGE PHASE for 	 *  the TASK COMPLETE message.	 */	SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),		PADDR_A (msg_in),	SCR_JUMP,		PADDR_A (dispatch),}/*-------------------------< COMPLETE >-------------------------*/,{	/*	 *  Complete message.	 *	 *  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,}/*-------------------------< COMPLETE2 >------------------------*/,{	/*	 *  Save host status.	 */	SCR_COPY (4),		RADDR_1 (scr0),		HADDR_1 (ccb_head.status),	/*	 *  Move back the CCB header using self-modifying 	 *  SCRIPTS.	 */	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a40),	SCR_COPY (sizeof(struct sym_ccbh)),		HADDR_1 (ccb_head),}/*-------------------------< _SMS_A40 >-------------------------*/,{		0,	/*	 *  Some bridges may reorder DMA writes to memory.	 *  We donnot want the CPU to deal with completions  	 *  without all the posted write having been flushed 	 *  to memory. This DUMMY READ should flush posted 	 *  buffers prior to the CPU having to deal with 	 *  completions.	 */	SCR_COPY (4),			/* DUMMY READ */		HADDR_1 (ccb_head.status),		RADDR_1 (scr0),	/*	 *  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)),		PADDR_B (bad_status),	/*	 *  If we performed an auto-sense, call 	 *  the C code to synchronyze task aborts 	 *  with UNIT ATTENTION conditions.	 */	SCR_FROM_REG (HF_REG),		0,	SCR_JUMP ^ IFFALSE (MASK (0 ,(HF_SENSE|HF_EXT_ERR))),		PADDR_A (complete_error),}/*-------------------------< DONE >-----------------------------*/,{	/*	 *  Copy the DSA to the DONE QUEUE and 	 *  signal completion to the host.	 *  If we are interrupted between DONE 	 *  and DONE_END, we must reset, otherwise 	 *  the completed CCB may be lost.	 */	SCR_COPY (4),		PADDR_B (done_pos),		PADDR_A (_sms_a50),	SCR_COPY (4),		RADDR_1 (dsa),}/*-------------------------< _SMS_A50 >-------------------------*/,{		0,	SCR_COPY (4),		PADDR_B (done_pos),		PADDR_A (_sms_a60),	/*	 *  The instruction below reads the DONE QUEUE next 	 *  free position from memory.	 *  In addition it ensures that all PCI posted writes  	 *  are flushed and so the DSA value of the done 	 *  CCB is visible by the CPU before INTFLY is raised.	 */	SCR_COPY (8),}/*-------------------------< _SMS_A60 >-------------------------*/,{		0,		PADDR_B (prev_done),}/*-------------------------< DONE_END >-------------------------*/,{	SCR_INT_FLY,		0,	SCR_JUMP,		PADDR_A (start),}/*-------------------------< COMPLETE_ERROR >-------------------*/,{	SCR_COPY (4),		PADDR_B (startpos),		RADDR_1 (scratcha),	SCR_INT,		SIR_COMPLETE_ERROR,}/*-------------------------< SAVE_DP >--------------------------*/,{	/*	 *  Clear ACK immediately.	 *  No need to delay it.	 */	SCR_CLR (SCR_ACK),		0,	/*	 *  Keep track we received a SAVE DP, so 	 *  we will switch to the other PM context 	 *  on the next PM since the DP may point 	 *  to the current PM context.	 */	SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED),		0,	/*	 *  SAVE_DP message:	 *  Copy LASTP to SAVEP.	 */	SCR_COPY (4),		HADDR_1 (ccb_head.lastp),		HADDR_1 (ccb_head.savep),	/*	 *  Anticipate the MESSAGE PHASE for 	 *  the DISCONNECT message.	 */	SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),		PADDR_A (msg_in),	SCR_JUMP,		PADDR_A (dispatch),}/*-------------------------< RESTORE_DP >-----------------------*/,{	/*	 *  Clear ACK immediately.	 *  No need to delay it.	 */	SCR_CLR (SCR_ACK),		0,	/*	 *  Copy SAVEP to LASTP.	 */	SCR_COPY (4),		HADDR_1 (ccb_head.savep),		HADDR_1 (ccb_head.lastp),	SCR_JUMP,		PADDR_A (dispatch),}/*-------------------------< 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,	/*	 *  Status is: DISCONNECTED.	 */	SCR_LOAD_REG (HS_REG, HS_DISCONNECT),		0,	/*	 *  Save host status.	 */	SCR_COPY (4),		RADDR_1 (scr0),		HADDR_1 (ccb_head.status),}/*-------------------------< DISCONNECT2 >----------------------*/,{	/*	 *  Move back the CCB header using self-modifying 	 *  SCRIPTS.	 */	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a65),	SCR_COPY (sizeof(struct sym_ccbh)),		HADDR_1 (ccb_head),}/*-------------------------< _SMS_A65 >-------------------------*/,{		0,	SCR_JUMP,		PADDR_A (start),}/*-------------------------< IDLE >-----------------------------*/,{	/*	 *  Nothing to do?	 *  Switch the LED off and wait for reselect.	 *  Will be patched with a NO_OP if LED	 *  not needed or not desired.	 */	SCR_REG_REG (gpreg, SCR_OR, 0x01),		0,#ifdef SYM_CONF_IARB_SUPPORT	SCR_JUMPR,		8,#endif}/*-------------------------< UNGETJOB >-------------------------*/,{#ifdef SYM_CONF_IARB_SUPPORT	/*	 *  Set IMMEDIATE ARBITRATION, for the next time.	 *  This will give us better chance to win arbitration 	 *  for the job we just wanted to do.	 */	SCR_REG_REG (scntl1, SCR_OR, IARB),		0,#endif	/*	 *  We are not able to restart the SCRIPTS if we are 	 *  interrupted and these instruction haven't been 	 *  all executed. BTW, this is very unlikely to 	 *  happen, but we check that from the C code.	 */	SCR_LOAD_REG (dsa, 0xff),		0,	SCR_COPY (4),		RADDR_1 (scratcha),		PADDR_B (startpos),}/*-------------------------< RESELECT >-------------------------*/,{#ifdef SYM_CONF_TARGET_ROLE_SUPPORT	/*	 *  Make sure we are in initiator mode.	 */	SCR_CLR (SCR_TRG),		0,#endif	/*	 *  Sleep waiting for a reselection.	 */	SCR_WAIT_RESEL,		PADDR_A(start),}/*-------------------------< RESELECTED >-----------------------*/,{	/*	 *  Switch the LED on.	 *  Will be patched with a NO_OP if LED	 *  not needed or not desired.	 */	SCR_REG_REG (gpreg, SCR_AND, 0xfe),		0,	/*	 *  load the target id into the sdid	 */	SCR_REG_SFBR (ssid, SCR_AND, 0x8F),		0,	SCR_TO_REG (sdid),		0,	/*	 *  Load the target control block address	 */	SCR_COPY (4),		PADDR_B (targtbl),		RADDR_1 (dsa),	SCR_SFBR_REG (dsa, SCR_SHL, 0),		0,	SCR_REG_REG (dsa, SCR_SHL, 0),		0,	SCR_REG_REG (dsa, SCR_AND, 0x3c),		0,	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a70),	SCR_COPY (4),}/*-------------------------< _SMS_A70 >-------------------------*/,{		0,		RADDR_1 (dsa),	/*	 *  Copy the TCB header to a fixed place in 	 *  the HCB.	 */	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a80),	SCR_COPY (sizeof(struct sym_tcbh)),}/*-------------------------< _SMS_A80 >-------------------------*/,{		0,		HADDR_1 (tcb_head),	/*	 *  We expect MESSAGE IN phase.	 *  If not, get help from the C code.	 */	SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),		SIR_RESEL_NO_MSG_IN,}/*-------------------------< RESELECTED1 >----------------------*/,{	/*	 *  Load the synchronous transfer registers.	 */	SCR_COPY (1),		HADDR_1 (tcb_head.wval),		RADDR_1 (scntl3),	SCR_COPY (1),		HADDR_1 (tcb_head.sval),		RADDR_1 (sxfer),	/*	 *  Get the IDENTIFY message.	 */	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,		HADDR_1 (msgin),	/*	 *  If IDENTIFY LUN #0, use a faster path 	 *  to find the LCB structure.	 */	SCR_JUMP ^ IFTRUE (MASK (0x80, 0xbf)),		PADDR_A (resel_lun0),	/*	 *  If message isn't an IDENTIFY, 	 *  tell the C code about.	 */	SCR_INT ^ IFFALSE (MASK (0x80, 0x80)),		SIR_RESEL_NO_IDENTIFY,	/*	 *  It is an IDENTIFY message,	 *  Load the LUN control block address.	 */	SCR_COPY (4),		HADDR_1 (tcb_head.luntbl_sa),		RADDR_1 (dsa),	SCR_SFBR_REG (dsa, SCR_SHL, 0),		0,	SCR_REG_REG (dsa, SCR_SHL, 0),		0,	SCR_REG_REG (dsa, SCR_AND, 0xfc),		0,	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a90),	SCR_COPY (4),}/*-------------------------< _SMS_A90 >-------------------------*/,{		0,		RADDR_1 (dsa),	SCR_JUMPR,		12,}/*-------------------------< RESEL_LUN0 >-----------------------*/,{	/*	 *  LUN 0 special case (but usual one :))	 */	SCR_COPY (4),		HADDR_1 (tcb_head.lun0_sa),		RADDR_1 (dsa),	/*	 *  Jump indirectly to the reselect action for this LUN.	 *  (lcb.head.resel_sa assumed at offset zero of lcb).	 */	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a100),	SCR_COPY (4),}/*-------------------------< _SMS_A100 >------------------------*/,{		0,		RADDR_1 (temp),	SCR_RETURN,		0,	/* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */}/*-------------------------< RESEL_TAG >------------------------*/,{	/*	 *  ACK the IDENTIFY previously received.	 */	SCR_CLR (SCR_ACK),		0,	/*	 *  It shall be a tagged command.	 *  Read SIMPLE+TAG.	 *  The C code will deal with errors.	 *  Aggressive optimization, isn't it? :)	 */	SCR_MOVE_ABS (2) ^ SCR_MSG_IN,		HADDR_1 (msgin),	/*	 *  Copy the LCB header to a fixed place in 	 *  the HCB using self-modifying SCRIPTS.	 */	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a110),	SCR_COPY (sizeof(struct sym_lcbh)),}/*-------------------------< _SMS_A110 >------------------------*/,{		0,		HADDR_1 (lcb_head),	/*	 *  Load the pointer to the tagged task 	 *  table for this LUN.	 */	SCR_COPY (4),		HADDR_1 (lcb_head.itlq_tbl_sa),		RADDR_1 (dsa),	/*	 *  The SIDL still contains the TAG value.	 *  Aggressive optimization, isn't it? :):)	 */	SCR_REG_SFBR (sidl, SCR_SHL, 0),		0,#if SYM_CONF_MAX_TASK*4 > 512	SCR_JUMPR ^ IFFALSE (CARRYSET),		8,	SCR_REG_REG (dsa1, SCR_OR, 2),		0,	SCR_REG_REG (sfbr, SCR_SHL, 0),		0,	SCR_JUMPR ^ IFFALSE (CARRYSET),		8,	SCR_REG_REG (dsa1, SCR_OR, 1),		0,#elif SYM_CONF_MAX_TASK*4 > 256	SCR_JUMPR ^ IFFALSE (CARRYSET),		8,	SCR_REG_REG (dsa1, SCR_OR, 1),		0,#endif	/*	 *  Retrieve the DSA of this task.	 *  JUMP indirectly to the restart point of the CCB.	 */	SCR_SFBR_REG (dsa, SCR_AND, 0xfc),		0,	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a120),	SCR_COPY (4),}/*-------------------------< _SMS_A120 >------------------------*/,{		0,		RADDR_1 (dsa),}/*-------------------------< RESEL_GO >-------------------------*/,{	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a130),	/*	 *  Move 'ccb.phys.head.go' action to 	 *  scratch/scratch1. So scratch1 will 	 *  contain the 'restart' field of the 	 *  'go' structure.	 */	SCR_COPY (8),}/*-------------------------< _SMS_A130 >------------------------*/,{		0,		PADDR_B (scratch),	SCR_COPY (4),		PADDR_B (scratch1), /* phys.head.go.restart */		RADDR_1 (temp),	SCR_RETURN,		0,	/* In normal situations we branch to RESEL_DSA */}/*-------------------------< RESEL_DSA >------------------------*/,{	/*	 *  ACK the IDENTIFY or TAG previously received.	 */	SCR_CLR (SCR_ACK),		0,}/*-------------------------< RESEL_DSA1 >-----------------------*/,{	/*	 *  Copy the CCB header to a fixed location 	 *  in the HCB using self-modifying SCRIPTS.	 */	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a140),	SCR_COPY (sizeof(struct sym_ccbh)),}/*-------------------------< _SMS_A140 >------------------------*/,{		0,		HADDR_1 (ccb_head),	/*	 *  Initialize the status register	 */	SCR_COPY (4),		HADDR_1 (ccb_head.status),		RADDR_1 (scr0),	/*	 *  Jump to dispatcher.	 */	SCR_JUMP,		PADDR_A (dispatch),}/*-------------------------< RESEL_NO_TAG >---------------------*/,{	/*	 *  Copy the LCB header to a fixed place in 	 *  the HCB using self-modifying SCRIPTS.	 */	SCR_COPY (4),		RADDR_1 (dsa),		PADDR_A (_sms_a145),	SCR_COPY (sizeof(struct sym_lcbh)),}/*-------------------------< _SMS_A145 >------------------------*/,{		0,		HADDR_1 (lcb_head),	/*	 *  Load the DSA with the unique ITL task.	 */	SCR_COPY (4),		HADDR_1 (lcb_head.itl_task_sa),		RADDR_1 (dsa),	SCR_JUMP,		PADDR_A (resel_go),}/*-------------------------< DATA_IN >--------------------------*/,{/* *  Because the size depends on the *  #define SYM_CONF_MAX_SG parameter, *  it is filled in at runtime. * *  ##===========< i=0; i<SYM_CONF_MAX_SG >========= *  ||	SCR_CHMOV_TBL ^ SCR_DATA_IN, *  ||		offsetof (struct sym_dsb, data[ i]), *  ##========================================== */0}/*-------------------------< DATA_IN2 >-------------------------*/,{	SCR_CALL,		PADDR_A (datai_done),	SCR_JUMP,		PADDR_B (data_ovrun),}/*-------------------------< DATA_OUT >-------------------------*/,{/* *  Because the size depends on the *  #define SYM_CONF_MAX_SG parameter, *  it is filled in at runtime. * *  ##===========< i=0; i<SYM_CONF_MAX_SG >========= *  ||	SCR_CHMOV_TBL ^ SCR_DATA_OUT, *  ||		offsetof (struct sym_dsb, data[ i]), *  ##========================================== */0}/*-------------------------< DATA_OUT2 >------------------------*/,{	SCR_CALL,		PADDR_A (datao_done),	SCR_JUMP,		PADDR_B (data_ovrun),}/*-------------------------< PM0_DATA >-------------------------*/,{	/*	 *  Read our host flags to SFBR, so we will be able 	 *  to check against the data direction we expect.	 */	SCR_FROM_REG (HF_REG),		0,	/*	 *  Check against actual DATA PHASE.	 */	SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?