📄 sym_fw1.h
字号:
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. * Agressive optimization, is'nt 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. * Agressive 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)), PADDR_A (pm0_data_out), /* * Actual phase is DATA IN. * Check against expected direction. */ SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), PADDR_B (data_ovrun), /* * Keep track we are moving data from the * PM0 DATA mini-script. */ SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 0, /* * Move the data to memory. */ SCR_CHMOV_TBL ^ SCR_DATA_IN, offsetof (struct sym_ccb, phys.pm0.sg), SCR_JUMP, PADDR_A (pm0_data_end),}/*-------------------------< PM0_DATA_OUT >---------------------*/,{ /* * Actual phase is DATA OUT. * Check against expected direction. */ SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), PADDR_B (data_ovrun), /* * Keep track we are moving data from the * PM0 DATA mini-script. */ SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 0, /* * Move the data from memory. */ SCR_CHMOV_TBL ^ SCR_DATA_OUT, offsetof (struct sym_ccb, phys.pm0.sg),}/*-------------------------< PM0_DATA_END >---------------------*/,{ /* * Clear the flag that told we were moving * data from the PM0 DATA mini-script. */ SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)), 0, /* * Return to the previous DATA script which * is guaranteed by design (if no bug) to be * the main DATA script for this transfer. */ SCR_COPY (4), RADDR_1 (dsa), RADDR_1 (scratcha), SCR_REG_REG (scratcha, SCR_ADD, offsetof (struct sym_ccb,phys.pm0.ret)), 0,}/*-------------------------< PM_DATA_END >----------------------*/,{ SCR_COPY (4), RADDR_1 (scratcha), PADDR_A (_sms_a150), SCR_COPY (4),}/*-------------------------< _SMS_A150 >------------------------*/,{ 0, RADDR_1 (temp), SCR_RETURN, 0,}/*-------------------------< PM1_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)), PADDR_A (pm1_data_out), /* * Actual phase is DATA IN. * Check against expected direction. */ SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), PADDR_B (data_ovrun), /* * Keep track we are moving data from the * PM1 DATA mini-script. */ SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 0, /* * Move the data to memory. */ SCR_CHMOV_TBL ^ SCR_DATA_IN, offsetof (struct sym_ccb, phys.pm1.sg), SCR_JUMP, PADDR_A (pm1_data_end),}/*-------------------------< PM1_DATA_OUT >---------------------*/,{ /* * Actual phase is DATA OUT. * Check against expected direction. */ SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), PADDR_B (data_ovrun), /* * Keep track we are moving data from the * PM1 DATA mini-script. */ SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 0, /* * Move the data from memory. */ SCR_CHMOV_TBL ^ SCR_DATA_OUT, offsetof (struct sym_ccb, phys.pm1.sg),}/*-------------------------< PM1_DATA_END >---------------------*/,{ /* * Clear the flag that told we were moving * data from the PM1 DATA mini-script. */ SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)), 0, /* * Return to the previous DATA script which * is guaranteed by design (if no bug) to be * the main DATA script for this transfer. */ SCR_COPY (4), RADDR_1 (dsa), RADDR_1 (scratcha), SCR_REG_REG (scratcha, SCR_ADD, offsetof (struct sym_ccb,phys.pm1.ret)), 0, SCR_JUMP, PADDR_A (pm_data_end),}/*--------------------------<>----------------------------------*/};static struct SYM_FWB_SCR SYM_FWB_SCR = {/*-------------------------< NO_DATA >--------------------------*/ { SCR_JUMP, PADDR_B (data_ovrun),}/*-------------------------< SEL_FOR_ABORT >--------------------*/,{ /* * We are jumped here by the C code, if we have * some target to reset or some disconnected * job to abort. Since error recovery is a serious * busyness, we will really reset the SCSI BUS, if * case of a SCSI interrupt occurring in this path. */#ifdef SYM_CONF_TARGET_ROLE_SUPPORT /* * Set initiator mode. */ SCR_CLR (SCR_TRG), 0,#endif /* * And try to select this target. */ SCR_SEL_TBL_ATN ^ offsetof (struct sym_hcb, abrt_sel), PADDR_A (reselect), /* * Wait for the selection to complete or * the selection to time out. */ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)), -8, /* * Call the C code. */ SCR_INT, SIR_TARGET_SELECTED, /* * The C code should let us continue here. * Send the 'kiss of death' message. * We expect an immediate disconnect once * the target has eaten the message. */ SCR_REG_REG (scntl2, SCR_AND, 0x7f), 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -