📄 sym_fw1.h
字号:
/* * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family * of PCI-SCSI IO processors. * * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier * * The sym53c8xx driver is derived from the ncr53c8xx driver that had been * a port of the FreeBSD ncr driver to Linux-1.2.13. * * The original ncr driver has been written for 386bsd and FreeBSD by * Wolfgang Stanglmeier <wolf@cologne.de> * Stefan Esser <se@mi.Uni-Koeln.de> * Copyright (C) 1994 Wolfgang Stanglmeier * * Other major contributions: * * NVRAM detection and reading. * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> * *----------------------------------------------------------------------------- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * Scripts for SYMBIOS-Processor * * We have to know the offsets of all labels before we reach * them (for forward jumps). Therefore we declare a struct * here. If you make changes inside the script, * * DONT FORGET TO CHANGE THE LENGTHS HERE! *//* * Script fragments which are loaded into the on-chip RAM * of 825A, 875, 876, 895, 895A, 896 and 1010 chips. * Must not exceed 4K bytes. */struct SYM_FWA_SCR { u32 start [ 11]; u32 getjob_begin [ 4]; u32 _sms_a10 [ 5]; u32 getjob_end [ 4]; u32 _sms_a20 [ 4];#ifdef SYM_CONF_TARGET_ROLE_SUPPORT u32 select [ 8];#else u32 select [ 6];#endif u32 _sms_a30 [ 5]; u32 wf_sel_done [ 2]; u32 send_ident [ 2];#ifdef SYM_CONF_IARB_SUPPORT u32 select2 [ 8];#else u32 select2 [ 2];#endif u32 command [ 2]; u32 dispatch [ 28]; u32 sel_no_cmd [ 10]; u32 init [ 6]; u32 clrack [ 4]; u32 datai_done [ 11]; u32 datai_done_wsr [ 20]; u32 datao_done [ 11]; u32 datao_done_wss [ 6]; u32 datai_phase [ 5]; u32 datao_phase [ 5]; u32 msg_in [ 2]; u32 msg_in2 [ 10];#ifdef SYM_CONF_IARB_SUPPORT u32 status [ 14];#else u32 status [ 10];#endif u32 complete [ 6]; u32 complete2 [ 8]; u32 _sms_a40 [ 12]; u32 done [ 5]; u32 _sms_a50 [ 5]; u32 _sms_a60 [ 2]; u32 done_end [ 4]; u32 complete_error [ 5]; u32 save_dp [ 11]; u32 restore_dp [ 7]; u32 disconnect [ 11]; u32 disconnect2 [ 5]; u32 _sms_a65 [ 3];#ifdef SYM_CONF_IARB_SUPPORT u32 idle [ 4];#else u32 idle [ 2];#endif#ifdef SYM_CONF_IARB_SUPPORT u32 ungetjob [ 7];#else u32 ungetjob [ 5];#endif#ifdef SYM_CONF_TARGET_ROLE_SUPPORT u32 reselect [ 4];#else u32 reselect [ 2];#endif u32 reselected [ 19]; u32 _sms_a70 [ 6]; u32 _sms_a80 [ 4]; u32 reselected1 [ 25]; u32 _sms_a90 [ 4]; u32 resel_lun0 [ 7]; u32 _sms_a100 [ 4]; u32 resel_tag [ 8];#if SYM_CONF_MAX_TASK*4 > 512 u32 _sms_a110 [ 23];#elif SYM_CONF_MAX_TASK*4 > 256 u32 _sms_a110 [ 17];#else u32 _sms_a110 [ 13];#endif u32 _sms_a120 [ 2]; u32 resel_go [ 4]; u32 _sms_a130 [ 7]; u32 resel_dsa [ 2]; u32 resel_dsa1 [ 4]; u32 _sms_a140 [ 7]; u32 resel_no_tag [ 4]; u32 _sms_a145 [ 7]; u32 data_in [SYM_CONF_MAX_SG * 2]; u32 data_in2 [ 4]; u32 data_out [SYM_CONF_MAX_SG * 2]; u32 data_out2 [ 4]; u32 pm0_data [ 12]; u32 pm0_data_out [ 6]; u32 pm0_data_end [ 7]; u32 pm_data_end [ 4]; u32 _sms_a150 [ 4]; u32 pm1_data [ 12]; u32 pm1_data_out [ 6]; u32 pm1_data_end [ 9];};/* * Script fragments which stay in main memory for all chips * except for chips that support 8K on-chip RAM. */struct SYM_FWB_SCR { u32 no_data [ 2];#ifdef SYM_CONF_TARGET_ROLE_SUPPORT u32 sel_for_abort [ 18];#else u32 sel_for_abort [ 16];#endif u32 sel_for_abort_1 [ 2]; u32 msg_in_etc [ 12]; u32 msg_received [ 5]; u32 msg_weird_seen [ 5]; u32 msg_extended [ 17]; u32 _sms_b10 [ 4]; u32 msg_bad [ 6]; u32 msg_weird [ 4]; u32 msg_weird1 [ 8]; u32 wdtr_resp [ 6]; u32 send_wdtr [ 4]; u32 sdtr_resp [ 6]; u32 send_sdtr [ 4]; u32 ppr_resp [ 6]; u32 send_ppr [ 4]; u32 nego_bad_phase [ 4]; u32 msg_out [ 4]; u32 msg_out_done [ 4]; u32 data_ovrun [ 3]; u32 data_ovrun1 [ 22]; u32 data_ovrun2 [ 8]; u32 abort_resel [ 16]; u32 resend_ident [ 4]; u32 ident_break [ 4]; u32 ident_break_atn [ 4]; u32 sdata_in [ 6]; u32 resel_bad_lun [ 4]; u32 bad_i_t_l [ 4]; u32 bad_i_t_l_q [ 4]; u32 bad_status [ 7]; u32 wsr_ma_helper [ 4];#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN /* Unknown direction handling */ u32 data_io [ 2]; u32 data_io_com [ 8]; u32 data_io_out [ 7];#endif /* Data area */ u32 zero [ 1]; u32 scratch [ 1]; u32 scratch1 [ 1]; u32 prev_done [ 1]; u32 done_pos [ 1]; u32 nextjob [ 1]; u32 startpos [ 1]; u32 targtbl [ 1];};/* * Script fragments used at initialisations. * Only runs out of main memory. */struct SYM_FWZ_SCR { u32 snooptest [ 9]; u32 snoopend [ 2];};static struct SYM_FWA_SCR SYM_FWA_SCR = {/*--------------------------< START >----------------------------*/ { /* * 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, /* * Clear SIGP. */ SCR_FROM_REG (ctest2), 0, /* * Stop here if the C code wants to perform * some error recovery procedure manually. * (Indicate this by setting SEM in ISTAT) */ SCR_FROM_REG (istat), 0, /* * Report to the C code the next position in * the start queue the SCRIPTS will schedule. * The C code must not change SCRATCHA. */ SCR_COPY (4), PADDR_B (startpos), RADDR_1 (scratcha), SCR_INT ^ IFTRUE (MASK (SEM, SEM)), SIR_SCRIPT_STOPPED, /* * Start the next job. * * @DSA = start point for this job. * SCRATCHA = address of this job in the start queue. * * We will restore startpos with SCRATCHA if we fails the * arbitration or if it is the idle job. * * The below GETJOB_BEGIN to GETJOB_END section of SCRIPTS * is a critical path. If it is partially executed, it then * may happen that the job address is not yet in the DSA * and the next queue position points to the next JOB. */}/*-------------------------< GETJOB_BEGIN >---------------------*/,{ /* * Copy to a fixed location both the next STARTPOS * and the current JOB address, using self modifying * SCRIPTS. */ SCR_COPY (4), RADDR_1 (scratcha), PADDR_A (_sms_a10), SCR_COPY (8),}/*-------------------------< _SMS_A10 >-------------------------*/,{ 0, PADDR_B (nextjob), /* * Move the start address to TEMP using self- * modifying SCRIPTS and jump indirectly to * that address. */ SCR_COPY (4), PADDR_B (nextjob), RADDR_1 (dsa),}/*-------------------------< GETJOB_END >-----------------------*/,{ SCR_COPY (4), RADDR_1 (dsa), PADDR_A (_sms_a20), SCR_COPY (4),}/*-------------------------< _SMS_A20 >-------------------------*/,{ 0, RADDR_1 (temp), SCR_RETURN, 0,}/*-------------------------< SELECT >---------------------------*/,{ /* * DSA contains the address of a scheduled * data structure. * * SCRATCHA contains the address of the start queue * entry which points to the next job. * * Set Initiator mode. * * (Target mode is left as an exercise for the reader) */#ifdef SYM_CONF_TARGET_ROLE_SUPPORT SCR_CLR (SCR_TRG), 0,#endif /* * And try to select this target. */ SCR_SEL_TBL_ATN ^ offsetof (struct sym_dsb, select), PADDR_A (ungetjob), /* * Now there are 4 possibilities: * * (1) The chip loses arbitration. * This is ok, because it will try again, * when the bus becomes idle. * (But beware of the timeout function!) * * (2) The chip is reselected. * Then the script processor takes the jump * to the RESELECT label. * * (3) The chip wins arbitration. * Then it will execute SCRIPTS instruction until * the next instruction that checks SCSI phase. * Then will stop and wait for selection to be * complete or selection time-out to occur. * * After having won arbitration, the SCRIPTS * processor is able to execute instructions while * the SCSI core is performing SCSI selection. */ /* * Copy the CCB header to a fixed location * in the HCB using self-modifying SCRIPTS. */ SCR_COPY (4), RADDR_1 (dsa), PADDR_A (_sms_a30), SCR_COPY (sizeof(struct sym_ccbh)),}/*-------------------------< _SMS_A30 >-------------------------*/,{ 0, HADDR_1 (ccb_head), /* * Initialize the status register */ SCR_COPY (4), HADDR_1 (ccb_head.status), RADDR_1 (scr0),}/*-------------------------< WF_SEL_DONE >----------------------*/,{ SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), SIR_SEL_ATN_NO_MSG_OUT,}/*-------------------------< SEND_IDENT >-----------------------*/,{ /* * Selection complete. * Send the IDENTIFY and possibly the TAG message * and negotiation message if present. */ SCR_MOVE_TBL ^ SCR_MSG_OUT, offsetof (struct sym_dsb, smsg),}/*-------------------------< SELECT2 >--------------------------*/,{#ifdef SYM_CONF_IARB_SUPPORT /* * Set IMMEDIATE ARBITRATION if we have been given * a hint to do so. (Some job to do after this one). */ SCR_FROM_REG (HF_REG), 0, SCR_JUMPR ^ IFFALSE (MASK (HF_HINT_IARB, HF_HINT_IARB)), 8, SCR_REG_REG (scntl1, SCR_OR, IARB), 0,#endif /* * Anticipate the COMMAND phase. * This is the PHASE we expect at this point. */ SCR_JUMP ^ IFFALSE (WHEN (SCR_COMMAND)), PADDR_A (sel_no_cmd),}/*-------------------------< COMMAND >--------------------------*/,{ /* * ... and send the command */ SCR_MOVE_TBL ^ SCR_COMMAND, offsetof (struct sym_dsb, cmd),}/*-------------------------< DISPATCH >-------------------------*/,{ /* * MSG_IN is the only phase that shall be * entered at least once for each (re)selection. * So we test it first. */ SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), PADDR_A (msg_in), SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)), PADDR_A (datao_phase), SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)), PADDR_A (datai_phase), SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)), PADDR_A (status), SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)), PADDR_A (command), SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)), PADDR_B (msg_out), /* * Discard as many illegal phases as * required and tell the C code about. */ SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_OUT)), 16, SCR_MOVE_ABS (1) ^ SCR_ILG_OUT, HADDR_1 (scratch), SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_OUT)), -16, SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_IN)), 16, SCR_MOVE_ABS (1) ^ SCR_ILG_IN, HADDR_1 (scratch), SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_IN)), -16, SCR_INT, SIR_BAD_PHASE, SCR_JUMP, PADDR_A (dispatch),}/*-------------------------< SEL_NO_CMD >-----------------------*/,{ /* * The target does not switch to command * phase after IDENTIFY has been sent. * * If it stays in MSG OUT phase send it * the IDENTIFY again. */ SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), PADDR_B (resend_ident), /* * If target does not switch to MSG IN phase * and we sent a negotiation, assert the * failure immediately. */ SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), PADDR_A (dispatch), SCR_FROM_REG (HS_REG), 0, SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), SIR_NEGO_FAILED, /* * Jump to dispatcher. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -