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 + -
显示快捷键?