162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 462306a36Sopenharmony_ci * of PCI-SCSI IO processors. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This driver is derived from the Linux sym53c8xx driver. 962306a36Sopenharmony_ci * Copyright (C) 1998-2000 Gerard Roudier 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 1262306a36Sopenharmony_ci * a port of the FreeBSD ncr driver to Linux-1.2.13. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * The original ncr driver has been written for 386bsd and FreeBSD by 1562306a36Sopenharmony_ci * Wolfgang Stanglmeier <wolf@cologne.de> 1662306a36Sopenharmony_ci * Stefan Esser <se@mi.Uni-Koeln.de> 1762306a36Sopenharmony_ci * Copyright (C) 1994 Wolfgang Stanglmeier 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * Other major contributions: 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * NVRAM detection and reading. 2262306a36Sopenharmony_ci * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci *----------------------------------------------------------------------------- 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* 2862306a36Sopenharmony_ci * Scripts for SYMBIOS-Processor 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * We have to know the offsets of all labels before we reach 3162306a36Sopenharmony_ci * them (for forward jumps). Therefore we declare a struct 3262306a36Sopenharmony_ci * here. If you make changes inside the script, 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * DONT FORGET TO CHANGE THE LENGTHS HERE! 3562306a36Sopenharmony_ci */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* 3862306a36Sopenharmony_ci * Script fragments which are loaded into the on-chip RAM 3962306a36Sopenharmony_ci * of 825A, 875, 876, 895, 895A, 896 and 1010 chips. 4062306a36Sopenharmony_ci * Must not exceed 4K bytes. 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_cistruct SYM_FWA_SCR { 4362306a36Sopenharmony_ci u32 start [ 11]; 4462306a36Sopenharmony_ci u32 getjob_begin [ 4]; 4562306a36Sopenharmony_ci u32 _sms_a10 [ 5]; 4662306a36Sopenharmony_ci u32 getjob_end [ 4]; 4762306a36Sopenharmony_ci u32 _sms_a20 [ 4]; 4862306a36Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 4962306a36Sopenharmony_ci u32 select [ 8]; 5062306a36Sopenharmony_ci#else 5162306a36Sopenharmony_ci u32 select [ 6]; 5262306a36Sopenharmony_ci#endif 5362306a36Sopenharmony_ci u32 _sms_a30 [ 5]; 5462306a36Sopenharmony_ci u32 wf_sel_done [ 2]; 5562306a36Sopenharmony_ci u32 send_ident [ 2]; 5662306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 5762306a36Sopenharmony_ci u32 select2 [ 8]; 5862306a36Sopenharmony_ci#else 5962306a36Sopenharmony_ci u32 select2 [ 2]; 6062306a36Sopenharmony_ci#endif 6162306a36Sopenharmony_ci u32 command [ 2]; 6262306a36Sopenharmony_ci u32 dispatch [ 28]; 6362306a36Sopenharmony_ci u32 sel_no_cmd [ 10]; 6462306a36Sopenharmony_ci u32 init [ 6]; 6562306a36Sopenharmony_ci u32 clrack [ 4]; 6662306a36Sopenharmony_ci u32 datai_done [ 11]; 6762306a36Sopenharmony_ci u32 datai_done_wsr [ 20]; 6862306a36Sopenharmony_ci u32 datao_done [ 11]; 6962306a36Sopenharmony_ci u32 datao_done_wss [ 6]; 7062306a36Sopenharmony_ci u32 datai_phase [ 5]; 7162306a36Sopenharmony_ci u32 datao_phase [ 5]; 7262306a36Sopenharmony_ci u32 msg_in [ 2]; 7362306a36Sopenharmony_ci u32 msg_in2 [ 10]; 7462306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 7562306a36Sopenharmony_ci u32 status [ 14]; 7662306a36Sopenharmony_ci#else 7762306a36Sopenharmony_ci u32 status [ 10]; 7862306a36Sopenharmony_ci#endif 7962306a36Sopenharmony_ci u32 complete [ 6]; 8062306a36Sopenharmony_ci u32 complete2 [ 8]; 8162306a36Sopenharmony_ci u32 _sms_a40 [ 12]; 8262306a36Sopenharmony_ci u32 done [ 5]; 8362306a36Sopenharmony_ci u32 _sms_a50 [ 5]; 8462306a36Sopenharmony_ci u32 _sms_a60 [ 2]; 8562306a36Sopenharmony_ci u32 done_end [ 4]; 8662306a36Sopenharmony_ci u32 complete_error [ 5]; 8762306a36Sopenharmony_ci u32 save_dp [ 11]; 8862306a36Sopenharmony_ci u32 restore_dp [ 7]; 8962306a36Sopenharmony_ci u32 disconnect [ 11]; 9062306a36Sopenharmony_ci u32 disconnect2 [ 5]; 9162306a36Sopenharmony_ci u32 _sms_a65 [ 3]; 9262306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 9362306a36Sopenharmony_ci u32 idle [ 4]; 9462306a36Sopenharmony_ci#else 9562306a36Sopenharmony_ci u32 idle [ 2]; 9662306a36Sopenharmony_ci#endif 9762306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 9862306a36Sopenharmony_ci u32 ungetjob [ 7]; 9962306a36Sopenharmony_ci#else 10062306a36Sopenharmony_ci u32 ungetjob [ 5]; 10162306a36Sopenharmony_ci#endif 10262306a36Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 10362306a36Sopenharmony_ci u32 reselect [ 4]; 10462306a36Sopenharmony_ci#else 10562306a36Sopenharmony_ci u32 reselect [ 2]; 10662306a36Sopenharmony_ci#endif 10762306a36Sopenharmony_ci u32 reselected [ 19]; 10862306a36Sopenharmony_ci u32 _sms_a70 [ 6]; 10962306a36Sopenharmony_ci u32 _sms_a80 [ 4]; 11062306a36Sopenharmony_ci u32 reselected1 [ 25]; 11162306a36Sopenharmony_ci u32 _sms_a90 [ 4]; 11262306a36Sopenharmony_ci u32 resel_lun0 [ 7]; 11362306a36Sopenharmony_ci u32 _sms_a100 [ 4]; 11462306a36Sopenharmony_ci u32 resel_tag [ 8]; 11562306a36Sopenharmony_ci#if SYM_CONF_MAX_TASK*4 > 512 11662306a36Sopenharmony_ci u32 _sms_a110 [ 23]; 11762306a36Sopenharmony_ci#elif SYM_CONF_MAX_TASK*4 > 256 11862306a36Sopenharmony_ci u32 _sms_a110 [ 17]; 11962306a36Sopenharmony_ci#else 12062306a36Sopenharmony_ci u32 _sms_a110 [ 13]; 12162306a36Sopenharmony_ci#endif 12262306a36Sopenharmony_ci u32 _sms_a120 [ 2]; 12362306a36Sopenharmony_ci u32 resel_go [ 4]; 12462306a36Sopenharmony_ci u32 _sms_a130 [ 7]; 12562306a36Sopenharmony_ci u32 resel_dsa [ 2]; 12662306a36Sopenharmony_ci u32 resel_dsa1 [ 4]; 12762306a36Sopenharmony_ci u32 _sms_a140 [ 7]; 12862306a36Sopenharmony_ci u32 resel_no_tag [ 4]; 12962306a36Sopenharmony_ci u32 _sms_a145 [ 7]; 13062306a36Sopenharmony_ci u32 data_in [SYM_CONF_MAX_SG * 2]; 13162306a36Sopenharmony_ci u32 data_in2 [ 4]; 13262306a36Sopenharmony_ci u32 data_out [SYM_CONF_MAX_SG * 2]; 13362306a36Sopenharmony_ci u32 data_out2 [ 4]; 13462306a36Sopenharmony_ci u32 pm0_data [ 12]; 13562306a36Sopenharmony_ci u32 pm0_data_out [ 6]; 13662306a36Sopenharmony_ci u32 pm0_data_end [ 7]; 13762306a36Sopenharmony_ci u32 pm_data_end [ 4]; 13862306a36Sopenharmony_ci u32 _sms_a150 [ 4]; 13962306a36Sopenharmony_ci u32 pm1_data [ 12]; 14062306a36Sopenharmony_ci u32 pm1_data_out [ 6]; 14162306a36Sopenharmony_ci u32 pm1_data_end [ 9]; 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/* 14562306a36Sopenharmony_ci * Script fragments which stay in main memory for all chips 14662306a36Sopenharmony_ci * except for chips that support 8K on-chip RAM. 14762306a36Sopenharmony_ci */ 14862306a36Sopenharmony_cistruct SYM_FWB_SCR { 14962306a36Sopenharmony_ci u32 no_data [ 2]; 15062306a36Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 15162306a36Sopenharmony_ci u32 sel_for_abort [ 18]; 15262306a36Sopenharmony_ci#else 15362306a36Sopenharmony_ci u32 sel_for_abort [ 16]; 15462306a36Sopenharmony_ci#endif 15562306a36Sopenharmony_ci u32 sel_for_abort_1 [ 2]; 15662306a36Sopenharmony_ci u32 msg_in_etc [ 12]; 15762306a36Sopenharmony_ci u32 msg_received [ 5]; 15862306a36Sopenharmony_ci u32 msg_weird_seen [ 5]; 15962306a36Sopenharmony_ci u32 msg_extended [ 17]; 16062306a36Sopenharmony_ci u32 _sms_b10 [ 4]; 16162306a36Sopenharmony_ci u32 msg_bad [ 6]; 16262306a36Sopenharmony_ci u32 msg_weird [ 4]; 16362306a36Sopenharmony_ci u32 msg_weird1 [ 8]; 16462306a36Sopenharmony_ci u32 wdtr_resp [ 6]; 16562306a36Sopenharmony_ci u32 send_wdtr [ 4]; 16662306a36Sopenharmony_ci u32 sdtr_resp [ 6]; 16762306a36Sopenharmony_ci u32 send_sdtr [ 4]; 16862306a36Sopenharmony_ci u32 ppr_resp [ 6]; 16962306a36Sopenharmony_ci u32 send_ppr [ 4]; 17062306a36Sopenharmony_ci u32 nego_bad_phase [ 4]; 17162306a36Sopenharmony_ci u32 msg_out [ 4]; 17262306a36Sopenharmony_ci u32 msg_out_done [ 4]; 17362306a36Sopenharmony_ci u32 data_ovrun [ 3]; 17462306a36Sopenharmony_ci u32 data_ovrun1 [ 22]; 17562306a36Sopenharmony_ci u32 data_ovrun2 [ 8]; 17662306a36Sopenharmony_ci u32 abort_resel [ 16]; 17762306a36Sopenharmony_ci u32 resend_ident [ 4]; 17862306a36Sopenharmony_ci u32 ident_break [ 4]; 17962306a36Sopenharmony_ci u32 ident_break_atn [ 4]; 18062306a36Sopenharmony_ci u32 sdata_in [ 6]; 18162306a36Sopenharmony_ci u32 resel_bad_lun [ 4]; 18262306a36Sopenharmony_ci u32 bad_i_t_l [ 4]; 18362306a36Sopenharmony_ci u32 bad_i_t_l_q [ 4]; 18462306a36Sopenharmony_ci u32 bad_status [ 7]; 18562306a36Sopenharmony_ci u32 wsr_ma_helper [ 4]; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci /* Data area */ 18862306a36Sopenharmony_ci u32 zero [ 1]; 18962306a36Sopenharmony_ci u32 scratch [ 1]; 19062306a36Sopenharmony_ci u32 scratch1 [ 1]; 19162306a36Sopenharmony_ci u32 prev_done [ 1]; 19262306a36Sopenharmony_ci u32 done_pos [ 1]; 19362306a36Sopenharmony_ci u32 nextjob [ 1]; 19462306a36Sopenharmony_ci u32 startpos [ 1]; 19562306a36Sopenharmony_ci u32 targtbl [ 1]; 19662306a36Sopenharmony_ci}; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* 19962306a36Sopenharmony_ci * Script fragments used at initialisations. 20062306a36Sopenharmony_ci * Only runs out of main memory. 20162306a36Sopenharmony_ci */ 20262306a36Sopenharmony_cistruct SYM_FWZ_SCR { 20362306a36Sopenharmony_ci u32 snooptest [ 9]; 20462306a36Sopenharmony_ci u32 snoopend [ 2]; 20562306a36Sopenharmony_ci}; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic struct SYM_FWA_SCR SYM_FWA_SCR = { 20862306a36Sopenharmony_ci/*--------------------------< START >----------------------------*/ { 20962306a36Sopenharmony_ci /* 21062306a36Sopenharmony_ci * Switch the LED on. 21162306a36Sopenharmony_ci * Will be patched with a NO_OP if LED 21262306a36Sopenharmony_ci * not needed or not desired. 21362306a36Sopenharmony_ci */ 21462306a36Sopenharmony_ci SCR_REG_REG (gpreg, SCR_AND, 0xfe), 21562306a36Sopenharmony_ci 0, 21662306a36Sopenharmony_ci /* 21762306a36Sopenharmony_ci * Clear SIGP. 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_ci SCR_FROM_REG (ctest2), 22062306a36Sopenharmony_ci 0, 22162306a36Sopenharmony_ci /* 22262306a36Sopenharmony_ci * Stop here if the C code wants to perform 22362306a36Sopenharmony_ci * some error recovery procedure manually. 22462306a36Sopenharmony_ci * (Indicate this by setting SEM in ISTAT) 22562306a36Sopenharmony_ci */ 22662306a36Sopenharmony_ci SCR_FROM_REG (istat), 22762306a36Sopenharmony_ci 0, 22862306a36Sopenharmony_ci /* 22962306a36Sopenharmony_ci * Report to the C code the next position in 23062306a36Sopenharmony_ci * the start queue the SCRIPTS will schedule. 23162306a36Sopenharmony_ci * The C code must not change SCRATCHA. 23262306a36Sopenharmony_ci */ 23362306a36Sopenharmony_ci SCR_COPY (4), 23462306a36Sopenharmony_ci PADDR_B (startpos), 23562306a36Sopenharmony_ci RADDR_1 (scratcha), 23662306a36Sopenharmony_ci SCR_INT ^ IFTRUE (MASK (SEM, SEM)), 23762306a36Sopenharmony_ci SIR_SCRIPT_STOPPED, 23862306a36Sopenharmony_ci /* 23962306a36Sopenharmony_ci * Start the next job. 24062306a36Sopenharmony_ci * 24162306a36Sopenharmony_ci * @DSA = start point for this job. 24262306a36Sopenharmony_ci * SCRATCHA = address of this job in the start queue. 24362306a36Sopenharmony_ci * 24462306a36Sopenharmony_ci * We will restore startpos with SCRATCHA if we fails the 24562306a36Sopenharmony_ci * arbitration or if it is the idle job. 24662306a36Sopenharmony_ci * 24762306a36Sopenharmony_ci * The below GETJOB_BEGIN to GETJOB_END section of SCRIPTS 24862306a36Sopenharmony_ci * is a critical path. If it is partially executed, it then 24962306a36Sopenharmony_ci * may happen that the job address is not yet in the DSA 25062306a36Sopenharmony_ci * and the next queue position points to the next JOB. 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_ci}/*-------------------------< GETJOB_BEGIN >---------------------*/,{ 25362306a36Sopenharmony_ci /* 25462306a36Sopenharmony_ci * Copy to a fixed location both the next STARTPOS 25562306a36Sopenharmony_ci * and the current JOB address, using self modifying 25662306a36Sopenharmony_ci * SCRIPTS. 25762306a36Sopenharmony_ci */ 25862306a36Sopenharmony_ci SCR_COPY (4), 25962306a36Sopenharmony_ci RADDR_1 (scratcha), 26062306a36Sopenharmony_ci PADDR_A (_sms_a10), 26162306a36Sopenharmony_ci SCR_COPY (8), 26262306a36Sopenharmony_ci}/*-------------------------< _SMS_A10 >-------------------------*/,{ 26362306a36Sopenharmony_ci 0, 26462306a36Sopenharmony_ci PADDR_B (nextjob), 26562306a36Sopenharmony_ci /* 26662306a36Sopenharmony_ci * Move the start address to TEMP using self- 26762306a36Sopenharmony_ci * modifying SCRIPTS and jump indirectly to 26862306a36Sopenharmony_ci * that address. 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_ci SCR_COPY (4), 27162306a36Sopenharmony_ci PADDR_B (nextjob), 27262306a36Sopenharmony_ci RADDR_1 (dsa), 27362306a36Sopenharmony_ci}/*-------------------------< GETJOB_END >-----------------------*/,{ 27462306a36Sopenharmony_ci SCR_COPY (4), 27562306a36Sopenharmony_ci RADDR_1 (dsa), 27662306a36Sopenharmony_ci PADDR_A (_sms_a20), 27762306a36Sopenharmony_ci SCR_COPY (4), 27862306a36Sopenharmony_ci}/*-------------------------< _SMS_A20 >-------------------------*/,{ 27962306a36Sopenharmony_ci 0, 28062306a36Sopenharmony_ci RADDR_1 (temp), 28162306a36Sopenharmony_ci SCR_RETURN, 28262306a36Sopenharmony_ci 0, 28362306a36Sopenharmony_ci}/*-------------------------< SELECT >---------------------------*/,{ 28462306a36Sopenharmony_ci /* 28562306a36Sopenharmony_ci * DSA contains the address of a scheduled 28662306a36Sopenharmony_ci * data structure. 28762306a36Sopenharmony_ci * 28862306a36Sopenharmony_ci * SCRATCHA contains the address of the start queue 28962306a36Sopenharmony_ci * entry which points to the next job. 29062306a36Sopenharmony_ci * 29162306a36Sopenharmony_ci * Set Initiator mode. 29262306a36Sopenharmony_ci * 29362306a36Sopenharmony_ci * (Target mode is left as an exercise for the reader) 29462306a36Sopenharmony_ci */ 29562306a36Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 29662306a36Sopenharmony_ci SCR_CLR (SCR_TRG), 29762306a36Sopenharmony_ci 0, 29862306a36Sopenharmony_ci#endif 29962306a36Sopenharmony_ci /* 30062306a36Sopenharmony_ci * And try to select this target. 30162306a36Sopenharmony_ci */ 30262306a36Sopenharmony_ci SCR_SEL_TBL_ATN ^ offsetof (struct sym_dsb, select), 30362306a36Sopenharmony_ci PADDR_A (ungetjob), 30462306a36Sopenharmony_ci /* 30562306a36Sopenharmony_ci * Now there are 4 possibilities: 30662306a36Sopenharmony_ci * 30762306a36Sopenharmony_ci * (1) The chip loses arbitration. 30862306a36Sopenharmony_ci * This is ok, because it will try again, 30962306a36Sopenharmony_ci * when the bus becomes idle. 31062306a36Sopenharmony_ci * (But beware of the timeout function!) 31162306a36Sopenharmony_ci * 31262306a36Sopenharmony_ci * (2) The chip is reselected. 31362306a36Sopenharmony_ci * Then the script processor takes the jump 31462306a36Sopenharmony_ci * to the RESELECT label. 31562306a36Sopenharmony_ci * 31662306a36Sopenharmony_ci * (3) The chip wins arbitration. 31762306a36Sopenharmony_ci * Then it will execute SCRIPTS instruction until 31862306a36Sopenharmony_ci * the next instruction that checks SCSI phase. 31962306a36Sopenharmony_ci * Then will stop and wait for selection to be 32062306a36Sopenharmony_ci * complete or selection time-out to occur. 32162306a36Sopenharmony_ci * 32262306a36Sopenharmony_ci * After having won arbitration, the SCRIPTS 32362306a36Sopenharmony_ci * processor is able to execute instructions while 32462306a36Sopenharmony_ci * the SCSI core is performing SCSI selection. 32562306a36Sopenharmony_ci */ 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* 32862306a36Sopenharmony_ci * Copy the CCB header to a fixed location 32962306a36Sopenharmony_ci * in the HCB using self-modifying SCRIPTS. 33062306a36Sopenharmony_ci */ 33162306a36Sopenharmony_ci SCR_COPY (4), 33262306a36Sopenharmony_ci RADDR_1 (dsa), 33362306a36Sopenharmony_ci PADDR_A (_sms_a30), 33462306a36Sopenharmony_ci SCR_COPY (sizeof(struct sym_ccbh)), 33562306a36Sopenharmony_ci}/*-------------------------< _SMS_A30 >-------------------------*/,{ 33662306a36Sopenharmony_ci 0, 33762306a36Sopenharmony_ci HADDR_1 (ccb_head), 33862306a36Sopenharmony_ci /* 33962306a36Sopenharmony_ci * Initialize the status register 34062306a36Sopenharmony_ci */ 34162306a36Sopenharmony_ci SCR_COPY (4), 34262306a36Sopenharmony_ci HADDR_1 (ccb_head.status), 34362306a36Sopenharmony_ci RADDR_1 (scr0), 34462306a36Sopenharmony_ci}/*-------------------------< WF_SEL_DONE >----------------------*/,{ 34562306a36Sopenharmony_ci SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), 34662306a36Sopenharmony_ci SIR_SEL_ATN_NO_MSG_OUT, 34762306a36Sopenharmony_ci}/*-------------------------< SEND_IDENT >-----------------------*/,{ 34862306a36Sopenharmony_ci /* 34962306a36Sopenharmony_ci * Selection complete. 35062306a36Sopenharmony_ci * Send the IDENTIFY and possibly the TAG message 35162306a36Sopenharmony_ci * and negotiation message if present. 35262306a36Sopenharmony_ci */ 35362306a36Sopenharmony_ci SCR_MOVE_TBL ^ SCR_MSG_OUT, 35462306a36Sopenharmony_ci offsetof (struct sym_dsb, smsg), 35562306a36Sopenharmony_ci}/*-------------------------< SELECT2 >--------------------------*/,{ 35662306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 35762306a36Sopenharmony_ci /* 35862306a36Sopenharmony_ci * Set IMMEDIATE ARBITRATION if we have been given 35962306a36Sopenharmony_ci * a hint to do so. (Some job to do after this one). 36062306a36Sopenharmony_ci */ 36162306a36Sopenharmony_ci SCR_FROM_REG (HF_REG), 36262306a36Sopenharmony_ci 0, 36362306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (MASK (HF_HINT_IARB, HF_HINT_IARB)), 36462306a36Sopenharmony_ci 8, 36562306a36Sopenharmony_ci SCR_REG_REG (scntl1, SCR_OR, IARB), 36662306a36Sopenharmony_ci 0, 36762306a36Sopenharmony_ci#endif 36862306a36Sopenharmony_ci /* 36962306a36Sopenharmony_ci * Anticipate the COMMAND phase. 37062306a36Sopenharmony_ci * This is the PHASE we expect at this point. 37162306a36Sopenharmony_ci */ 37262306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_COMMAND)), 37362306a36Sopenharmony_ci PADDR_A (sel_no_cmd), 37462306a36Sopenharmony_ci}/*-------------------------< COMMAND >--------------------------*/,{ 37562306a36Sopenharmony_ci /* 37662306a36Sopenharmony_ci * ... and send the command 37762306a36Sopenharmony_ci */ 37862306a36Sopenharmony_ci SCR_MOVE_TBL ^ SCR_COMMAND, 37962306a36Sopenharmony_ci offsetof (struct sym_dsb, cmd), 38062306a36Sopenharmony_ci}/*-------------------------< DISPATCH >-------------------------*/,{ 38162306a36Sopenharmony_ci /* 38262306a36Sopenharmony_ci * MSG_IN is the only phase that shall be 38362306a36Sopenharmony_ci * entered at least once for each (re)selection. 38462306a36Sopenharmony_ci * So we test it first. 38562306a36Sopenharmony_ci */ 38662306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 38762306a36Sopenharmony_ci PADDR_A (msg_in), 38862306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)), 38962306a36Sopenharmony_ci PADDR_A (datao_phase), 39062306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)), 39162306a36Sopenharmony_ci PADDR_A (datai_phase), 39262306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)), 39362306a36Sopenharmony_ci PADDR_A (status), 39462306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)), 39562306a36Sopenharmony_ci PADDR_A (command), 39662306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)), 39762306a36Sopenharmony_ci PADDR_B (msg_out), 39862306a36Sopenharmony_ci /* 39962306a36Sopenharmony_ci * Discard as many illegal phases as 40062306a36Sopenharmony_ci * required and tell the C code about. 40162306a36Sopenharmony_ci */ 40262306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_OUT)), 40362306a36Sopenharmony_ci 16, 40462306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_ILG_OUT, 40562306a36Sopenharmony_ci HADDR_1 (scratch), 40662306a36Sopenharmony_ci SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_OUT)), 40762306a36Sopenharmony_ci -16, 40862306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_IN)), 40962306a36Sopenharmony_ci 16, 41062306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_ILG_IN, 41162306a36Sopenharmony_ci HADDR_1 (scratch), 41262306a36Sopenharmony_ci SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_IN)), 41362306a36Sopenharmony_ci -16, 41462306a36Sopenharmony_ci SCR_INT, 41562306a36Sopenharmony_ci SIR_BAD_PHASE, 41662306a36Sopenharmony_ci SCR_JUMP, 41762306a36Sopenharmony_ci PADDR_A (dispatch), 41862306a36Sopenharmony_ci}/*-------------------------< SEL_NO_CMD >-----------------------*/,{ 41962306a36Sopenharmony_ci /* 42062306a36Sopenharmony_ci * The target does not switch to command 42162306a36Sopenharmony_ci * phase after IDENTIFY has been sent. 42262306a36Sopenharmony_ci * 42362306a36Sopenharmony_ci * If it stays in MSG OUT phase send it 42462306a36Sopenharmony_ci * the IDENTIFY again. 42562306a36Sopenharmony_ci */ 42662306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), 42762306a36Sopenharmony_ci PADDR_B (resend_ident), 42862306a36Sopenharmony_ci /* 42962306a36Sopenharmony_ci * If target does not switch to MSG IN phase 43062306a36Sopenharmony_ci * and we sent a negotiation, assert the 43162306a36Sopenharmony_ci * failure immediately. 43262306a36Sopenharmony_ci */ 43362306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 43462306a36Sopenharmony_ci PADDR_A (dispatch), 43562306a36Sopenharmony_ci SCR_FROM_REG (HS_REG), 43662306a36Sopenharmony_ci 0, 43762306a36Sopenharmony_ci SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), 43862306a36Sopenharmony_ci SIR_NEGO_FAILED, 43962306a36Sopenharmony_ci /* 44062306a36Sopenharmony_ci * Jump to dispatcher. 44162306a36Sopenharmony_ci */ 44262306a36Sopenharmony_ci SCR_JUMP, 44362306a36Sopenharmony_ci PADDR_A (dispatch), 44462306a36Sopenharmony_ci}/*-------------------------< INIT >-----------------------------*/,{ 44562306a36Sopenharmony_ci /* 44662306a36Sopenharmony_ci * Wait for the SCSI RESET signal to be 44762306a36Sopenharmony_ci * inactive before restarting operations, 44862306a36Sopenharmony_ci * since the chip may hang on SEL_ATN 44962306a36Sopenharmony_ci * if SCSI RESET is active. 45062306a36Sopenharmony_ci */ 45162306a36Sopenharmony_ci SCR_FROM_REG (sstat0), 45262306a36Sopenharmony_ci 0, 45362306a36Sopenharmony_ci SCR_JUMPR ^ IFTRUE (MASK (IRST, IRST)), 45462306a36Sopenharmony_ci -16, 45562306a36Sopenharmony_ci SCR_JUMP, 45662306a36Sopenharmony_ci PADDR_A (start), 45762306a36Sopenharmony_ci}/*-------------------------< CLRACK >---------------------------*/,{ 45862306a36Sopenharmony_ci /* 45962306a36Sopenharmony_ci * Terminate possible pending message phase. 46062306a36Sopenharmony_ci */ 46162306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 46262306a36Sopenharmony_ci 0, 46362306a36Sopenharmony_ci SCR_JUMP, 46462306a36Sopenharmony_ci PADDR_A (dispatch), 46562306a36Sopenharmony_ci}/*-------------------------< DATAI_DONE >-----------------------*/,{ 46662306a36Sopenharmony_ci /* 46762306a36Sopenharmony_ci * Save current pointer to LASTP. 46862306a36Sopenharmony_ci */ 46962306a36Sopenharmony_ci SCR_COPY (4), 47062306a36Sopenharmony_ci RADDR_1 (temp), 47162306a36Sopenharmony_ci HADDR_1 (ccb_head.lastp), 47262306a36Sopenharmony_ci /* 47362306a36Sopenharmony_ci * If the SWIDE is not full, jump to dispatcher. 47462306a36Sopenharmony_ci * We anticipate a STATUS phase. 47562306a36Sopenharmony_ci */ 47662306a36Sopenharmony_ci SCR_FROM_REG (scntl2), 47762306a36Sopenharmony_ci 0, 47862306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (WSR, WSR)), 47962306a36Sopenharmony_ci PADDR_A (datai_done_wsr), 48062306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)), 48162306a36Sopenharmony_ci PADDR_A (status), 48262306a36Sopenharmony_ci SCR_JUMP, 48362306a36Sopenharmony_ci PADDR_A (dispatch), 48462306a36Sopenharmony_ci}/*-------------------------< DATAI_DONE_WSR >-------------------*/,{ 48562306a36Sopenharmony_ci /* 48662306a36Sopenharmony_ci * The SWIDE is full. 48762306a36Sopenharmony_ci * Clear this condition. 48862306a36Sopenharmony_ci */ 48962306a36Sopenharmony_ci SCR_REG_REG (scntl2, SCR_OR, WSR), 49062306a36Sopenharmony_ci 0, 49162306a36Sopenharmony_ci /* 49262306a36Sopenharmony_ci * We are expecting an IGNORE RESIDUE message 49362306a36Sopenharmony_ci * from the device, otherwise we are in data 49462306a36Sopenharmony_ci * overrun condition. Check against MSG_IN phase. 49562306a36Sopenharmony_ci */ 49662306a36Sopenharmony_ci SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)), 49762306a36Sopenharmony_ci SIR_SWIDE_OVERRUN, 49862306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 49962306a36Sopenharmony_ci PADDR_A (dispatch), 50062306a36Sopenharmony_ci /* 50162306a36Sopenharmony_ci * We are in MSG_IN phase, 50262306a36Sopenharmony_ci * Read the first byte of the message. 50362306a36Sopenharmony_ci * If it is not an IGNORE RESIDUE message, 50462306a36Sopenharmony_ci * signal overrun and jump to message 50562306a36Sopenharmony_ci * processing. 50662306a36Sopenharmony_ci */ 50762306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 50862306a36Sopenharmony_ci HADDR_1 (msgin[0]), 50962306a36Sopenharmony_ci SCR_INT ^ IFFALSE (DATA (M_IGN_RESIDUE)), 51062306a36Sopenharmony_ci SIR_SWIDE_OVERRUN, 51162306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)), 51262306a36Sopenharmony_ci PADDR_A (msg_in2), 51362306a36Sopenharmony_ci /* 51462306a36Sopenharmony_ci * We got the message we expected. 51562306a36Sopenharmony_ci * Read the 2nd byte, and jump to dispatcher. 51662306a36Sopenharmony_ci */ 51762306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 51862306a36Sopenharmony_ci 0, 51962306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 52062306a36Sopenharmony_ci HADDR_1 (msgin[1]), 52162306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 52262306a36Sopenharmony_ci 0, 52362306a36Sopenharmony_ci SCR_JUMP, 52462306a36Sopenharmony_ci PADDR_A (dispatch), 52562306a36Sopenharmony_ci}/*-------------------------< DATAO_DONE >-----------------------*/,{ 52662306a36Sopenharmony_ci /* 52762306a36Sopenharmony_ci * Save current pointer to LASTP. 52862306a36Sopenharmony_ci */ 52962306a36Sopenharmony_ci SCR_COPY (4), 53062306a36Sopenharmony_ci RADDR_1 (temp), 53162306a36Sopenharmony_ci HADDR_1 (ccb_head.lastp), 53262306a36Sopenharmony_ci /* 53362306a36Sopenharmony_ci * If the SODL is not full jump to dispatcher. 53462306a36Sopenharmony_ci * We anticipate a STATUS phase. 53562306a36Sopenharmony_ci */ 53662306a36Sopenharmony_ci SCR_FROM_REG (scntl2), 53762306a36Sopenharmony_ci 0, 53862306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (WSS, WSS)), 53962306a36Sopenharmony_ci PADDR_A (datao_done_wss), 54062306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)), 54162306a36Sopenharmony_ci PADDR_A (status), 54262306a36Sopenharmony_ci SCR_JUMP, 54362306a36Sopenharmony_ci PADDR_A (dispatch), 54462306a36Sopenharmony_ci}/*-------------------------< DATAO_DONE_WSS >-------------------*/,{ 54562306a36Sopenharmony_ci /* 54662306a36Sopenharmony_ci * The SODL is full, clear this condition. 54762306a36Sopenharmony_ci */ 54862306a36Sopenharmony_ci SCR_REG_REG (scntl2, SCR_OR, WSS), 54962306a36Sopenharmony_ci 0, 55062306a36Sopenharmony_ci /* 55162306a36Sopenharmony_ci * And signal a DATA UNDERRUN condition 55262306a36Sopenharmony_ci * to the C code. 55362306a36Sopenharmony_ci */ 55462306a36Sopenharmony_ci SCR_INT, 55562306a36Sopenharmony_ci SIR_SODL_UNDERRUN, 55662306a36Sopenharmony_ci SCR_JUMP, 55762306a36Sopenharmony_ci PADDR_A (dispatch), 55862306a36Sopenharmony_ci}/*-------------------------< DATAI_PHASE >----------------------*/,{ 55962306a36Sopenharmony_ci /* 56062306a36Sopenharmony_ci * Jump to current pointer. 56162306a36Sopenharmony_ci */ 56262306a36Sopenharmony_ci SCR_COPY (4), 56362306a36Sopenharmony_ci HADDR_1 (ccb_head.lastp), 56462306a36Sopenharmony_ci RADDR_1 (temp), 56562306a36Sopenharmony_ci SCR_RETURN, 56662306a36Sopenharmony_ci 0, 56762306a36Sopenharmony_ci}/*-------------------------< DATAO_PHASE >----------------------*/,{ 56862306a36Sopenharmony_ci /* 56962306a36Sopenharmony_ci * Jump to current pointer. 57062306a36Sopenharmony_ci */ 57162306a36Sopenharmony_ci SCR_COPY (4), 57262306a36Sopenharmony_ci HADDR_1 (ccb_head.lastp), 57362306a36Sopenharmony_ci RADDR_1 (temp), 57462306a36Sopenharmony_ci SCR_RETURN, 57562306a36Sopenharmony_ci 0, 57662306a36Sopenharmony_ci}/*-------------------------< MSG_IN >---------------------------*/,{ 57762306a36Sopenharmony_ci /* 57862306a36Sopenharmony_ci * Get the first byte of the message. 57962306a36Sopenharmony_ci * 58062306a36Sopenharmony_ci * The script processor doesn't negate the 58162306a36Sopenharmony_ci * ACK signal after this transfer. 58262306a36Sopenharmony_ci */ 58362306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 58462306a36Sopenharmony_ci HADDR_1 (msgin[0]), 58562306a36Sopenharmony_ci}/*-------------------------< MSG_IN2 >--------------------------*/,{ 58662306a36Sopenharmony_ci /* 58762306a36Sopenharmony_ci * Check first against 1 byte messages 58862306a36Sopenharmony_ci * that we handle from SCRIPTS. 58962306a36Sopenharmony_ci */ 59062306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)), 59162306a36Sopenharmony_ci PADDR_A (complete), 59262306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)), 59362306a36Sopenharmony_ci PADDR_A (disconnect), 59462306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)), 59562306a36Sopenharmony_ci PADDR_A (save_dp), 59662306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)), 59762306a36Sopenharmony_ci PADDR_A (restore_dp), 59862306a36Sopenharmony_ci /* 59962306a36Sopenharmony_ci * We handle all other messages from the 60062306a36Sopenharmony_ci * C code, so no need to waste on-chip RAM 60162306a36Sopenharmony_ci * for those ones. 60262306a36Sopenharmony_ci */ 60362306a36Sopenharmony_ci SCR_JUMP, 60462306a36Sopenharmony_ci PADDR_B (msg_in_etc), 60562306a36Sopenharmony_ci}/*-------------------------< STATUS >---------------------------*/,{ 60662306a36Sopenharmony_ci /* 60762306a36Sopenharmony_ci * get the status 60862306a36Sopenharmony_ci */ 60962306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_STATUS, 61062306a36Sopenharmony_ci HADDR_1 (scratch), 61162306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 61262306a36Sopenharmony_ci /* 61362306a36Sopenharmony_ci * If STATUS is not GOOD, clear IMMEDIATE ARBITRATION, 61462306a36Sopenharmony_ci * since we may have to tamper the start queue from 61562306a36Sopenharmony_ci * the C code. 61662306a36Sopenharmony_ci */ 61762306a36Sopenharmony_ci SCR_JUMPR ^ IFTRUE (DATA (S_GOOD)), 61862306a36Sopenharmony_ci 8, 61962306a36Sopenharmony_ci SCR_REG_REG (scntl1, SCR_AND, ~IARB), 62062306a36Sopenharmony_ci 0, 62162306a36Sopenharmony_ci#endif 62262306a36Sopenharmony_ci /* 62362306a36Sopenharmony_ci * save status to scsi_status. 62462306a36Sopenharmony_ci * mark as complete. 62562306a36Sopenharmony_ci */ 62662306a36Sopenharmony_ci SCR_TO_REG (SS_REG), 62762306a36Sopenharmony_ci 0, 62862306a36Sopenharmony_ci SCR_LOAD_REG (HS_REG, HS_COMPLETE), 62962306a36Sopenharmony_ci 0, 63062306a36Sopenharmony_ci /* 63162306a36Sopenharmony_ci * Anticipate the MESSAGE PHASE for 63262306a36Sopenharmony_ci * the TASK COMPLETE message. 63362306a36Sopenharmony_ci */ 63462306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 63562306a36Sopenharmony_ci PADDR_A (msg_in), 63662306a36Sopenharmony_ci SCR_JUMP, 63762306a36Sopenharmony_ci PADDR_A (dispatch), 63862306a36Sopenharmony_ci}/*-------------------------< COMPLETE >-------------------------*/,{ 63962306a36Sopenharmony_ci /* 64062306a36Sopenharmony_ci * Complete message. 64162306a36Sopenharmony_ci * 64262306a36Sopenharmony_ci * When we terminate the cycle by clearing ACK, 64362306a36Sopenharmony_ci * the target may disconnect immediately. 64462306a36Sopenharmony_ci * 64562306a36Sopenharmony_ci * We don't want to be told of an "unexpected disconnect", 64662306a36Sopenharmony_ci * so we disable this feature. 64762306a36Sopenharmony_ci */ 64862306a36Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 64962306a36Sopenharmony_ci 0, 65062306a36Sopenharmony_ci /* 65162306a36Sopenharmony_ci * Terminate cycle ... 65262306a36Sopenharmony_ci */ 65362306a36Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 65462306a36Sopenharmony_ci 0, 65562306a36Sopenharmony_ci /* 65662306a36Sopenharmony_ci * ... and wait for the disconnect. 65762306a36Sopenharmony_ci */ 65862306a36Sopenharmony_ci SCR_WAIT_DISC, 65962306a36Sopenharmony_ci 0, 66062306a36Sopenharmony_ci}/*-------------------------< COMPLETE2 >------------------------*/,{ 66162306a36Sopenharmony_ci /* 66262306a36Sopenharmony_ci * Save host status. 66362306a36Sopenharmony_ci */ 66462306a36Sopenharmony_ci SCR_COPY (4), 66562306a36Sopenharmony_ci RADDR_1 (scr0), 66662306a36Sopenharmony_ci HADDR_1 (ccb_head.status), 66762306a36Sopenharmony_ci /* 66862306a36Sopenharmony_ci * Move back the CCB header using self-modifying 66962306a36Sopenharmony_ci * SCRIPTS. 67062306a36Sopenharmony_ci */ 67162306a36Sopenharmony_ci SCR_COPY (4), 67262306a36Sopenharmony_ci RADDR_1 (dsa), 67362306a36Sopenharmony_ci PADDR_A (_sms_a40), 67462306a36Sopenharmony_ci SCR_COPY (sizeof(struct sym_ccbh)), 67562306a36Sopenharmony_ci HADDR_1 (ccb_head), 67662306a36Sopenharmony_ci}/*-------------------------< _SMS_A40 >-------------------------*/,{ 67762306a36Sopenharmony_ci 0, 67862306a36Sopenharmony_ci /* 67962306a36Sopenharmony_ci * Some bridges may reorder DMA writes to memory. 68062306a36Sopenharmony_ci * We donnot want the CPU to deal with completions 68162306a36Sopenharmony_ci * without all the posted write having been flushed 68262306a36Sopenharmony_ci * to memory. This DUMMY READ should flush posted 68362306a36Sopenharmony_ci * buffers prior to the CPU having to deal with 68462306a36Sopenharmony_ci * completions. 68562306a36Sopenharmony_ci */ 68662306a36Sopenharmony_ci SCR_COPY (4), /* DUMMY READ */ 68762306a36Sopenharmony_ci HADDR_1 (ccb_head.status), 68862306a36Sopenharmony_ci RADDR_1 (scr0), 68962306a36Sopenharmony_ci /* 69062306a36Sopenharmony_ci * If command resulted in not GOOD status, 69162306a36Sopenharmony_ci * call the C code if needed. 69262306a36Sopenharmony_ci */ 69362306a36Sopenharmony_ci SCR_FROM_REG (SS_REG), 69462306a36Sopenharmony_ci 0, 69562306a36Sopenharmony_ci SCR_CALL ^ IFFALSE (DATA (S_GOOD)), 69662306a36Sopenharmony_ci PADDR_B (bad_status), 69762306a36Sopenharmony_ci /* 69862306a36Sopenharmony_ci * If we performed an auto-sense, call 69962306a36Sopenharmony_ci * the C code to synchronyze task aborts 70062306a36Sopenharmony_ci * with UNIT ATTENTION conditions. 70162306a36Sopenharmony_ci */ 70262306a36Sopenharmony_ci SCR_FROM_REG (HF_REG), 70362306a36Sopenharmony_ci 0, 70462306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (0 ,(HF_SENSE|HF_EXT_ERR))), 70562306a36Sopenharmony_ci PADDR_A (complete_error), 70662306a36Sopenharmony_ci}/*-------------------------< DONE >-----------------------------*/,{ 70762306a36Sopenharmony_ci /* 70862306a36Sopenharmony_ci * Copy the DSA to the DONE QUEUE and 70962306a36Sopenharmony_ci * signal completion to the host. 71062306a36Sopenharmony_ci * If we are interrupted between DONE 71162306a36Sopenharmony_ci * and DONE_END, we must reset, otherwise 71262306a36Sopenharmony_ci * the completed CCB may be lost. 71362306a36Sopenharmony_ci */ 71462306a36Sopenharmony_ci SCR_COPY (4), 71562306a36Sopenharmony_ci PADDR_B (done_pos), 71662306a36Sopenharmony_ci PADDR_A (_sms_a50), 71762306a36Sopenharmony_ci SCR_COPY (4), 71862306a36Sopenharmony_ci RADDR_1 (dsa), 71962306a36Sopenharmony_ci}/*-------------------------< _SMS_A50 >-------------------------*/,{ 72062306a36Sopenharmony_ci 0, 72162306a36Sopenharmony_ci SCR_COPY (4), 72262306a36Sopenharmony_ci PADDR_B (done_pos), 72362306a36Sopenharmony_ci PADDR_A (_sms_a60), 72462306a36Sopenharmony_ci /* 72562306a36Sopenharmony_ci * The instruction below reads the DONE QUEUE next 72662306a36Sopenharmony_ci * free position from memory. 72762306a36Sopenharmony_ci * In addition it ensures that all PCI posted writes 72862306a36Sopenharmony_ci * are flushed and so the DSA value of the done 72962306a36Sopenharmony_ci * CCB is visible by the CPU before INTFLY is raised. 73062306a36Sopenharmony_ci */ 73162306a36Sopenharmony_ci SCR_COPY (8), 73262306a36Sopenharmony_ci}/*-------------------------< _SMS_A60 >-------------------------*/,{ 73362306a36Sopenharmony_ci 0, 73462306a36Sopenharmony_ci PADDR_B (prev_done), 73562306a36Sopenharmony_ci}/*-------------------------< DONE_END >-------------------------*/,{ 73662306a36Sopenharmony_ci SCR_INT_FLY, 73762306a36Sopenharmony_ci 0, 73862306a36Sopenharmony_ci SCR_JUMP, 73962306a36Sopenharmony_ci PADDR_A (start), 74062306a36Sopenharmony_ci}/*-------------------------< COMPLETE_ERROR >-------------------*/,{ 74162306a36Sopenharmony_ci SCR_COPY (4), 74262306a36Sopenharmony_ci PADDR_B (startpos), 74362306a36Sopenharmony_ci RADDR_1 (scratcha), 74462306a36Sopenharmony_ci SCR_INT, 74562306a36Sopenharmony_ci SIR_COMPLETE_ERROR, 74662306a36Sopenharmony_ci}/*-------------------------< SAVE_DP >--------------------------*/,{ 74762306a36Sopenharmony_ci /* 74862306a36Sopenharmony_ci * Clear ACK immediately. 74962306a36Sopenharmony_ci * No need to delay it. 75062306a36Sopenharmony_ci */ 75162306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 75262306a36Sopenharmony_ci 0, 75362306a36Sopenharmony_ci /* 75462306a36Sopenharmony_ci * Keep track we received a SAVE DP, so 75562306a36Sopenharmony_ci * we will switch to the other PM context 75662306a36Sopenharmony_ci * on the next PM since the DP may point 75762306a36Sopenharmony_ci * to the current PM context. 75862306a36Sopenharmony_ci */ 75962306a36Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED), 76062306a36Sopenharmony_ci 0, 76162306a36Sopenharmony_ci /* 76262306a36Sopenharmony_ci * SAVE_DP message: 76362306a36Sopenharmony_ci * Copy LASTP to SAVEP. 76462306a36Sopenharmony_ci */ 76562306a36Sopenharmony_ci SCR_COPY (4), 76662306a36Sopenharmony_ci HADDR_1 (ccb_head.lastp), 76762306a36Sopenharmony_ci HADDR_1 (ccb_head.savep), 76862306a36Sopenharmony_ci /* 76962306a36Sopenharmony_ci * Anticipate the MESSAGE PHASE for 77062306a36Sopenharmony_ci * the DISCONNECT message. 77162306a36Sopenharmony_ci */ 77262306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 77362306a36Sopenharmony_ci PADDR_A (msg_in), 77462306a36Sopenharmony_ci SCR_JUMP, 77562306a36Sopenharmony_ci PADDR_A (dispatch), 77662306a36Sopenharmony_ci}/*-------------------------< RESTORE_DP >-----------------------*/,{ 77762306a36Sopenharmony_ci /* 77862306a36Sopenharmony_ci * Clear ACK immediately. 77962306a36Sopenharmony_ci * No need to delay it. 78062306a36Sopenharmony_ci */ 78162306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 78262306a36Sopenharmony_ci 0, 78362306a36Sopenharmony_ci /* 78462306a36Sopenharmony_ci * Copy SAVEP to LASTP. 78562306a36Sopenharmony_ci */ 78662306a36Sopenharmony_ci SCR_COPY (4), 78762306a36Sopenharmony_ci HADDR_1 (ccb_head.savep), 78862306a36Sopenharmony_ci HADDR_1 (ccb_head.lastp), 78962306a36Sopenharmony_ci SCR_JUMP, 79062306a36Sopenharmony_ci PADDR_A (dispatch), 79162306a36Sopenharmony_ci}/*-------------------------< DISCONNECT >-----------------------*/,{ 79262306a36Sopenharmony_ci /* 79362306a36Sopenharmony_ci * DISCONNECTing ... 79462306a36Sopenharmony_ci * 79562306a36Sopenharmony_ci * disable the "unexpected disconnect" feature, 79662306a36Sopenharmony_ci * and remove the ACK signal. 79762306a36Sopenharmony_ci */ 79862306a36Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 79962306a36Sopenharmony_ci 0, 80062306a36Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 80162306a36Sopenharmony_ci 0, 80262306a36Sopenharmony_ci /* 80362306a36Sopenharmony_ci * Wait for the disconnect. 80462306a36Sopenharmony_ci */ 80562306a36Sopenharmony_ci SCR_WAIT_DISC, 80662306a36Sopenharmony_ci 0, 80762306a36Sopenharmony_ci /* 80862306a36Sopenharmony_ci * Status is: DISCONNECTED. 80962306a36Sopenharmony_ci */ 81062306a36Sopenharmony_ci SCR_LOAD_REG (HS_REG, HS_DISCONNECT), 81162306a36Sopenharmony_ci 0, 81262306a36Sopenharmony_ci /* 81362306a36Sopenharmony_ci * Save host status. 81462306a36Sopenharmony_ci */ 81562306a36Sopenharmony_ci SCR_COPY (4), 81662306a36Sopenharmony_ci RADDR_1 (scr0), 81762306a36Sopenharmony_ci HADDR_1 (ccb_head.status), 81862306a36Sopenharmony_ci}/*-------------------------< DISCONNECT2 >----------------------*/,{ 81962306a36Sopenharmony_ci /* 82062306a36Sopenharmony_ci * Move back the CCB header using self-modifying 82162306a36Sopenharmony_ci * SCRIPTS. 82262306a36Sopenharmony_ci */ 82362306a36Sopenharmony_ci SCR_COPY (4), 82462306a36Sopenharmony_ci RADDR_1 (dsa), 82562306a36Sopenharmony_ci PADDR_A (_sms_a65), 82662306a36Sopenharmony_ci SCR_COPY (sizeof(struct sym_ccbh)), 82762306a36Sopenharmony_ci HADDR_1 (ccb_head), 82862306a36Sopenharmony_ci}/*-------------------------< _SMS_A65 >-------------------------*/,{ 82962306a36Sopenharmony_ci 0, 83062306a36Sopenharmony_ci SCR_JUMP, 83162306a36Sopenharmony_ci PADDR_A (start), 83262306a36Sopenharmony_ci}/*-------------------------< IDLE >-----------------------------*/,{ 83362306a36Sopenharmony_ci /* 83462306a36Sopenharmony_ci * Nothing to do? 83562306a36Sopenharmony_ci * Switch the LED off and wait for reselect. 83662306a36Sopenharmony_ci * Will be patched with a NO_OP if LED 83762306a36Sopenharmony_ci * not needed or not desired. 83862306a36Sopenharmony_ci */ 83962306a36Sopenharmony_ci SCR_REG_REG (gpreg, SCR_OR, 0x01), 84062306a36Sopenharmony_ci 0, 84162306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 84262306a36Sopenharmony_ci SCR_JUMPR, 84362306a36Sopenharmony_ci 8, 84462306a36Sopenharmony_ci#endif 84562306a36Sopenharmony_ci}/*-------------------------< UNGETJOB >-------------------------*/,{ 84662306a36Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 84762306a36Sopenharmony_ci /* 84862306a36Sopenharmony_ci * Set IMMEDIATE ARBITRATION, for the next time. 84962306a36Sopenharmony_ci * This will give us better chance to win arbitration 85062306a36Sopenharmony_ci * for the job we just wanted to do. 85162306a36Sopenharmony_ci */ 85262306a36Sopenharmony_ci SCR_REG_REG (scntl1, SCR_OR, IARB), 85362306a36Sopenharmony_ci 0, 85462306a36Sopenharmony_ci#endif 85562306a36Sopenharmony_ci /* 85662306a36Sopenharmony_ci * We are not able to restart the SCRIPTS if we are 85762306a36Sopenharmony_ci * interrupted and these instruction haven't been 85862306a36Sopenharmony_ci * all executed. BTW, this is very unlikely to 85962306a36Sopenharmony_ci * happen, but we check that from the C code. 86062306a36Sopenharmony_ci */ 86162306a36Sopenharmony_ci SCR_LOAD_REG (dsa, 0xff), 86262306a36Sopenharmony_ci 0, 86362306a36Sopenharmony_ci SCR_COPY (4), 86462306a36Sopenharmony_ci RADDR_1 (scratcha), 86562306a36Sopenharmony_ci PADDR_B (startpos), 86662306a36Sopenharmony_ci}/*-------------------------< RESELECT >-------------------------*/,{ 86762306a36Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 86862306a36Sopenharmony_ci /* 86962306a36Sopenharmony_ci * Make sure we are in initiator mode. 87062306a36Sopenharmony_ci */ 87162306a36Sopenharmony_ci SCR_CLR (SCR_TRG), 87262306a36Sopenharmony_ci 0, 87362306a36Sopenharmony_ci#endif 87462306a36Sopenharmony_ci /* 87562306a36Sopenharmony_ci * Sleep waiting for a reselection. 87662306a36Sopenharmony_ci */ 87762306a36Sopenharmony_ci SCR_WAIT_RESEL, 87862306a36Sopenharmony_ci PADDR_A(start), 87962306a36Sopenharmony_ci}/*-------------------------< RESELECTED >-----------------------*/,{ 88062306a36Sopenharmony_ci /* 88162306a36Sopenharmony_ci * Switch the LED on. 88262306a36Sopenharmony_ci * Will be patched with a NO_OP if LED 88362306a36Sopenharmony_ci * not needed or not desired. 88462306a36Sopenharmony_ci */ 88562306a36Sopenharmony_ci SCR_REG_REG (gpreg, SCR_AND, 0xfe), 88662306a36Sopenharmony_ci 0, 88762306a36Sopenharmony_ci /* 88862306a36Sopenharmony_ci * load the target id into the sdid 88962306a36Sopenharmony_ci */ 89062306a36Sopenharmony_ci SCR_REG_SFBR (ssid, SCR_AND, 0x8F), 89162306a36Sopenharmony_ci 0, 89262306a36Sopenharmony_ci SCR_TO_REG (sdid), 89362306a36Sopenharmony_ci 0, 89462306a36Sopenharmony_ci /* 89562306a36Sopenharmony_ci * Load the target control block address 89662306a36Sopenharmony_ci */ 89762306a36Sopenharmony_ci SCR_COPY (4), 89862306a36Sopenharmony_ci PADDR_B (targtbl), 89962306a36Sopenharmony_ci RADDR_1 (dsa), 90062306a36Sopenharmony_ci SCR_SFBR_REG (dsa, SCR_SHL, 0), 90162306a36Sopenharmony_ci 0, 90262306a36Sopenharmony_ci SCR_REG_REG (dsa, SCR_SHL, 0), 90362306a36Sopenharmony_ci 0, 90462306a36Sopenharmony_ci SCR_REG_REG (dsa, SCR_AND, 0x3c), 90562306a36Sopenharmony_ci 0, 90662306a36Sopenharmony_ci SCR_COPY (4), 90762306a36Sopenharmony_ci RADDR_1 (dsa), 90862306a36Sopenharmony_ci PADDR_A (_sms_a70), 90962306a36Sopenharmony_ci SCR_COPY (4), 91062306a36Sopenharmony_ci}/*-------------------------< _SMS_A70 >-------------------------*/,{ 91162306a36Sopenharmony_ci 0, 91262306a36Sopenharmony_ci RADDR_1 (dsa), 91362306a36Sopenharmony_ci /* 91462306a36Sopenharmony_ci * Copy the TCB header to a fixed place in 91562306a36Sopenharmony_ci * the HCB. 91662306a36Sopenharmony_ci */ 91762306a36Sopenharmony_ci SCR_COPY (4), 91862306a36Sopenharmony_ci RADDR_1 (dsa), 91962306a36Sopenharmony_ci PADDR_A (_sms_a80), 92062306a36Sopenharmony_ci SCR_COPY (sizeof(struct sym_tcbh)), 92162306a36Sopenharmony_ci}/*-------------------------< _SMS_A80 >-------------------------*/,{ 92262306a36Sopenharmony_ci 0, 92362306a36Sopenharmony_ci HADDR_1 (tcb_head), 92462306a36Sopenharmony_ci /* 92562306a36Sopenharmony_ci * We expect MESSAGE IN phase. 92662306a36Sopenharmony_ci * If not, get help from the C code. 92762306a36Sopenharmony_ci */ 92862306a36Sopenharmony_ci SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)), 92962306a36Sopenharmony_ci SIR_RESEL_NO_MSG_IN, 93062306a36Sopenharmony_ci}/*-------------------------< RESELECTED1 >----------------------*/,{ 93162306a36Sopenharmony_ci /* 93262306a36Sopenharmony_ci * Load the synchronous transfer registers. 93362306a36Sopenharmony_ci */ 93462306a36Sopenharmony_ci SCR_COPY (1), 93562306a36Sopenharmony_ci HADDR_1 (tcb_head.wval), 93662306a36Sopenharmony_ci RADDR_1 (scntl3), 93762306a36Sopenharmony_ci SCR_COPY (1), 93862306a36Sopenharmony_ci HADDR_1 (tcb_head.sval), 93962306a36Sopenharmony_ci RADDR_1 (sxfer), 94062306a36Sopenharmony_ci /* 94162306a36Sopenharmony_ci * Get the IDENTIFY message. 94262306a36Sopenharmony_ci */ 94362306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 94462306a36Sopenharmony_ci HADDR_1 (msgin), 94562306a36Sopenharmony_ci /* 94662306a36Sopenharmony_ci * If IDENTIFY LUN #0, use a faster path 94762306a36Sopenharmony_ci * to find the LCB structure. 94862306a36Sopenharmony_ci */ 94962306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0x80, 0xbf)), 95062306a36Sopenharmony_ci PADDR_A (resel_lun0), 95162306a36Sopenharmony_ci /* 95262306a36Sopenharmony_ci * If message isn't an IDENTIFY, 95362306a36Sopenharmony_ci * tell the C code about. 95462306a36Sopenharmony_ci */ 95562306a36Sopenharmony_ci SCR_INT ^ IFFALSE (MASK (0x80, 0x80)), 95662306a36Sopenharmony_ci SIR_RESEL_NO_IDENTIFY, 95762306a36Sopenharmony_ci /* 95862306a36Sopenharmony_ci * It is an IDENTIFY message, 95962306a36Sopenharmony_ci * Load the LUN control block address. 96062306a36Sopenharmony_ci */ 96162306a36Sopenharmony_ci SCR_COPY (4), 96262306a36Sopenharmony_ci HADDR_1 (tcb_head.luntbl_sa), 96362306a36Sopenharmony_ci RADDR_1 (dsa), 96462306a36Sopenharmony_ci SCR_SFBR_REG (dsa, SCR_SHL, 0), 96562306a36Sopenharmony_ci 0, 96662306a36Sopenharmony_ci SCR_REG_REG (dsa, SCR_SHL, 0), 96762306a36Sopenharmony_ci 0, 96862306a36Sopenharmony_ci SCR_REG_REG (dsa, SCR_AND, 0xfc), 96962306a36Sopenharmony_ci 0, 97062306a36Sopenharmony_ci SCR_COPY (4), 97162306a36Sopenharmony_ci RADDR_1 (dsa), 97262306a36Sopenharmony_ci PADDR_A (_sms_a90), 97362306a36Sopenharmony_ci SCR_COPY (4), 97462306a36Sopenharmony_ci}/*-------------------------< _SMS_A90 >-------------------------*/,{ 97562306a36Sopenharmony_ci 0, 97662306a36Sopenharmony_ci RADDR_1 (dsa), 97762306a36Sopenharmony_ci SCR_JUMPR, 97862306a36Sopenharmony_ci 12, 97962306a36Sopenharmony_ci}/*-------------------------< RESEL_LUN0 >-----------------------*/,{ 98062306a36Sopenharmony_ci /* 98162306a36Sopenharmony_ci * LUN 0 special case (but usual one :)) 98262306a36Sopenharmony_ci */ 98362306a36Sopenharmony_ci SCR_COPY (4), 98462306a36Sopenharmony_ci HADDR_1 (tcb_head.lun0_sa), 98562306a36Sopenharmony_ci RADDR_1 (dsa), 98662306a36Sopenharmony_ci /* 98762306a36Sopenharmony_ci * Jump indirectly to the reselect action for this LUN. 98862306a36Sopenharmony_ci * (lcb.head.resel_sa assumed at offset zero of lcb). 98962306a36Sopenharmony_ci */ 99062306a36Sopenharmony_ci SCR_COPY (4), 99162306a36Sopenharmony_ci RADDR_1 (dsa), 99262306a36Sopenharmony_ci PADDR_A (_sms_a100), 99362306a36Sopenharmony_ci SCR_COPY (4), 99462306a36Sopenharmony_ci}/*-------------------------< _SMS_A100 >------------------------*/,{ 99562306a36Sopenharmony_ci 0, 99662306a36Sopenharmony_ci RADDR_1 (temp), 99762306a36Sopenharmony_ci SCR_RETURN, 99862306a36Sopenharmony_ci 0, 99962306a36Sopenharmony_ci /* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */ 100062306a36Sopenharmony_ci}/*-------------------------< RESEL_TAG >------------------------*/,{ 100162306a36Sopenharmony_ci /* 100262306a36Sopenharmony_ci * ACK the IDENTIFY previously received. 100362306a36Sopenharmony_ci */ 100462306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 100562306a36Sopenharmony_ci 0, 100662306a36Sopenharmony_ci /* 100762306a36Sopenharmony_ci * It shall be a tagged command. 100862306a36Sopenharmony_ci * Read SIMPLE+TAG. 100962306a36Sopenharmony_ci * The C code will deal with errors. 101062306a36Sopenharmony_ci * Aggressive optimization, isn't it? :) 101162306a36Sopenharmony_ci */ 101262306a36Sopenharmony_ci SCR_MOVE_ABS (2) ^ SCR_MSG_IN, 101362306a36Sopenharmony_ci HADDR_1 (msgin), 101462306a36Sopenharmony_ci /* 101562306a36Sopenharmony_ci * Copy the LCB header to a fixed place in 101662306a36Sopenharmony_ci * the HCB using self-modifying SCRIPTS. 101762306a36Sopenharmony_ci */ 101862306a36Sopenharmony_ci SCR_COPY (4), 101962306a36Sopenharmony_ci RADDR_1 (dsa), 102062306a36Sopenharmony_ci PADDR_A (_sms_a110), 102162306a36Sopenharmony_ci SCR_COPY (sizeof(struct sym_lcbh)), 102262306a36Sopenharmony_ci}/*-------------------------< _SMS_A110 >------------------------*/,{ 102362306a36Sopenharmony_ci 0, 102462306a36Sopenharmony_ci HADDR_1 (lcb_head), 102562306a36Sopenharmony_ci /* 102662306a36Sopenharmony_ci * Load the pointer to the tagged task 102762306a36Sopenharmony_ci * table for this LUN. 102862306a36Sopenharmony_ci */ 102962306a36Sopenharmony_ci SCR_COPY (4), 103062306a36Sopenharmony_ci HADDR_1 (lcb_head.itlq_tbl_sa), 103162306a36Sopenharmony_ci RADDR_1 (dsa), 103262306a36Sopenharmony_ci /* 103362306a36Sopenharmony_ci * The SIDL still contains the TAG value. 103462306a36Sopenharmony_ci * Aggressive optimization, isn't it? :):) 103562306a36Sopenharmony_ci */ 103662306a36Sopenharmony_ci SCR_REG_SFBR (sidl, SCR_SHL, 0), 103762306a36Sopenharmony_ci 0, 103862306a36Sopenharmony_ci#if SYM_CONF_MAX_TASK*4 > 512 103962306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (CARRYSET), 104062306a36Sopenharmony_ci 8, 104162306a36Sopenharmony_ci SCR_REG_REG (dsa1, SCR_OR, 2), 104262306a36Sopenharmony_ci 0, 104362306a36Sopenharmony_ci SCR_REG_REG (sfbr, SCR_SHL, 0), 104462306a36Sopenharmony_ci 0, 104562306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (CARRYSET), 104662306a36Sopenharmony_ci 8, 104762306a36Sopenharmony_ci SCR_REG_REG (dsa1, SCR_OR, 1), 104862306a36Sopenharmony_ci 0, 104962306a36Sopenharmony_ci#elif SYM_CONF_MAX_TASK*4 > 256 105062306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (CARRYSET), 105162306a36Sopenharmony_ci 8, 105262306a36Sopenharmony_ci SCR_REG_REG (dsa1, SCR_OR, 1), 105362306a36Sopenharmony_ci 0, 105462306a36Sopenharmony_ci#endif 105562306a36Sopenharmony_ci /* 105662306a36Sopenharmony_ci * Retrieve the DSA of this task. 105762306a36Sopenharmony_ci * JUMP indirectly to the restart point of the CCB. 105862306a36Sopenharmony_ci */ 105962306a36Sopenharmony_ci SCR_SFBR_REG (dsa, SCR_AND, 0xfc), 106062306a36Sopenharmony_ci 0, 106162306a36Sopenharmony_ci SCR_COPY (4), 106262306a36Sopenharmony_ci RADDR_1 (dsa), 106362306a36Sopenharmony_ci PADDR_A (_sms_a120), 106462306a36Sopenharmony_ci SCR_COPY (4), 106562306a36Sopenharmony_ci}/*-------------------------< _SMS_A120 >------------------------*/,{ 106662306a36Sopenharmony_ci 0, 106762306a36Sopenharmony_ci RADDR_1 (dsa), 106862306a36Sopenharmony_ci}/*-------------------------< RESEL_GO >-------------------------*/,{ 106962306a36Sopenharmony_ci SCR_COPY (4), 107062306a36Sopenharmony_ci RADDR_1 (dsa), 107162306a36Sopenharmony_ci PADDR_A (_sms_a130), 107262306a36Sopenharmony_ci /* 107362306a36Sopenharmony_ci * Move 'ccb.phys.head.go' action to 107462306a36Sopenharmony_ci * scratch/scratch1. So scratch1 will 107562306a36Sopenharmony_ci * contain the 'restart' field of the 107662306a36Sopenharmony_ci * 'go' structure. 107762306a36Sopenharmony_ci */ 107862306a36Sopenharmony_ci SCR_COPY (8), 107962306a36Sopenharmony_ci}/*-------------------------< _SMS_A130 >------------------------*/,{ 108062306a36Sopenharmony_ci 0, 108162306a36Sopenharmony_ci PADDR_B (scratch), 108262306a36Sopenharmony_ci SCR_COPY (4), 108362306a36Sopenharmony_ci PADDR_B (scratch1), /* phys.head.go.restart */ 108462306a36Sopenharmony_ci RADDR_1 (temp), 108562306a36Sopenharmony_ci SCR_RETURN, 108662306a36Sopenharmony_ci 0, 108762306a36Sopenharmony_ci /* In normal situations we branch to RESEL_DSA */ 108862306a36Sopenharmony_ci}/*-------------------------< RESEL_DSA >------------------------*/,{ 108962306a36Sopenharmony_ci /* 109062306a36Sopenharmony_ci * ACK the IDENTIFY or TAG previously received. 109162306a36Sopenharmony_ci */ 109262306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 109362306a36Sopenharmony_ci 0, 109462306a36Sopenharmony_ci}/*-------------------------< RESEL_DSA1 >-----------------------*/,{ 109562306a36Sopenharmony_ci /* 109662306a36Sopenharmony_ci * Copy the CCB header to a fixed location 109762306a36Sopenharmony_ci * in the HCB using self-modifying SCRIPTS. 109862306a36Sopenharmony_ci */ 109962306a36Sopenharmony_ci SCR_COPY (4), 110062306a36Sopenharmony_ci RADDR_1 (dsa), 110162306a36Sopenharmony_ci PADDR_A (_sms_a140), 110262306a36Sopenharmony_ci SCR_COPY (sizeof(struct sym_ccbh)), 110362306a36Sopenharmony_ci}/*-------------------------< _SMS_A140 >------------------------*/,{ 110462306a36Sopenharmony_ci 0, 110562306a36Sopenharmony_ci HADDR_1 (ccb_head), 110662306a36Sopenharmony_ci /* 110762306a36Sopenharmony_ci * Initialize the status register 110862306a36Sopenharmony_ci */ 110962306a36Sopenharmony_ci SCR_COPY (4), 111062306a36Sopenharmony_ci HADDR_1 (ccb_head.status), 111162306a36Sopenharmony_ci RADDR_1 (scr0), 111262306a36Sopenharmony_ci /* 111362306a36Sopenharmony_ci * Jump to dispatcher. 111462306a36Sopenharmony_ci */ 111562306a36Sopenharmony_ci SCR_JUMP, 111662306a36Sopenharmony_ci PADDR_A (dispatch), 111762306a36Sopenharmony_ci}/*-------------------------< RESEL_NO_TAG >---------------------*/,{ 111862306a36Sopenharmony_ci /* 111962306a36Sopenharmony_ci * Copy the LCB header to a fixed place in 112062306a36Sopenharmony_ci * the HCB using self-modifying SCRIPTS. 112162306a36Sopenharmony_ci */ 112262306a36Sopenharmony_ci SCR_COPY (4), 112362306a36Sopenharmony_ci RADDR_1 (dsa), 112462306a36Sopenharmony_ci PADDR_A (_sms_a145), 112562306a36Sopenharmony_ci SCR_COPY (sizeof(struct sym_lcbh)), 112662306a36Sopenharmony_ci}/*-------------------------< _SMS_A145 >------------------------*/,{ 112762306a36Sopenharmony_ci 0, 112862306a36Sopenharmony_ci HADDR_1 (lcb_head), 112962306a36Sopenharmony_ci /* 113062306a36Sopenharmony_ci * Load the DSA with the unique ITL task. 113162306a36Sopenharmony_ci */ 113262306a36Sopenharmony_ci SCR_COPY (4), 113362306a36Sopenharmony_ci HADDR_1 (lcb_head.itl_task_sa), 113462306a36Sopenharmony_ci RADDR_1 (dsa), 113562306a36Sopenharmony_ci SCR_JUMP, 113662306a36Sopenharmony_ci PADDR_A (resel_go), 113762306a36Sopenharmony_ci}/*-------------------------< DATA_IN >--------------------------*/,{ 113862306a36Sopenharmony_ci/* 113962306a36Sopenharmony_ci * Because the size depends on the 114062306a36Sopenharmony_ci * #define SYM_CONF_MAX_SG parameter, 114162306a36Sopenharmony_ci * it is filled in at runtime. 114262306a36Sopenharmony_ci * 114362306a36Sopenharmony_ci * ##===========< i=0; i<SYM_CONF_MAX_SG >========= 114462306a36Sopenharmony_ci * || SCR_CHMOV_TBL ^ SCR_DATA_IN, 114562306a36Sopenharmony_ci * || offsetof (struct sym_dsb, data[ i]), 114662306a36Sopenharmony_ci * ##========================================== 114762306a36Sopenharmony_ci */ 114862306a36Sopenharmony_ci0 114962306a36Sopenharmony_ci}/*-------------------------< DATA_IN2 >-------------------------*/,{ 115062306a36Sopenharmony_ci SCR_CALL, 115162306a36Sopenharmony_ci PADDR_A (datai_done), 115262306a36Sopenharmony_ci SCR_JUMP, 115362306a36Sopenharmony_ci PADDR_B (data_ovrun), 115462306a36Sopenharmony_ci}/*-------------------------< DATA_OUT >-------------------------*/,{ 115562306a36Sopenharmony_ci/* 115662306a36Sopenharmony_ci * Because the size depends on the 115762306a36Sopenharmony_ci * #define SYM_CONF_MAX_SG parameter, 115862306a36Sopenharmony_ci * it is filled in at runtime. 115962306a36Sopenharmony_ci * 116062306a36Sopenharmony_ci * ##===========< i=0; i<SYM_CONF_MAX_SG >========= 116162306a36Sopenharmony_ci * || SCR_CHMOV_TBL ^ SCR_DATA_OUT, 116262306a36Sopenharmony_ci * || offsetof (struct sym_dsb, data[ i]), 116362306a36Sopenharmony_ci * ##========================================== 116462306a36Sopenharmony_ci */ 116562306a36Sopenharmony_ci0 116662306a36Sopenharmony_ci}/*-------------------------< DATA_OUT2 >------------------------*/,{ 116762306a36Sopenharmony_ci SCR_CALL, 116862306a36Sopenharmony_ci PADDR_A (datao_done), 116962306a36Sopenharmony_ci SCR_JUMP, 117062306a36Sopenharmony_ci PADDR_B (data_ovrun), 117162306a36Sopenharmony_ci}/*-------------------------< PM0_DATA >-------------------------*/,{ 117262306a36Sopenharmony_ci /* 117362306a36Sopenharmony_ci * Read our host flags to SFBR, so we will be able 117462306a36Sopenharmony_ci * to check against the data direction we expect. 117562306a36Sopenharmony_ci */ 117662306a36Sopenharmony_ci SCR_FROM_REG (HF_REG), 117762306a36Sopenharmony_ci 0, 117862306a36Sopenharmony_ci /* 117962306a36Sopenharmony_ci * Check against actual DATA PHASE. 118062306a36Sopenharmony_ci */ 118162306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 118262306a36Sopenharmony_ci PADDR_A (pm0_data_out), 118362306a36Sopenharmony_ci /* 118462306a36Sopenharmony_ci * Actual phase is DATA IN. 118562306a36Sopenharmony_ci * Check against expected direction. 118662306a36Sopenharmony_ci */ 118762306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), 118862306a36Sopenharmony_ci PADDR_B (data_ovrun), 118962306a36Sopenharmony_ci /* 119062306a36Sopenharmony_ci * Keep track we are moving data from the 119162306a36Sopenharmony_ci * PM0 DATA mini-script. 119262306a36Sopenharmony_ci */ 119362306a36Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 119462306a36Sopenharmony_ci 0, 119562306a36Sopenharmony_ci /* 119662306a36Sopenharmony_ci * Move the data to memory. 119762306a36Sopenharmony_ci */ 119862306a36Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 119962306a36Sopenharmony_ci offsetof (struct sym_ccb, phys.pm0.sg), 120062306a36Sopenharmony_ci SCR_JUMP, 120162306a36Sopenharmony_ci PADDR_A (pm0_data_end), 120262306a36Sopenharmony_ci}/*-------------------------< PM0_DATA_OUT >---------------------*/,{ 120362306a36Sopenharmony_ci /* 120462306a36Sopenharmony_ci * Actual phase is DATA OUT. 120562306a36Sopenharmony_ci * Check against expected direction. 120662306a36Sopenharmony_ci */ 120762306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), 120862306a36Sopenharmony_ci PADDR_B (data_ovrun), 120962306a36Sopenharmony_ci /* 121062306a36Sopenharmony_ci * Keep track we are moving data from the 121162306a36Sopenharmony_ci * PM0 DATA mini-script. 121262306a36Sopenharmony_ci */ 121362306a36Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 121462306a36Sopenharmony_ci 0, 121562306a36Sopenharmony_ci /* 121662306a36Sopenharmony_ci * Move the data from memory. 121762306a36Sopenharmony_ci */ 121862306a36Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_OUT, 121962306a36Sopenharmony_ci offsetof (struct sym_ccb, phys.pm0.sg), 122062306a36Sopenharmony_ci}/*-------------------------< PM0_DATA_END >---------------------*/,{ 122162306a36Sopenharmony_ci /* 122262306a36Sopenharmony_ci * Clear the flag that told we were moving 122362306a36Sopenharmony_ci * data from the PM0 DATA mini-script. 122462306a36Sopenharmony_ci */ 122562306a36Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)), 122662306a36Sopenharmony_ci 0, 122762306a36Sopenharmony_ci /* 122862306a36Sopenharmony_ci * Return to the previous DATA script which 122962306a36Sopenharmony_ci * is guaranteed by design (if no bug) to be 123062306a36Sopenharmony_ci * the main DATA script for this transfer. 123162306a36Sopenharmony_ci */ 123262306a36Sopenharmony_ci SCR_COPY (4), 123362306a36Sopenharmony_ci RADDR_1 (dsa), 123462306a36Sopenharmony_ci RADDR_1 (scratcha), 123562306a36Sopenharmony_ci SCR_REG_REG (scratcha, SCR_ADD, offsetof (struct sym_ccb,phys.pm0.ret)), 123662306a36Sopenharmony_ci 0, 123762306a36Sopenharmony_ci}/*-------------------------< PM_DATA_END >----------------------*/,{ 123862306a36Sopenharmony_ci SCR_COPY (4), 123962306a36Sopenharmony_ci RADDR_1 (scratcha), 124062306a36Sopenharmony_ci PADDR_A (_sms_a150), 124162306a36Sopenharmony_ci SCR_COPY (4), 124262306a36Sopenharmony_ci}/*-------------------------< _SMS_A150 >------------------------*/,{ 124362306a36Sopenharmony_ci 0, 124462306a36Sopenharmony_ci RADDR_1 (temp), 124562306a36Sopenharmony_ci SCR_RETURN, 124662306a36Sopenharmony_ci 0, 124762306a36Sopenharmony_ci}/*-------------------------< PM1_DATA >-------------------------*/,{ 124862306a36Sopenharmony_ci /* 124962306a36Sopenharmony_ci * Read our host flags to SFBR, so we will be able 125062306a36Sopenharmony_ci * to check against the data direction we expect. 125162306a36Sopenharmony_ci */ 125262306a36Sopenharmony_ci SCR_FROM_REG (HF_REG), 125362306a36Sopenharmony_ci 0, 125462306a36Sopenharmony_ci /* 125562306a36Sopenharmony_ci * Check against actual DATA PHASE. 125662306a36Sopenharmony_ci */ 125762306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 125862306a36Sopenharmony_ci PADDR_A (pm1_data_out), 125962306a36Sopenharmony_ci /* 126062306a36Sopenharmony_ci * Actual phase is DATA IN. 126162306a36Sopenharmony_ci * Check against expected direction. 126262306a36Sopenharmony_ci */ 126362306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), 126462306a36Sopenharmony_ci PADDR_B (data_ovrun), 126562306a36Sopenharmony_ci /* 126662306a36Sopenharmony_ci * Keep track we are moving data from the 126762306a36Sopenharmony_ci * PM1 DATA mini-script. 126862306a36Sopenharmony_ci */ 126962306a36Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 127062306a36Sopenharmony_ci 0, 127162306a36Sopenharmony_ci /* 127262306a36Sopenharmony_ci * Move the data to memory. 127362306a36Sopenharmony_ci */ 127462306a36Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 127562306a36Sopenharmony_ci offsetof (struct sym_ccb, phys.pm1.sg), 127662306a36Sopenharmony_ci SCR_JUMP, 127762306a36Sopenharmony_ci PADDR_A (pm1_data_end), 127862306a36Sopenharmony_ci}/*-------------------------< PM1_DATA_OUT >---------------------*/,{ 127962306a36Sopenharmony_ci /* 128062306a36Sopenharmony_ci * Actual phase is DATA OUT. 128162306a36Sopenharmony_ci * Check against expected direction. 128262306a36Sopenharmony_ci */ 128362306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), 128462306a36Sopenharmony_ci PADDR_B (data_ovrun), 128562306a36Sopenharmony_ci /* 128662306a36Sopenharmony_ci * Keep track we are moving data from the 128762306a36Sopenharmony_ci * PM1 DATA mini-script. 128862306a36Sopenharmony_ci */ 128962306a36Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 129062306a36Sopenharmony_ci 0, 129162306a36Sopenharmony_ci /* 129262306a36Sopenharmony_ci * Move the data from memory. 129362306a36Sopenharmony_ci */ 129462306a36Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_OUT, 129562306a36Sopenharmony_ci offsetof (struct sym_ccb, phys.pm1.sg), 129662306a36Sopenharmony_ci}/*-------------------------< PM1_DATA_END >---------------------*/,{ 129762306a36Sopenharmony_ci /* 129862306a36Sopenharmony_ci * Clear the flag that told we were moving 129962306a36Sopenharmony_ci * data from the PM1 DATA mini-script. 130062306a36Sopenharmony_ci */ 130162306a36Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)), 130262306a36Sopenharmony_ci 0, 130362306a36Sopenharmony_ci /* 130462306a36Sopenharmony_ci * Return to the previous DATA script which 130562306a36Sopenharmony_ci * is guaranteed by design (if no bug) to be 130662306a36Sopenharmony_ci * the main DATA script for this transfer. 130762306a36Sopenharmony_ci */ 130862306a36Sopenharmony_ci SCR_COPY (4), 130962306a36Sopenharmony_ci RADDR_1 (dsa), 131062306a36Sopenharmony_ci RADDR_1 (scratcha), 131162306a36Sopenharmony_ci SCR_REG_REG (scratcha, SCR_ADD, offsetof (struct sym_ccb,phys.pm1.ret)), 131262306a36Sopenharmony_ci 0, 131362306a36Sopenharmony_ci SCR_JUMP, 131462306a36Sopenharmony_ci PADDR_A (pm_data_end), 131562306a36Sopenharmony_ci}/*--------------------------<>----------------------------------*/ 131662306a36Sopenharmony_ci}; 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_cistatic struct SYM_FWB_SCR SYM_FWB_SCR = { 131962306a36Sopenharmony_ci/*-------------------------< NO_DATA >--------------------------*/ { 132062306a36Sopenharmony_ci SCR_JUMP, 132162306a36Sopenharmony_ci PADDR_B (data_ovrun), 132262306a36Sopenharmony_ci}/*-------------------------< SEL_FOR_ABORT >--------------------*/,{ 132362306a36Sopenharmony_ci /* 132462306a36Sopenharmony_ci * We are jumped here by the C code, if we have 132562306a36Sopenharmony_ci * some target to reset or some disconnected 132662306a36Sopenharmony_ci * job to abort. Since error recovery is a serious 132762306a36Sopenharmony_ci * busyness, we will really reset the SCSI BUS, if 132862306a36Sopenharmony_ci * case of a SCSI interrupt occurring in this path. 132962306a36Sopenharmony_ci */ 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 133262306a36Sopenharmony_ci /* 133362306a36Sopenharmony_ci * Set initiator mode. 133462306a36Sopenharmony_ci */ 133562306a36Sopenharmony_ci SCR_CLR (SCR_TRG), 133662306a36Sopenharmony_ci 0, 133762306a36Sopenharmony_ci#endif 133862306a36Sopenharmony_ci /* 133962306a36Sopenharmony_ci * And try to select this target. 134062306a36Sopenharmony_ci */ 134162306a36Sopenharmony_ci SCR_SEL_TBL_ATN ^ offsetof (struct sym_hcb, abrt_sel), 134262306a36Sopenharmony_ci PADDR_A (reselect), 134362306a36Sopenharmony_ci /* 134462306a36Sopenharmony_ci * Wait for the selection to complete or 134562306a36Sopenharmony_ci * the selection to time out. 134662306a36Sopenharmony_ci */ 134762306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)), 134862306a36Sopenharmony_ci -8, 134962306a36Sopenharmony_ci /* 135062306a36Sopenharmony_ci * Call the C code. 135162306a36Sopenharmony_ci */ 135262306a36Sopenharmony_ci SCR_INT, 135362306a36Sopenharmony_ci SIR_TARGET_SELECTED, 135462306a36Sopenharmony_ci /* 135562306a36Sopenharmony_ci * The C code should let us continue here. 135662306a36Sopenharmony_ci * Send the 'kiss of death' message. 135762306a36Sopenharmony_ci * We expect an immediate disconnect once 135862306a36Sopenharmony_ci * the target has eaten the message. 135962306a36Sopenharmony_ci */ 136062306a36Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 136162306a36Sopenharmony_ci 0, 136262306a36Sopenharmony_ci SCR_MOVE_TBL ^ SCR_MSG_OUT, 136362306a36Sopenharmony_ci offsetof (struct sym_hcb, abrt_tbl), 136462306a36Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 136562306a36Sopenharmony_ci 0, 136662306a36Sopenharmony_ci SCR_WAIT_DISC, 136762306a36Sopenharmony_ci 0, 136862306a36Sopenharmony_ci /* 136962306a36Sopenharmony_ci * Tell the C code that we are done. 137062306a36Sopenharmony_ci */ 137162306a36Sopenharmony_ci SCR_INT, 137262306a36Sopenharmony_ci SIR_ABORT_SENT, 137362306a36Sopenharmony_ci}/*-------------------------< SEL_FOR_ABORT_1 >------------------*/,{ 137462306a36Sopenharmony_ci /* 137562306a36Sopenharmony_ci * Jump at scheduler. 137662306a36Sopenharmony_ci */ 137762306a36Sopenharmony_ci SCR_JUMP, 137862306a36Sopenharmony_ci PADDR_A (start), 137962306a36Sopenharmony_ci}/*-------------------------< MSG_IN_ETC >-----------------------*/,{ 138062306a36Sopenharmony_ci /* 138162306a36Sopenharmony_ci * If it is an EXTENDED (variable size message) 138262306a36Sopenharmony_ci * Handle it. 138362306a36Sopenharmony_ci */ 138462306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), 138562306a36Sopenharmony_ci PADDR_B (msg_extended), 138662306a36Sopenharmony_ci /* 138762306a36Sopenharmony_ci * Let the C code handle any other 138862306a36Sopenharmony_ci * 1 byte message. 138962306a36Sopenharmony_ci */ 139062306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0x00, 0xf0)), 139162306a36Sopenharmony_ci PADDR_B (msg_received), 139262306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0x10, 0xf0)), 139362306a36Sopenharmony_ci PADDR_B (msg_received), 139462306a36Sopenharmony_ci /* 139562306a36Sopenharmony_ci * We donnot handle 2 bytes messages from SCRIPTS. 139662306a36Sopenharmony_ci * So, let the C code deal with these ones too. 139762306a36Sopenharmony_ci */ 139862306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (0x20, 0xf0)), 139962306a36Sopenharmony_ci PADDR_B (msg_weird_seen), 140062306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 140162306a36Sopenharmony_ci 0, 140262306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 140362306a36Sopenharmony_ci HADDR_1 (msgin[1]), 140462306a36Sopenharmony_ci}/*-------------------------< MSG_RECEIVED >---------------------*/,{ 140562306a36Sopenharmony_ci SCR_COPY (4), /* DUMMY READ */ 140662306a36Sopenharmony_ci HADDR_1 (scratch), 140762306a36Sopenharmony_ci RADDR_1 (scratcha), 140862306a36Sopenharmony_ci SCR_INT, 140962306a36Sopenharmony_ci SIR_MSG_RECEIVED, 141062306a36Sopenharmony_ci}/*-------------------------< MSG_WEIRD_SEEN >-------------------*/,{ 141162306a36Sopenharmony_ci SCR_COPY (4), /* DUMMY READ */ 141262306a36Sopenharmony_ci HADDR_1 (scratch), 141362306a36Sopenharmony_ci RADDR_1 (scratcha), 141462306a36Sopenharmony_ci SCR_INT, 141562306a36Sopenharmony_ci SIR_MSG_WEIRD, 141662306a36Sopenharmony_ci}/*-------------------------< MSG_EXTENDED >---------------------*/,{ 141762306a36Sopenharmony_ci /* 141862306a36Sopenharmony_ci * Clear ACK and get the next byte 141962306a36Sopenharmony_ci * assumed to be the message length. 142062306a36Sopenharmony_ci */ 142162306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 142262306a36Sopenharmony_ci 0, 142362306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 142462306a36Sopenharmony_ci HADDR_1 (msgin[1]), 142562306a36Sopenharmony_ci /* 142662306a36Sopenharmony_ci * Try to catch some unlikely situations as 0 length 142762306a36Sopenharmony_ci * or too large the length. 142862306a36Sopenharmony_ci */ 142962306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (0)), 143062306a36Sopenharmony_ci PADDR_B (msg_weird_seen), 143162306a36Sopenharmony_ci SCR_TO_REG (scratcha), 143262306a36Sopenharmony_ci 0, 143362306a36Sopenharmony_ci SCR_REG_REG (sfbr, SCR_ADD, (256-8)), 143462306a36Sopenharmony_ci 0, 143562306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (CARRYSET), 143662306a36Sopenharmony_ci PADDR_B (msg_weird_seen), 143762306a36Sopenharmony_ci /* 143862306a36Sopenharmony_ci * We donnot handle extended messages from SCRIPTS. 143962306a36Sopenharmony_ci * Read the amount of data corresponding to the 144062306a36Sopenharmony_ci * message length and call the C code. 144162306a36Sopenharmony_ci */ 144262306a36Sopenharmony_ci SCR_COPY (1), 144362306a36Sopenharmony_ci RADDR_1 (scratcha), 144462306a36Sopenharmony_ci PADDR_B (_sms_b10), 144562306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 144662306a36Sopenharmony_ci 0, 144762306a36Sopenharmony_ci}/*-------------------------< _SMS_B10 >-------------------------*/,{ 144862306a36Sopenharmony_ci SCR_MOVE_ABS (0) ^ SCR_MSG_IN, 144962306a36Sopenharmony_ci HADDR_1 (msgin[2]), 145062306a36Sopenharmony_ci SCR_JUMP, 145162306a36Sopenharmony_ci PADDR_B (msg_received), 145262306a36Sopenharmony_ci}/*-------------------------< MSG_BAD >--------------------------*/,{ 145362306a36Sopenharmony_ci /* 145462306a36Sopenharmony_ci * unimplemented message - reject it. 145562306a36Sopenharmony_ci */ 145662306a36Sopenharmony_ci SCR_INT, 145762306a36Sopenharmony_ci SIR_REJECT_TO_SEND, 145862306a36Sopenharmony_ci SCR_SET (SCR_ATN), 145962306a36Sopenharmony_ci 0, 146062306a36Sopenharmony_ci SCR_JUMP, 146162306a36Sopenharmony_ci PADDR_A (clrack), 146262306a36Sopenharmony_ci}/*-------------------------< MSG_WEIRD >------------------------*/,{ 146362306a36Sopenharmony_ci /* 146462306a36Sopenharmony_ci * weird message received 146562306a36Sopenharmony_ci * ignore all MSG IN phases and reject it. 146662306a36Sopenharmony_ci */ 146762306a36Sopenharmony_ci SCR_INT, 146862306a36Sopenharmony_ci SIR_REJECT_TO_SEND, 146962306a36Sopenharmony_ci SCR_SET (SCR_ATN), 147062306a36Sopenharmony_ci 0, 147162306a36Sopenharmony_ci}/*-------------------------< MSG_WEIRD1 >-----------------------*/,{ 147262306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 147362306a36Sopenharmony_ci 0, 147462306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 147562306a36Sopenharmony_ci PADDR_A (dispatch), 147662306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 147762306a36Sopenharmony_ci HADDR_1 (scratch), 147862306a36Sopenharmony_ci SCR_JUMP, 147962306a36Sopenharmony_ci PADDR_B (msg_weird1), 148062306a36Sopenharmony_ci}/*-------------------------< WDTR_RESP >------------------------*/,{ 148162306a36Sopenharmony_ci /* 148262306a36Sopenharmony_ci * let the target fetch our answer. 148362306a36Sopenharmony_ci */ 148462306a36Sopenharmony_ci SCR_SET (SCR_ATN), 148562306a36Sopenharmony_ci 0, 148662306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 148762306a36Sopenharmony_ci 0, 148862306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 148962306a36Sopenharmony_ci PADDR_B (nego_bad_phase), 149062306a36Sopenharmony_ci}/*-------------------------< SEND_WDTR >------------------------*/,{ 149162306a36Sopenharmony_ci /* 149262306a36Sopenharmony_ci * Send the M_X_WIDE_REQ 149362306a36Sopenharmony_ci */ 149462306a36Sopenharmony_ci SCR_MOVE_ABS (4) ^ SCR_MSG_OUT, 149562306a36Sopenharmony_ci HADDR_1 (msgout), 149662306a36Sopenharmony_ci SCR_JUMP, 149762306a36Sopenharmony_ci PADDR_B (msg_out_done), 149862306a36Sopenharmony_ci}/*-------------------------< SDTR_RESP >------------------------*/,{ 149962306a36Sopenharmony_ci /* 150062306a36Sopenharmony_ci * let the target fetch our answer. 150162306a36Sopenharmony_ci */ 150262306a36Sopenharmony_ci SCR_SET (SCR_ATN), 150362306a36Sopenharmony_ci 0, 150462306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 150562306a36Sopenharmony_ci 0, 150662306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 150762306a36Sopenharmony_ci PADDR_B (nego_bad_phase), 150862306a36Sopenharmony_ci}/*-------------------------< SEND_SDTR >------------------------*/,{ 150962306a36Sopenharmony_ci /* 151062306a36Sopenharmony_ci * Send the M_X_SYNC_REQ 151162306a36Sopenharmony_ci */ 151262306a36Sopenharmony_ci SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, 151362306a36Sopenharmony_ci HADDR_1 (msgout), 151462306a36Sopenharmony_ci SCR_JUMP, 151562306a36Sopenharmony_ci PADDR_B (msg_out_done), 151662306a36Sopenharmony_ci}/*-------------------------< PPR_RESP >-------------------------*/,{ 151762306a36Sopenharmony_ci /* 151862306a36Sopenharmony_ci * let the target fetch our answer. 151962306a36Sopenharmony_ci */ 152062306a36Sopenharmony_ci SCR_SET (SCR_ATN), 152162306a36Sopenharmony_ci 0, 152262306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 152362306a36Sopenharmony_ci 0, 152462306a36Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 152562306a36Sopenharmony_ci PADDR_B (nego_bad_phase), 152662306a36Sopenharmony_ci}/*-------------------------< SEND_PPR >-------------------------*/,{ 152762306a36Sopenharmony_ci /* 152862306a36Sopenharmony_ci * Send the M_X_PPR_REQ 152962306a36Sopenharmony_ci */ 153062306a36Sopenharmony_ci SCR_MOVE_ABS (8) ^ SCR_MSG_OUT, 153162306a36Sopenharmony_ci HADDR_1 (msgout), 153262306a36Sopenharmony_ci SCR_JUMP, 153362306a36Sopenharmony_ci PADDR_B (msg_out_done), 153462306a36Sopenharmony_ci}/*-------------------------< NEGO_BAD_PHASE >-------------------*/,{ 153562306a36Sopenharmony_ci SCR_INT, 153662306a36Sopenharmony_ci SIR_NEGO_PROTO, 153762306a36Sopenharmony_ci SCR_JUMP, 153862306a36Sopenharmony_ci PADDR_A (dispatch), 153962306a36Sopenharmony_ci}/*-------------------------< MSG_OUT >--------------------------*/,{ 154062306a36Sopenharmony_ci /* 154162306a36Sopenharmony_ci * The target requests a message. 154262306a36Sopenharmony_ci * We donnot send messages that may 154362306a36Sopenharmony_ci * require the device to go to bus free. 154462306a36Sopenharmony_ci */ 154562306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 154662306a36Sopenharmony_ci HADDR_1 (msgout), 154762306a36Sopenharmony_ci /* 154862306a36Sopenharmony_ci * ... wait for the next phase 154962306a36Sopenharmony_ci * if it's a message out, send it again, ... 155062306a36Sopenharmony_ci */ 155162306a36Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), 155262306a36Sopenharmony_ci PADDR_B (msg_out), 155362306a36Sopenharmony_ci}/*-------------------------< MSG_OUT_DONE >---------------------*/,{ 155462306a36Sopenharmony_ci /* 155562306a36Sopenharmony_ci * Let the C code be aware of the 155662306a36Sopenharmony_ci * sent message and clear the message. 155762306a36Sopenharmony_ci */ 155862306a36Sopenharmony_ci SCR_INT, 155962306a36Sopenharmony_ci SIR_MSG_OUT_DONE, 156062306a36Sopenharmony_ci /* 156162306a36Sopenharmony_ci * ... and process the next phase 156262306a36Sopenharmony_ci */ 156362306a36Sopenharmony_ci SCR_JUMP, 156462306a36Sopenharmony_ci PADDR_A (dispatch), 156562306a36Sopenharmony_ci}/*-------------------------< DATA_OVRUN >-----------------------*/,{ 156662306a36Sopenharmony_ci /* 156762306a36Sopenharmony_ci * Zero scratcha that will count the 156862306a36Sopenharmony_ci * extras bytes. 156962306a36Sopenharmony_ci */ 157062306a36Sopenharmony_ci SCR_COPY (4), 157162306a36Sopenharmony_ci PADDR_B (zero), 157262306a36Sopenharmony_ci RADDR_1 (scratcha), 157362306a36Sopenharmony_ci}/*-------------------------< DATA_OVRUN1 >----------------------*/,{ 157462306a36Sopenharmony_ci /* 157562306a36Sopenharmony_ci * The target may want to transfer too much data. 157662306a36Sopenharmony_ci * 157762306a36Sopenharmony_ci * If phase is DATA OUT write 1 byte and count it. 157862306a36Sopenharmony_ci */ 157962306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)), 158062306a36Sopenharmony_ci 16, 158162306a36Sopenharmony_ci SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT, 158262306a36Sopenharmony_ci HADDR_1 (scratch), 158362306a36Sopenharmony_ci SCR_JUMP, 158462306a36Sopenharmony_ci PADDR_B (data_ovrun2), 158562306a36Sopenharmony_ci /* 158662306a36Sopenharmony_ci * If WSR is set, clear this condition, and 158762306a36Sopenharmony_ci * count this byte. 158862306a36Sopenharmony_ci */ 158962306a36Sopenharmony_ci SCR_FROM_REG (scntl2), 159062306a36Sopenharmony_ci 0, 159162306a36Sopenharmony_ci SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)), 159262306a36Sopenharmony_ci 16, 159362306a36Sopenharmony_ci SCR_REG_REG (scntl2, SCR_OR, WSR), 159462306a36Sopenharmony_ci 0, 159562306a36Sopenharmony_ci SCR_JUMP, 159662306a36Sopenharmony_ci PADDR_B (data_ovrun2), 159762306a36Sopenharmony_ci /* 159862306a36Sopenharmony_ci * Finally check against DATA IN phase. 159962306a36Sopenharmony_ci * Signal data overrun to the C code 160062306a36Sopenharmony_ci * and jump to dispatcher if not so. 160162306a36Sopenharmony_ci * Read 1 byte otherwise and count it. 160262306a36Sopenharmony_ci */ 160362306a36Sopenharmony_ci SCR_JUMPR ^ IFTRUE (WHEN (SCR_DATA_IN)), 160462306a36Sopenharmony_ci 16, 160562306a36Sopenharmony_ci SCR_INT, 160662306a36Sopenharmony_ci SIR_DATA_OVERRUN, 160762306a36Sopenharmony_ci SCR_JUMP, 160862306a36Sopenharmony_ci PADDR_A (dispatch), 160962306a36Sopenharmony_ci SCR_CHMOV_ABS (1) ^ SCR_DATA_IN, 161062306a36Sopenharmony_ci HADDR_1 (scratch), 161162306a36Sopenharmony_ci}/*-------------------------< DATA_OVRUN2 >----------------------*/,{ 161262306a36Sopenharmony_ci /* 161362306a36Sopenharmony_ci * Count this byte. 161462306a36Sopenharmony_ci * This will allow to return a negative 161562306a36Sopenharmony_ci * residual to user. 161662306a36Sopenharmony_ci */ 161762306a36Sopenharmony_ci SCR_REG_REG (scratcha, SCR_ADD, 0x01), 161862306a36Sopenharmony_ci 0, 161962306a36Sopenharmony_ci SCR_REG_REG (scratcha1, SCR_ADDC, 0), 162062306a36Sopenharmony_ci 0, 162162306a36Sopenharmony_ci SCR_REG_REG (scratcha2, SCR_ADDC, 0), 162262306a36Sopenharmony_ci 0, 162362306a36Sopenharmony_ci /* 162462306a36Sopenharmony_ci * .. and repeat as required. 162562306a36Sopenharmony_ci */ 162662306a36Sopenharmony_ci SCR_JUMP, 162762306a36Sopenharmony_ci PADDR_B (data_ovrun1), 162862306a36Sopenharmony_ci}/*-------------------------< ABORT_RESEL >----------------------*/,{ 162962306a36Sopenharmony_ci SCR_SET (SCR_ATN), 163062306a36Sopenharmony_ci 0, 163162306a36Sopenharmony_ci SCR_CLR (SCR_ACK), 163262306a36Sopenharmony_ci 0, 163362306a36Sopenharmony_ci /* 163462306a36Sopenharmony_ci * send the abort/abortag/reset message 163562306a36Sopenharmony_ci * we expect an immediate disconnect 163662306a36Sopenharmony_ci */ 163762306a36Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 163862306a36Sopenharmony_ci 0, 163962306a36Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 164062306a36Sopenharmony_ci HADDR_1 (msgout), 164162306a36Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 164262306a36Sopenharmony_ci 0, 164362306a36Sopenharmony_ci SCR_WAIT_DISC, 164462306a36Sopenharmony_ci 0, 164562306a36Sopenharmony_ci SCR_INT, 164662306a36Sopenharmony_ci SIR_RESEL_ABORTED, 164762306a36Sopenharmony_ci SCR_JUMP, 164862306a36Sopenharmony_ci PADDR_A (start), 164962306a36Sopenharmony_ci}/*-------------------------< RESEND_IDENT >---------------------*/,{ 165062306a36Sopenharmony_ci /* 165162306a36Sopenharmony_ci * The target stays in MSG OUT phase after having acked 165262306a36Sopenharmony_ci * Identify [+ Tag [+ Extended message ]]. Targets shall 165362306a36Sopenharmony_ci * behave this way on parity error. 165462306a36Sopenharmony_ci * We must send it again all the messages. 165562306a36Sopenharmony_ci */ 165662306a36Sopenharmony_ci SCR_SET (SCR_ATN), /* Shall be asserted 2 deskew delays before the */ 165762306a36Sopenharmony_ci 0, /* 1rst ACK = 90 ns. Hope the chip isn't too fast */ 165862306a36Sopenharmony_ci SCR_JUMP, 165962306a36Sopenharmony_ci PADDR_A (send_ident), 166062306a36Sopenharmony_ci}/*-------------------------< IDENT_BREAK >----------------------*/,{ 166162306a36Sopenharmony_ci SCR_CLR (SCR_ATN), 166262306a36Sopenharmony_ci 0, 166362306a36Sopenharmony_ci SCR_JUMP, 166462306a36Sopenharmony_ci PADDR_A (select2), 166562306a36Sopenharmony_ci}/*-------------------------< IDENT_BREAK_ATN >------------------*/,{ 166662306a36Sopenharmony_ci SCR_SET (SCR_ATN), 166762306a36Sopenharmony_ci 0, 166862306a36Sopenharmony_ci SCR_JUMP, 166962306a36Sopenharmony_ci PADDR_A (select2), 167062306a36Sopenharmony_ci}/*-------------------------< SDATA_IN >-------------------------*/,{ 167162306a36Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 167262306a36Sopenharmony_ci offsetof (struct sym_dsb, sense), 167362306a36Sopenharmony_ci SCR_CALL, 167462306a36Sopenharmony_ci PADDR_A (datai_done), 167562306a36Sopenharmony_ci SCR_JUMP, 167662306a36Sopenharmony_ci PADDR_B (data_ovrun), 167762306a36Sopenharmony_ci}/*-------------------------< RESEL_BAD_LUN >--------------------*/,{ 167862306a36Sopenharmony_ci /* 167962306a36Sopenharmony_ci * Message is an IDENTIFY, but lun is unknown. 168062306a36Sopenharmony_ci * Signal problem to C code for logging the event. 168162306a36Sopenharmony_ci * Send a M_ABORT to clear all pending tasks. 168262306a36Sopenharmony_ci */ 168362306a36Sopenharmony_ci SCR_INT, 168462306a36Sopenharmony_ci SIR_RESEL_BAD_LUN, 168562306a36Sopenharmony_ci SCR_JUMP, 168662306a36Sopenharmony_ci PADDR_B (abort_resel), 168762306a36Sopenharmony_ci}/*-------------------------< BAD_I_T_L >------------------------*/,{ 168862306a36Sopenharmony_ci /* 168962306a36Sopenharmony_ci * We donnot have a task for that I_T_L. 169062306a36Sopenharmony_ci * Signal problem to C code for logging the event. 169162306a36Sopenharmony_ci * Send a M_ABORT message. 169262306a36Sopenharmony_ci */ 169362306a36Sopenharmony_ci SCR_INT, 169462306a36Sopenharmony_ci SIR_RESEL_BAD_I_T_L, 169562306a36Sopenharmony_ci SCR_JUMP, 169662306a36Sopenharmony_ci PADDR_B (abort_resel), 169762306a36Sopenharmony_ci}/*-------------------------< BAD_I_T_L_Q >----------------------*/,{ 169862306a36Sopenharmony_ci /* 169962306a36Sopenharmony_ci * We donnot have a task that matches the tag. 170062306a36Sopenharmony_ci * Signal problem to C code for logging the event. 170162306a36Sopenharmony_ci * Send a M_ABORTTAG message. 170262306a36Sopenharmony_ci */ 170362306a36Sopenharmony_ci SCR_INT, 170462306a36Sopenharmony_ci SIR_RESEL_BAD_I_T_L_Q, 170562306a36Sopenharmony_ci SCR_JUMP, 170662306a36Sopenharmony_ci PADDR_B (abort_resel), 170762306a36Sopenharmony_ci}/*-------------------------< BAD_STATUS >-----------------------*/,{ 170862306a36Sopenharmony_ci /* 170962306a36Sopenharmony_ci * Anything different from INTERMEDIATE 171062306a36Sopenharmony_ci * CONDITION MET should be a bad SCSI status, 171162306a36Sopenharmony_ci * given that GOOD status has already been tested. 171262306a36Sopenharmony_ci * Call the C code. 171362306a36Sopenharmony_ci */ 171462306a36Sopenharmony_ci SCR_COPY (4), 171562306a36Sopenharmony_ci PADDR_B (startpos), 171662306a36Sopenharmony_ci RADDR_1 (scratcha), 171762306a36Sopenharmony_ci SCR_INT ^ IFFALSE (DATA (S_COND_MET)), 171862306a36Sopenharmony_ci SIR_BAD_SCSI_STATUS, 171962306a36Sopenharmony_ci SCR_RETURN, 172062306a36Sopenharmony_ci 0, 172162306a36Sopenharmony_ci}/*-------------------------< WSR_MA_HELPER >--------------------*/,{ 172262306a36Sopenharmony_ci /* 172362306a36Sopenharmony_ci * Helper for the C code when WSR bit is set. 172462306a36Sopenharmony_ci * Perform the move of the residual byte. 172562306a36Sopenharmony_ci */ 172662306a36Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 172762306a36Sopenharmony_ci offsetof (struct sym_ccb, phys.wresid), 172862306a36Sopenharmony_ci SCR_JUMP, 172962306a36Sopenharmony_ci PADDR_A (dispatch), 173062306a36Sopenharmony_ci 173162306a36Sopenharmony_ci}/*-------------------------< ZERO >-----------------------------*/,{ 173262306a36Sopenharmony_ci SCR_DATA_ZERO, 173362306a36Sopenharmony_ci}/*-------------------------< SCRATCH >--------------------------*/,{ 173462306a36Sopenharmony_ci SCR_DATA_ZERO, /* MUST BE BEFORE SCRATCH1 */ 173562306a36Sopenharmony_ci}/*-------------------------< SCRATCH1 >-------------------------*/,{ 173662306a36Sopenharmony_ci SCR_DATA_ZERO, 173762306a36Sopenharmony_ci}/*-------------------------< PREV_DONE >------------------------*/,{ 173862306a36Sopenharmony_ci SCR_DATA_ZERO, /* MUST BE BEFORE DONE_POS ! */ 173962306a36Sopenharmony_ci}/*-------------------------< DONE_POS >-------------------------*/,{ 174062306a36Sopenharmony_ci SCR_DATA_ZERO, 174162306a36Sopenharmony_ci}/*-------------------------< NEXTJOB >--------------------------*/,{ 174262306a36Sopenharmony_ci SCR_DATA_ZERO, /* MUST BE BEFORE STARTPOS ! */ 174362306a36Sopenharmony_ci}/*-------------------------< STARTPOS >-------------------------*/,{ 174462306a36Sopenharmony_ci SCR_DATA_ZERO, 174562306a36Sopenharmony_ci}/*-------------------------< TARGTBL >--------------------------*/,{ 174662306a36Sopenharmony_ci SCR_DATA_ZERO, 174762306a36Sopenharmony_ci}/*--------------------------<>----------------------------------*/ 174862306a36Sopenharmony_ci}; 174962306a36Sopenharmony_ci 175062306a36Sopenharmony_cistatic struct SYM_FWZ_SCR SYM_FWZ_SCR = { 175162306a36Sopenharmony_ci /*-------------------------< SNOOPTEST >------------------------*/{ 175262306a36Sopenharmony_ci /* 175362306a36Sopenharmony_ci * Read the variable. 175462306a36Sopenharmony_ci */ 175562306a36Sopenharmony_ci SCR_COPY (4), 175662306a36Sopenharmony_ci HADDR_1 (scratch), 175762306a36Sopenharmony_ci RADDR_1 (scratcha), 175862306a36Sopenharmony_ci /* 175962306a36Sopenharmony_ci * Write the variable. 176062306a36Sopenharmony_ci */ 176162306a36Sopenharmony_ci SCR_COPY (4), 176262306a36Sopenharmony_ci RADDR_1 (temp), 176362306a36Sopenharmony_ci HADDR_1 (scratch), 176462306a36Sopenharmony_ci /* 176562306a36Sopenharmony_ci * Read back the variable. 176662306a36Sopenharmony_ci */ 176762306a36Sopenharmony_ci SCR_COPY (4), 176862306a36Sopenharmony_ci HADDR_1 (scratch), 176962306a36Sopenharmony_ci RADDR_1 (temp), 177062306a36Sopenharmony_ci}/*-------------------------< SNOOPEND >-------------------------*/,{ 177162306a36Sopenharmony_ci /* 177262306a36Sopenharmony_ci * And stop. 177362306a36Sopenharmony_ci */ 177462306a36Sopenharmony_ci SCR_INT, 177562306a36Sopenharmony_ci 99, 177662306a36Sopenharmony_ci}/*--------------------------<>----------------------------------*/ 177762306a36Sopenharmony_ci}; 1778