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