18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 48c2ecf20Sopenharmony_ci * of PCI-SCSI IO processors. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This driver is derived from the Linux sym53c8xx driver. 98c2ecf20Sopenharmony_ci * Copyright (C) 1998-2000 Gerard Roudier 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 128c2ecf20Sopenharmony_ci * a port of the FreeBSD ncr driver to Linux-1.2.13. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * The original ncr driver has been written for 386bsd and FreeBSD by 158c2ecf20Sopenharmony_ci * Wolfgang Stanglmeier <wolf@cologne.de> 168c2ecf20Sopenharmony_ci * Stefan Esser <se@mi.Uni-Koeln.de> 178c2ecf20Sopenharmony_ci * Copyright (C) 1994 Wolfgang Stanglmeier 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * Other major contributions: 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * NVRAM detection and reading. 228c2ecf20Sopenharmony_ci * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci *----------------------------------------------------------------------------- 258c2ecf20Sopenharmony_ci */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* 288c2ecf20Sopenharmony_ci * Scripts for SYMBIOS-Processor 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci * We have to know the offsets of all labels before we reach 318c2ecf20Sopenharmony_ci * them (for forward jumps). Therefore we declare a struct 328c2ecf20Sopenharmony_ci * here. If you make changes inside the script, 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci * DONT FORGET TO CHANGE THE LENGTHS HERE! 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* 388c2ecf20Sopenharmony_ci * Script fragments which are loaded into the on-chip RAM 398c2ecf20Sopenharmony_ci * of 825A, 875, 876, 895, 895A, 896 and 1010 chips. 408c2ecf20Sopenharmony_ci * Must not exceed 4K bytes. 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_cistruct SYM_FWA_SCR { 438c2ecf20Sopenharmony_ci u32 start [ 14]; 448c2ecf20Sopenharmony_ci u32 getjob_begin [ 4]; 458c2ecf20Sopenharmony_ci u32 getjob_end [ 4]; 468c2ecf20Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 478c2ecf20Sopenharmony_ci u32 select [ 6]; 488c2ecf20Sopenharmony_ci#else 498c2ecf20Sopenharmony_ci u32 select [ 4]; 508c2ecf20Sopenharmony_ci#endif 518c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 2 528c2ecf20Sopenharmony_ci u32 is_dmap_dirty [ 4]; 538c2ecf20Sopenharmony_ci#endif 548c2ecf20Sopenharmony_ci u32 wf_sel_done [ 2]; 558c2ecf20Sopenharmony_ci u32 sel_done [ 2]; 568c2ecf20Sopenharmony_ci u32 send_ident [ 2]; 578c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 588c2ecf20Sopenharmony_ci u32 select2 [ 8]; 598c2ecf20Sopenharmony_ci#else 608c2ecf20Sopenharmony_ci u32 select2 [ 2]; 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci u32 command [ 2]; 638c2ecf20Sopenharmony_ci u32 dispatch [ 28]; 648c2ecf20Sopenharmony_ci u32 sel_no_cmd [ 10]; 658c2ecf20Sopenharmony_ci u32 init [ 6]; 668c2ecf20Sopenharmony_ci u32 clrack [ 4]; 678c2ecf20Sopenharmony_ci u32 datai_done [ 10]; 688c2ecf20Sopenharmony_ci u32 datai_done_wsr [ 20]; 698c2ecf20Sopenharmony_ci u32 datao_done [ 10]; 708c2ecf20Sopenharmony_ci u32 datao_done_wss [ 6]; 718c2ecf20Sopenharmony_ci u32 datai_phase [ 4]; 728c2ecf20Sopenharmony_ci u32 datao_phase [ 6]; 738c2ecf20Sopenharmony_ci u32 msg_in [ 2]; 748c2ecf20Sopenharmony_ci u32 msg_in2 [ 10]; 758c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 768c2ecf20Sopenharmony_ci u32 status [ 14]; 778c2ecf20Sopenharmony_ci#else 788c2ecf20Sopenharmony_ci u32 status [ 10]; 798c2ecf20Sopenharmony_ci#endif 808c2ecf20Sopenharmony_ci u32 complete [ 6]; 818c2ecf20Sopenharmony_ci u32 complete2 [ 12]; 828c2ecf20Sopenharmony_ci u32 done [ 14]; 838c2ecf20Sopenharmony_ci u32 done_end [ 2]; 848c2ecf20Sopenharmony_ci u32 complete_error [ 4]; 858c2ecf20Sopenharmony_ci u32 save_dp [ 12]; 868c2ecf20Sopenharmony_ci u32 restore_dp [ 8]; 878c2ecf20Sopenharmony_ci u32 disconnect [ 12]; 888c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 898c2ecf20Sopenharmony_ci u32 idle [ 4]; 908c2ecf20Sopenharmony_ci#else 918c2ecf20Sopenharmony_ci u32 idle [ 2]; 928c2ecf20Sopenharmony_ci#endif 938c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 948c2ecf20Sopenharmony_ci u32 ungetjob [ 6]; 958c2ecf20Sopenharmony_ci#else 968c2ecf20Sopenharmony_ci u32 ungetjob [ 4]; 978c2ecf20Sopenharmony_ci#endif 988c2ecf20Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 998c2ecf20Sopenharmony_ci u32 reselect [ 4]; 1008c2ecf20Sopenharmony_ci#else 1018c2ecf20Sopenharmony_ci u32 reselect [ 2]; 1028c2ecf20Sopenharmony_ci#endif 1038c2ecf20Sopenharmony_ci u32 reselected [ 22]; 1048c2ecf20Sopenharmony_ci u32 resel_scntl4 [ 20]; 1058c2ecf20Sopenharmony_ci u32 resel_lun0 [ 6]; 1068c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_TASK*4 > 512 1078c2ecf20Sopenharmony_ci u32 resel_tag [ 26]; 1088c2ecf20Sopenharmony_ci#elif SYM_CONF_MAX_TASK*4 > 256 1098c2ecf20Sopenharmony_ci u32 resel_tag [ 20]; 1108c2ecf20Sopenharmony_ci#else 1118c2ecf20Sopenharmony_ci u32 resel_tag [ 16]; 1128c2ecf20Sopenharmony_ci#endif 1138c2ecf20Sopenharmony_ci u32 resel_dsa [ 2]; 1148c2ecf20Sopenharmony_ci u32 resel_dsa1 [ 4]; 1158c2ecf20Sopenharmony_ci u32 resel_no_tag [ 6]; 1168c2ecf20Sopenharmony_ci u32 data_in [SYM_CONF_MAX_SG * 2]; 1178c2ecf20Sopenharmony_ci u32 data_in2 [ 4]; 1188c2ecf20Sopenharmony_ci u32 data_out [SYM_CONF_MAX_SG * 2]; 1198c2ecf20Sopenharmony_ci u32 data_out2 [ 4]; 1208c2ecf20Sopenharmony_ci u32 pm0_data [ 12]; 1218c2ecf20Sopenharmony_ci u32 pm0_data_out [ 6]; 1228c2ecf20Sopenharmony_ci u32 pm0_data_end [ 6]; 1238c2ecf20Sopenharmony_ci u32 pm1_data [ 12]; 1248c2ecf20Sopenharmony_ci u32 pm1_data_out [ 6]; 1258c2ecf20Sopenharmony_ci u32 pm1_data_end [ 6]; 1268c2ecf20Sopenharmony_ci}; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/* 1298c2ecf20Sopenharmony_ci * Script fragments which stay in main memory for all chips 1308c2ecf20Sopenharmony_ci * except for chips that support 8K on-chip RAM. 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_cistruct SYM_FWB_SCR { 1338c2ecf20Sopenharmony_ci u32 start64 [ 2]; 1348c2ecf20Sopenharmony_ci u32 no_data [ 2]; 1358c2ecf20Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 1368c2ecf20Sopenharmony_ci u32 sel_for_abort [ 18]; 1378c2ecf20Sopenharmony_ci#else 1388c2ecf20Sopenharmony_ci u32 sel_for_abort [ 16]; 1398c2ecf20Sopenharmony_ci#endif 1408c2ecf20Sopenharmony_ci u32 sel_for_abort_1 [ 2]; 1418c2ecf20Sopenharmony_ci u32 msg_in_etc [ 12]; 1428c2ecf20Sopenharmony_ci u32 msg_received [ 4]; 1438c2ecf20Sopenharmony_ci u32 msg_weird_seen [ 4]; 1448c2ecf20Sopenharmony_ci u32 msg_extended [ 20]; 1458c2ecf20Sopenharmony_ci u32 msg_bad [ 6]; 1468c2ecf20Sopenharmony_ci u32 msg_weird [ 4]; 1478c2ecf20Sopenharmony_ci u32 msg_weird1 [ 8]; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci u32 wdtr_resp [ 6]; 1508c2ecf20Sopenharmony_ci u32 send_wdtr [ 4]; 1518c2ecf20Sopenharmony_ci u32 sdtr_resp [ 6]; 1528c2ecf20Sopenharmony_ci u32 send_sdtr [ 4]; 1538c2ecf20Sopenharmony_ci u32 ppr_resp [ 6]; 1548c2ecf20Sopenharmony_ci u32 send_ppr [ 4]; 1558c2ecf20Sopenharmony_ci u32 nego_bad_phase [ 4]; 1568c2ecf20Sopenharmony_ci u32 msg_out [ 4]; 1578c2ecf20Sopenharmony_ci u32 msg_out_done [ 4]; 1588c2ecf20Sopenharmony_ci u32 data_ovrun [ 2]; 1598c2ecf20Sopenharmony_ci u32 data_ovrun1 [ 22]; 1608c2ecf20Sopenharmony_ci u32 data_ovrun2 [ 8]; 1618c2ecf20Sopenharmony_ci u32 abort_resel [ 16]; 1628c2ecf20Sopenharmony_ci u32 resend_ident [ 4]; 1638c2ecf20Sopenharmony_ci u32 ident_break [ 4]; 1648c2ecf20Sopenharmony_ci u32 ident_break_atn [ 4]; 1658c2ecf20Sopenharmony_ci u32 sdata_in [ 6]; 1668c2ecf20Sopenharmony_ci u32 resel_bad_lun [ 4]; 1678c2ecf20Sopenharmony_ci u32 bad_i_t_l [ 4]; 1688c2ecf20Sopenharmony_ci u32 bad_i_t_l_q [ 4]; 1698c2ecf20Sopenharmony_ci u32 bad_status [ 6]; 1708c2ecf20Sopenharmony_ci u32 pm_handle [ 20]; 1718c2ecf20Sopenharmony_ci u32 pm_handle1 [ 4]; 1728c2ecf20Sopenharmony_ci u32 pm_save [ 4]; 1738c2ecf20Sopenharmony_ci u32 pm0_save [ 12]; 1748c2ecf20Sopenharmony_ci u32 pm_save_end [ 4]; 1758c2ecf20Sopenharmony_ci u32 pm1_save [ 14]; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci /* WSR handling */ 1788c2ecf20Sopenharmony_ci u32 pm_wsr_handle [ 38]; 1798c2ecf20Sopenharmony_ci u32 wsr_ma_helper [ 4]; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci /* Data area */ 1828c2ecf20Sopenharmony_ci u32 zero [ 1]; 1838c2ecf20Sopenharmony_ci u32 scratch [ 1]; 1848c2ecf20Sopenharmony_ci u32 pm0_data_addr [ 1]; 1858c2ecf20Sopenharmony_ci u32 pm1_data_addr [ 1]; 1868c2ecf20Sopenharmony_ci u32 done_pos [ 1]; 1878c2ecf20Sopenharmony_ci u32 startpos [ 1]; 1888c2ecf20Sopenharmony_ci u32 targtbl [ 1]; 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci/* 1928c2ecf20Sopenharmony_ci * Script fragments used at initialisations. 1938c2ecf20Sopenharmony_ci * Only runs out of main memory. 1948c2ecf20Sopenharmony_ci */ 1958c2ecf20Sopenharmony_cistruct SYM_FWZ_SCR { 1968c2ecf20Sopenharmony_ci u32 snooptest [ 6]; 1978c2ecf20Sopenharmony_ci u32 snoopend [ 2]; 1988c2ecf20Sopenharmony_ci}; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic struct SYM_FWA_SCR SYM_FWA_SCR = { 2018c2ecf20Sopenharmony_ci/*--------------------------< START >----------------------------*/ { 2028c2ecf20Sopenharmony_ci /* 2038c2ecf20Sopenharmony_ci * Switch the LED on. 2048c2ecf20Sopenharmony_ci * Will be patched with a NO_OP if LED 2058c2ecf20Sopenharmony_ci * not needed or not desired. 2068c2ecf20Sopenharmony_ci */ 2078c2ecf20Sopenharmony_ci SCR_REG_REG (gpreg, SCR_AND, 0xfe), 2088c2ecf20Sopenharmony_ci 0, 2098c2ecf20Sopenharmony_ci /* 2108c2ecf20Sopenharmony_ci * Clear SIGP. 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_ci SCR_FROM_REG (ctest2), 2138c2ecf20Sopenharmony_ci 0, 2148c2ecf20Sopenharmony_ci /* 2158c2ecf20Sopenharmony_ci * Stop here if the C code wants to perform 2168c2ecf20Sopenharmony_ci * some error recovery procedure manually. 2178c2ecf20Sopenharmony_ci * (Indicate this by setting SEM in ISTAT) 2188c2ecf20Sopenharmony_ci */ 2198c2ecf20Sopenharmony_ci SCR_FROM_REG (istat), 2208c2ecf20Sopenharmony_ci 0, 2218c2ecf20Sopenharmony_ci /* 2228c2ecf20Sopenharmony_ci * Report to the C code the next position in 2238c2ecf20Sopenharmony_ci * the start queue the SCRIPTS will schedule. 2248c2ecf20Sopenharmony_ci * The C code must not change SCRATCHA. 2258c2ecf20Sopenharmony_ci */ 2268c2ecf20Sopenharmony_ci SCR_LOAD_ABS (scratcha, 4), 2278c2ecf20Sopenharmony_ci PADDR_B (startpos), 2288c2ecf20Sopenharmony_ci SCR_INT ^ IFTRUE (MASK (SEM, SEM)), 2298c2ecf20Sopenharmony_ci SIR_SCRIPT_STOPPED, 2308c2ecf20Sopenharmony_ci /* 2318c2ecf20Sopenharmony_ci * Start the next job. 2328c2ecf20Sopenharmony_ci * 2338c2ecf20Sopenharmony_ci * @DSA = start point for this job. 2348c2ecf20Sopenharmony_ci * SCRATCHA = address of this job in the start queue. 2358c2ecf20Sopenharmony_ci * 2368c2ecf20Sopenharmony_ci * We will restore startpos with SCRATCHA if we fails the 2378c2ecf20Sopenharmony_ci * arbitration or if it is the idle job. 2388c2ecf20Sopenharmony_ci * 2398c2ecf20Sopenharmony_ci * The below GETJOB_BEGIN to GETJOB_END section of SCRIPTS 2408c2ecf20Sopenharmony_ci * is a critical path. If it is partially executed, it then 2418c2ecf20Sopenharmony_ci * may happen that the job address is not yet in the DSA 2428c2ecf20Sopenharmony_ci * and the next queue position points to the next JOB. 2438c2ecf20Sopenharmony_ci */ 2448c2ecf20Sopenharmony_ci SCR_LOAD_ABS (dsa, 4), 2458c2ecf20Sopenharmony_ci PADDR_B (startpos), 2468c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 2478c2ecf20Sopenharmony_ci 4, 2488c2ecf20Sopenharmony_ci}/*-------------------------< GETJOB_BEGIN >---------------------*/,{ 2498c2ecf20Sopenharmony_ci SCR_STORE_ABS (temp, 4), 2508c2ecf20Sopenharmony_ci PADDR_B (startpos), 2518c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 2528c2ecf20Sopenharmony_ci 0, 2538c2ecf20Sopenharmony_ci}/*-------------------------< GETJOB_END >-----------------------*/,{ 2548c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 2558c2ecf20Sopenharmony_ci 0, 2568c2ecf20Sopenharmony_ci SCR_RETURN, 2578c2ecf20Sopenharmony_ci 0, 2588c2ecf20Sopenharmony_ci}/*-------------------------< SELECT >---------------------------*/,{ 2598c2ecf20Sopenharmony_ci /* 2608c2ecf20Sopenharmony_ci * DSA contains the address of a scheduled 2618c2ecf20Sopenharmony_ci * data structure. 2628c2ecf20Sopenharmony_ci * 2638c2ecf20Sopenharmony_ci * SCRATCHA contains the address of the start queue 2648c2ecf20Sopenharmony_ci * entry which points to the next job. 2658c2ecf20Sopenharmony_ci * 2668c2ecf20Sopenharmony_ci * Set Initiator mode. 2678c2ecf20Sopenharmony_ci * 2688c2ecf20Sopenharmony_ci * (Target mode is left as an exercise for the reader) 2698c2ecf20Sopenharmony_ci */ 2708c2ecf20Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 2718c2ecf20Sopenharmony_ci SCR_CLR (SCR_TRG), 2728c2ecf20Sopenharmony_ci 0, 2738c2ecf20Sopenharmony_ci#endif 2748c2ecf20Sopenharmony_ci /* 2758c2ecf20Sopenharmony_ci * And try to select this target. 2768c2ecf20Sopenharmony_ci */ 2778c2ecf20Sopenharmony_ci SCR_SEL_TBL_ATN ^ offsetof (struct sym_dsb, select), 2788c2ecf20Sopenharmony_ci PADDR_A (ungetjob), 2798c2ecf20Sopenharmony_ci /* 2808c2ecf20Sopenharmony_ci * Now there are 4 possibilities: 2818c2ecf20Sopenharmony_ci * 2828c2ecf20Sopenharmony_ci * (1) The chip loses arbitration. 2838c2ecf20Sopenharmony_ci * This is ok, because it will try again, 2848c2ecf20Sopenharmony_ci * when the bus becomes idle. 2858c2ecf20Sopenharmony_ci * (But beware of the timeout function!) 2868c2ecf20Sopenharmony_ci * 2878c2ecf20Sopenharmony_ci * (2) The chip is reselected. 2888c2ecf20Sopenharmony_ci * Then the script processor takes the jump 2898c2ecf20Sopenharmony_ci * to the RESELECT label. 2908c2ecf20Sopenharmony_ci * 2918c2ecf20Sopenharmony_ci * (3) The chip wins arbitration. 2928c2ecf20Sopenharmony_ci * Then it will execute SCRIPTS instruction until 2938c2ecf20Sopenharmony_ci * the next instruction that checks SCSI phase. 2948c2ecf20Sopenharmony_ci * Then will stop and wait for selection to be 2958c2ecf20Sopenharmony_ci * complete or selection time-out to occur. 2968c2ecf20Sopenharmony_ci * 2978c2ecf20Sopenharmony_ci * After having won arbitration, the SCRIPTS 2988c2ecf20Sopenharmony_ci * processor is able to execute instructions while 2998c2ecf20Sopenharmony_ci * the SCSI core is performing SCSI selection. 3008c2ecf20Sopenharmony_ci */ 3018c2ecf20Sopenharmony_ci /* 3028c2ecf20Sopenharmony_ci * Initialize the status registers 3038c2ecf20Sopenharmony_ci */ 3048c2ecf20Sopenharmony_ci SCR_LOAD_REL (scr0, 4), 3058c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.status), 3068c2ecf20Sopenharmony_ci /* 3078c2ecf20Sopenharmony_ci * We may need help from CPU if the DMA segment 3088c2ecf20Sopenharmony_ci * registers aren't up-to-date for this IO. 3098c2ecf20Sopenharmony_ci * Patched with NOOP for chips that donnot 3108c2ecf20Sopenharmony_ci * support DAC addressing. 3118c2ecf20Sopenharmony_ci */ 3128c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 2 3138c2ecf20Sopenharmony_ci}/*-------------------------< IS_DMAP_DIRTY >--------------------*/,{ 3148c2ecf20Sopenharmony_ci SCR_FROM_REG (HX_REG), 3158c2ecf20Sopenharmony_ci 0, 3168c2ecf20Sopenharmony_ci SCR_INT ^ IFTRUE (MASK (HX_DMAP_DIRTY, HX_DMAP_DIRTY)), 3178c2ecf20Sopenharmony_ci SIR_DMAP_DIRTY, 3188c2ecf20Sopenharmony_ci#endif 3198c2ecf20Sopenharmony_ci}/*-------------------------< WF_SEL_DONE >----------------------*/,{ 3208c2ecf20Sopenharmony_ci SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), 3218c2ecf20Sopenharmony_ci SIR_SEL_ATN_NO_MSG_OUT, 3228c2ecf20Sopenharmony_ci}/*-------------------------< SEL_DONE >-------------------------*/,{ 3238c2ecf20Sopenharmony_ci /* 3248c2ecf20Sopenharmony_ci * C1010-33 errata work-around. 3258c2ecf20Sopenharmony_ci * Due to a race, the SCSI core may not have 3268c2ecf20Sopenharmony_ci * loaded SCNTL3 on SEL_TBL instruction. 3278c2ecf20Sopenharmony_ci * We reload it once phase is stable. 3288c2ecf20Sopenharmony_ci * Patched with a NOOP for other chips. 3298c2ecf20Sopenharmony_ci */ 3308c2ecf20Sopenharmony_ci SCR_LOAD_REL (scntl3, 1), 3318c2ecf20Sopenharmony_ci offsetof(struct sym_dsb, select.sel_scntl3), 3328c2ecf20Sopenharmony_ci}/*-------------------------< SEND_IDENT >-----------------------*/,{ 3338c2ecf20Sopenharmony_ci /* 3348c2ecf20Sopenharmony_ci * Selection complete. 3358c2ecf20Sopenharmony_ci * Send the IDENTIFY and possibly the TAG message 3368c2ecf20Sopenharmony_ci * and negotiation message if present. 3378c2ecf20Sopenharmony_ci */ 3388c2ecf20Sopenharmony_ci SCR_MOVE_TBL ^ SCR_MSG_OUT, 3398c2ecf20Sopenharmony_ci offsetof (struct sym_dsb, smsg), 3408c2ecf20Sopenharmony_ci}/*-------------------------< SELECT2 >--------------------------*/,{ 3418c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 3428c2ecf20Sopenharmony_ci /* 3438c2ecf20Sopenharmony_ci * Set IMMEDIATE ARBITRATION if we have been given 3448c2ecf20Sopenharmony_ci * a hint to do so. (Some job to do after this one). 3458c2ecf20Sopenharmony_ci */ 3468c2ecf20Sopenharmony_ci SCR_FROM_REG (HF_REG), 3478c2ecf20Sopenharmony_ci 0, 3488c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (MASK (HF_HINT_IARB, HF_HINT_IARB)), 3498c2ecf20Sopenharmony_ci 8, 3508c2ecf20Sopenharmony_ci SCR_REG_REG (scntl1, SCR_OR, IARB), 3518c2ecf20Sopenharmony_ci 0, 3528c2ecf20Sopenharmony_ci#endif 3538c2ecf20Sopenharmony_ci /* 3548c2ecf20Sopenharmony_ci * Anticipate the COMMAND phase. 3558c2ecf20Sopenharmony_ci * This is the PHASE we expect at this point. 3568c2ecf20Sopenharmony_ci */ 3578c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_COMMAND)), 3588c2ecf20Sopenharmony_ci PADDR_A (sel_no_cmd), 3598c2ecf20Sopenharmony_ci}/*-------------------------< COMMAND >--------------------------*/,{ 3608c2ecf20Sopenharmony_ci /* 3618c2ecf20Sopenharmony_ci * ... and send the command 3628c2ecf20Sopenharmony_ci */ 3638c2ecf20Sopenharmony_ci SCR_MOVE_TBL ^ SCR_COMMAND, 3648c2ecf20Sopenharmony_ci offsetof (struct sym_dsb, cmd), 3658c2ecf20Sopenharmony_ci}/*-------------------------< DISPATCH >-------------------------*/,{ 3668c2ecf20Sopenharmony_ci /* 3678c2ecf20Sopenharmony_ci * MSG_IN is the only phase that shall be 3688c2ecf20Sopenharmony_ci * entered at least once for each (re)selection. 3698c2ecf20Sopenharmony_ci * So we test it first. 3708c2ecf20Sopenharmony_ci */ 3718c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 3728c2ecf20Sopenharmony_ci PADDR_A (msg_in), 3738c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)), 3748c2ecf20Sopenharmony_ci PADDR_A (datao_phase), 3758c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)), 3768c2ecf20Sopenharmony_ci PADDR_A (datai_phase), 3778c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)), 3788c2ecf20Sopenharmony_ci PADDR_A (status), 3798c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)), 3808c2ecf20Sopenharmony_ci PADDR_A (command), 3818c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)), 3828c2ecf20Sopenharmony_ci PADDR_B (msg_out), 3838c2ecf20Sopenharmony_ci /* 3848c2ecf20Sopenharmony_ci * Discard as many illegal phases as 3858c2ecf20Sopenharmony_ci * required and tell the C code about. 3868c2ecf20Sopenharmony_ci */ 3878c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_OUT)), 3888c2ecf20Sopenharmony_ci 16, 3898c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_ILG_OUT, 3908c2ecf20Sopenharmony_ci HADDR_1 (scratch), 3918c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_OUT)), 3928c2ecf20Sopenharmony_ci -16, 3938c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_IN)), 3948c2ecf20Sopenharmony_ci 16, 3958c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_ILG_IN, 3968c2ecf20Sopenharmony_ci HADDR_1 (scratch), 3978c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_IN)), 3988c2ecf20Sopenharmony_ci -16, 3998c2ecf20Sopenharmony_ci SCR_INT, 4008c2ecf20Sopenharmony_ci SIR_BAD_PHASE, 4018c2ecf20Sopenharmony_ci SCR_JUMP, 4028c2ecf20Sopenharmony_ci PADDR_A (dispatch), 4038c2ecf20Sopenharmony_ci}/*-------------------------< SEL_NO_CMD >-----------------------*/,{ 4048c2ecf20Sopenharmony_ci /* 4058c2ecf20Sopenharmony_ci * The target does not switch to command 4068c2ecf20Sopenharmony_ci * phase after IDENTIFY has been sent. 4078c2ecf20Sopenharmony_ci * 4088c2ecf20Sopenharmony_ci * If it stays in MSG OUT phase send it 4098c2ecf20Sopenharmony_ci * the IDENTIFY again. 4108c2ecf20Sopenharmony_ci */ 4118c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), 4128c2ecf20Sopenharmony_ci PADDR_B (resend_ident), 4138c2ecf20Sopenharmony_ci /* 4148c2ecf20Sopenharmony_ci * If target does not switch to MSG IN phase 4158c2ecf20Sopenharmony_ci * and we sent a negotiation, assert the 4168c2ecf20Sopenharmony_ci * failure immediately. 4178c2ecf20Sopenharmony_ci */ 4188c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 4198c2ecf20Sopenharmony_ci PADDR_A (dispatch), 4208c2ecf20Sopenharmony_ci SCR_FROM_REG (HS_REG), 4218c2ecf20Sopenharmony_ci 0, 4228c2ecf20Sopenharmony_ci SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), 4238c2ecf20Sopenharmony_ci SIR_NEGO_FAILED, 4248c2ecf20Sopenharmony_ci /* 4258c2ecf20Sopenharmony_ci * Jump to dispatcher. 4268c2ecf20Sopenharmony_ci */ 4278c2ecf20Sopenharmony_ci SCR_JUMP, 4288c2ecf20Sopenharmony_ci PADDR_A (dispatch), 4298c2ecf20Sopenharmony_ci}/*-------------------------< INIT >-----------------------------*/,{ 4308c2ecf20Sopenharmony_ci /* 4318c2ecf20Sopenharmony_ci * Wait for the SCSI RESET signal to be 4328c2ecf20Sopenharmony_ci * inactive before restarting operations, 4338c2ecf20Sopenharmony_ci * since the chip may hang on SEL_ATN 4348c2ecf20Sopenharmony_ci * if SCSI RESET is active. 4358c2ecf20Sopenharmony_ci */ 4368c2ecf20Sopenharmony_ci SCR_FROM_REG (sstat0), 4378c2ecf20Sopenharmony_ci 0, 4388c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFTRUE (MASK (IRST, IRST)), 4398c2ecf20Sopenharmony_ci -16, 4408c2ecf20Sopenharmony_ci SCR_JUMP, 4418c2ecf20Sopenharmony_ci PADDR_A (start), 4428c2ecf20Sopenharmony_ci}/*-------------------------< CLRACK >---------------------------*/,{ 4438c2ecf20Sopenharmony_ci /* 4448c2ecf20Sopenharmony_ci * Terminate possible pending message phase. 4458c2ecf20Sopenharmony_ci */ 4468c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 4478c2ecf20Sopenharmony_ci 0, 4488c2ecf20Sopenharmony_ci SCR_JUMP, 4498c2ecf20Sopenharmony_ci PADDR_A (dispatch), 4508c2ecf20Sopenharmony_ci}/*-------------------------< DATAI_DONE >-----------------------*/,{ 4518c2ecf20Sopenharmony_ci /* 4528c2ecf20Sopenharmony_ci * Save current pointer to LASTP. 4538c2ecf20Sopenharmony_ci */ 4548c2ecf20Sopenharmony_ci SCR_STORE_REL (temp, 4), 4558c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.lastp), 4568c2ecf20Sopenharmony_ci /* 4578c2ecf20Sopenharmony_ci * If the SWIDE is not full, jump to dispatcher. 4588c2ecf20Sopenharmony_ci * We anticipate a STATUS phase. 4598c2ecf20Sopenharmony_ci */ 4608c2ecf20Sopenharmony_ci SCR_FROM_REG (scntl2), 4618c2ecf20Sopenharmony_ci 0, 4628c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (WSR, WSR)), 4638c2ecf20Sopenharmony_ci PADDR_A (datai_done_wsr), 4648c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)), 4658c2ecf20Sopenharmony_ci PADDR_A (status), 4668c2ecf20Sopenharmony_ci SCR_JUMP, 4678c2ecf20Sopenharmony_ci PADDR_A (dispatch), 4688c2ecf20Sopenharmony_ci}/*-------------------------< DATAI_DONE_WSR >-------------------*/,{ 4698c2ecf20Sopenharmony_ci /* 4708c2ecf20Sopenharmony_ci * The SWIDE is full. 4718c2ecf20Sopenharmony_ci * Clear this condition. 4728c2ecf20Sopenharmony_ci */ 4738c2ecf20Sopenharmony_ci SCR_REG_REG (scntl2, SCR_OR, WSR), 4748c2ecf20Sopenharmony_ci 0, 4758c2ecf20Sopenharmony_ci /* 4768c2ecf20Sopenharmony_ci * We are expecting an IGNORE RESIDUE message 4778c2ecf20Sopenharmony_ci * from the device, otherwise we are in data 4788c2ecf20Sopenharmony_ci * overrun condition. Check against MSG_IN phase. 4798c2ecf20Sopenharmony_ci */ 4808c2ecf20Sopenharmony_ci SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)), 4818c2ecf20Sopenharmony_ci SIR_SWIDE_OVERRUN, 4828c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 4838c2ecf20Sopenharmony_ci PADDR_A (dispatch), 4848c2ecf20Sopenharmony_ci /* 4858c2ecf20Sopenharmony_ci * We are in MSG_IN phase, 4868c2ecf20Sopenharmony_ci * Read the first byte of the message. 4878c2ecf20Sopenharmony_ci * If it is not an IGNORE RESIDUE message, 4888c2ecf20Sopenharmony_ci * signal overrun and jump to message 4898c2ecf20Sopenharmony_ci * processing. 4908c2ecf20Sopenharmony_ci */ 4918c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 4928c2ecf20Sopenharmony_ci HADDR_1 (msgin[0]), 4938c2ecf20Sopenharmony_ci SCR_INT ^ IFFALSE (DATA (M_IGN_RESIDUE)), 4948c2ecf20Sopenharmony_ci SIR_SWIDE_OVERRUN, 4958c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)), 4968c2ecf20Sopenharmony_ci PADDR_A (msg_in2), 4978c2ecf20Sopenharmony_ci /* 4988c2ecf20Sopenharmony_ci * We got the message we expected. 4998c2ecf20Sopenharmony_ci * Read the 2nd byte, and jump to dispatcher. 5008c2ecf20Sopenharmony_ci */ 5018c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 5028c2ecf20Sopenharmony_ci 0, 5038c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 5048c2ecf20Sopenharmony_ci HADDR_1 (msgin[1]), 5058c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 5068c2ecf20Sopenharmony_ci 0, 5078c2ecf20Sopenharmony_ci SCR_JUMP, 5088c2ecf20Sopenharmony_ci PADDR_A (dispatch), 5098c2ecf20Sopenharmony_ci}/*-------------------------< DATAO_DONE >-----------------------*/,{ 5108c2ecf20Sopenharmony_ci /* 5118c2ecf20Sopenharmony_ci * Save current pointer to LASTP. 5128c2ecf20Sopenharmony_ci */ 5138c2ecf20Sopenharmony_ci SCR_STORE_REL (temp, 4), 5148c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.lastp), 5158c2ecf20Sopenharmony_ci /* 5168c2ecf20Sopenharmony_ci * If the SODL is not full jump to dispatcher. 5178c2ecf20Sopenharmony_ci * We anticipate a STATUS phase. 5188c2ecf20Sopenharmony_ci */ 5198c2ecf20Sopenharmony_ci SCR_FROM_REG (scntl2), 5208c2ecf20Sopenharmony_ci 0, 5218c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (WSS, WSS)), 5228c2ecf20Sopenharmony_ci PADDR_A (datao_done_wss), 5238c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)), 5248c2ecf20Sopenharmony_ci PADDR_A (status), 5258c2ecf20Sopenharmony_ci SCR_JUMP, 5268c2ecf20Sopenharmony_ci PADDR_A (dispatch), 5278c2ecf20Sopenharmony_ci}/*-------------------------< DATAO_DONE_WSS >-------------------*/,{ 5288c2ecf20Sopenharmony_ci /* 5298c2ecf20Sopenharmony_ci * The SODL is full, clear this condition. 5308c2ecf20Sopenharmony_ci */ 5318c2ecf20Sopenharmony_ci SCR_REG_REG (scntl2, SCR_OR, WSS), 5328c2ecf20Sopenharmony_ci 0, 5338c2ecf20Sopenharmony_ci /* 5348c2ecf20Sopenharmony_ci * And signal a DATA UNDERRUN condition 5358c2ecf20Sopenharmony_ci * to the C code. 5368c2ecf20Sopenharmony_ci */ 5378c2ecf20Sopenharmony_ci SCR_INT, 5388c2ecf20Sopenharmony_ci SIR_SODL_UNDERRUN, 5398c2ecf20Sopenharmony_ci SCR_JUMP, 5408c2ecf20Sopenharmony_ci PADDR_A (dispatch), 5418c2ecf20Sopenharmony_ci}/*-------------------------< DATAI_PHASE >----------------------*/,{ 5428c2ecf20Sopenharmony_ci /* 5438c2ecf20Sopenharmony_ci * Jump to current pointer. 5448c2ecf20Sopenharmony_ci */ 5458c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 5468c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.lastp), 5478c2ecf20Sopenharmony_ci SCR_RETURN, 5488c2ecf20Sopenharmony_ci 0, 5498c2ecf20Sopenharmony_ci}/*-------------------------< DATAO_PHASE >----------------------*/,{ 5508c2ecf20Sopenharmony_ci /* 5518c2ecf20Sopenharmony_ci * C1010-66 errata work-around. 5528c2ecf20Sopenharmony_ci * Extra clocks of data hold must be inserted 5538c2ecf20Sopenharmony_ci * in DATA OUT phase on 33 MHz PCI BUS. 5548c2ecf20Sopenharmony_ci * Patched with a NOOP for other chips. 5558c2ecf20Sopenharmony_ci */ 5568c2ecf20Sopenharmony_ci SCR_REG_REG (scntl4, SCR_OR, (XCLKH_DT|XCLKH_ST)), 5578c2ecf20Sopenharmony_ci 0, 5588c2ecf20Sopenharmony_ci /* 5598c2ecf20Sopenharmony_ci * Jump to current pointer. 5608c2ecf20Sopenharmony_ci */ 5618c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 5628c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.lastp), 5638c2ecf20Sopenharmony_ci SCR_RETURN, 5648c2ecf20Sopenharmony_ci 0, 5658c2ecf20Sopenharmony_ci}/*-------------------------< MSG_IN >---------------------------*/,{ 5668c2ecf20Sopenharmony_ci /* 5678c2ecf20Sopenharmony_ci * Get the first byte of the message. 5688c2ecf20Sopenharmony_ci * 5698c2ecf20Sopenharmony_ci * The script processor doesn't negate the 5708c2ecf20Sopenharmony_ci * ACK signal after this transfer. 5718c2ecf20Sopenharmony_ci */ 5728c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 5738c2ecf20Sopenharmony_ci HADDR_1 (msgin[0]), 5748c2ecf20Sopenharmony_ci}/*-------------------------< MSG_IN2 >--------------------------*/,{ 5758c2ecf20Sopenharmony_ci /* 5768c2ecf20Sopenharmony_ci * Check first against 1 byte messages 5778c2ecf20Sopenharmony_ci * that we handle from SCRIPTS. 5788c2ecf20Sopenharmony_ci */ 5798c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)), 5808c2ecf20Sopenharmony_ci PADDR_A (complete), 5818c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)), 5828c2ecf20Sopenharmony_ci PADDR_A (disconnect), 5838c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)), 5848c2ecf20Sopenharmony_ci PADDR_A (save_dp), 5858c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)), 5868c2ecf20Sopenharmony_ci PADDR_A (restore_dp), 5878c2ecf20Sopenharmony_ci /* 5888c2ecf20Sopenharmony_ci * We handle all other messages from the 5898c2ecf20Sopenharmony_ci * C code, so no need to waste on-chip RAM 5908c2ecf20Sopenharmony_ci * for those ones. 5918c2ecf20Sopenharmony_ci */ 5928c2ecf20Sopenharmony_ci SCR_JUMP, 5938c2ecf20Sopenharmony_ci PADDR_B (msg_in_etc), 5948c2ecf20Sopenharmony_ci}/*-------------------------< STATUS >---------------------------*/,{ 5958c2ecf20Sopenharmony_ci /* 5968c2ecf20Sopenharmony_ci * get the status 5978c2ecf20Sopenharmony_ci */ 5988c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_STATUS, 5998c2ecf20Sopenharmony_ci HADDR_1 (scratch), 6008c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 6018c2ecf20Sopenharmony_ci /* 6028c2ecf20Sopenharmony_ci * If STATUS is not GOOD, clear IMMEDIATE ARBITRATION, 6038c2ecf20Sopenharmony_ci * since we may have to tamper the start queue from 6048c2ecf20Sopenharmony_ci * the C code. 6058c2ecf20Sopenharmony_ci */ 6068c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFTRUE (DATA (S_GOOD)), 6078c2ecf20Sopenharmony_ci 8, 6088c2ecf20Sopenharmony_ci SCR_REG_REG (scntl1, SCR_AND, ~IARB), 6098c2ecf20Sopenharmony_ci 0, 6108c2ecf20Sopenharmony_ci#endif 6118c2ecf20Sopenharmony_ci /* 6128c2ecf20Sopenharmony_ci * save status to scsi_status. 6138c2ecf20Sopenharmony_ci * mark as complete. 6148c2ecf20Sopenharmony_ci */ 6158c2ecf20Sopenharmony_ci SCR_TO_REG (SS_REG), 6168c2ecf20Sopenharmony_ci 0, 6178c2ecf20Sopenharmony_ci SCR_LOAD_REG (HS_REG, HS_COMPLETE), 6188c2ecf20Sopenharmony_ci 0, 6198c2ecf20Sopenharmony_ci /* 6208c2ecf20Sopenharmony_ci * Anticipate the MESSAGE PHASE for 6218c2ecf20Sopenharmony_ci * the TASK COMPLETE message. 6228c2ecf20Sopenharmony_ci */ 6238c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 6248c2ecf20Sopenharmony_ci PADDR_A (msg_in), 6258c2ecf20Sopenharmony_ci SCR_JUMP, 6268c2ecf20Sopenharmony_ci PADDR_A (dispatch), 6278c2ecf20Sopenharmony_ci}/*-------------------------< COMPLETE >-------------------------*/,{ 6288c2ecf20Sopenharmony_ci /* 6298c2ecf20Sopenharmony_ci * Complete message. 6308c2ecf20Sopenharmony_ci * 6318c2ecf20Sopenharmony_ci * When we terminate the cycle by clearing ACK, 6328c2ecf20Sopenharmony_ci * the target may disconnect immediately. 6338c2ecf20Sopenharmony_ci * 6348c2ecf20Sopenharmony_ci * We don't want to be told of an "unexpected disconnect", 6358c2ecf20Sopenharmony_ci * so we disable this feature. 6368c2ecf20Sopenharmony_ci */ 6378c2ecf20Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 6388c2ecf20Sopenharmony_ci 0, 6398c2ecf20Sopenharmony_ci /* 6408c2ecf20Sopenharmony_ci * Terminate cycle ... 6418c2ecf20Sopenharmony_ci */ 6428c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 6438c2ecf20Sopenharmony_ci 0, 6448c2ecf20Sopenharmony_ci /* 6458c2ecf20Sopenharmony_ci * ... and wait for the disconnect. 6468c2ecf20Sopenharmony_ci */ 6478c2ecf20Sopenharmony_ci SCR_WAIT_DISC, 6488c2ecf20Sopenharmony_ci 0, 6498c2ecf20Sopenharmony_ci}/*-------------------------< COMPLETE2 >------------------------*/,{ 6508c2ecf20Sopenharmony_ci /* 6518c2ecf20Sopenharmony_ci * Save host status. 6528c2ecf20Sopenharmony_ci */ 6538c2ecf20Sopenharmony_ci SCR_STORE_REL (scr0, 4), 6548c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.status), 6558c2ecf20Sopenharmony_ci /* 6568c2ecf20Sopenharmony_ci * Some bridges may reorder DMA writes to memory. 6578c2ecf20Sopenharmony_ci * We donnot want the CPU to deal with completions 6588c2ecf20Sopenharmony_ci * without all the posted write having been flushed 6598c2ecf20Sopenharmony_ci * to memory. This DUMMY READ should flush posted 6608c2ecf20Sopenharmony_ci * buffers prior to the CPU having to deal with 6618c2ecf20Sopenharmony_ci * completions. 6628c2ecf20Sopenharmony_ci */ 6638c2ecf20Sopenharmony_ci SCR_LOAD_REL (scr0, 4), /* DUMMY READ */ 6648c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.status), 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci /* 6678c2ecf20Sopenharmony_ci * If command resulted in not GOOD status, 6688c2ecf20Sopenharmony_ci * call the C code if needed. 6698c2ecf20Sopenharmony_ci */ 6708c2ecf20Sopenharmony_ci SCR_FROM_REG (SS_REG), 6718c2ecf20Sopenharmony_ci 0, 6728c2ecf20Sopenharmony_ci SCR_CALL ^ IFFALSE (DATA (S_GOOD)), 6738c2ecf20Sopenharmony_ci PADDR_B (bad_status), 6748c2ecf20Sopenharmony_ci /* 6758c2ecf20Sopenharmony_ci * If we performed an auto-sense, call 6768c2ecf20Sopenharmony_ci * the C code to synchronyze task aborts 6778c2ecf20Sopenharmony_ci * with UNIT ATTENTION conditions. 6788c2ecf20Sopenharmony_ci */ 6798c2ecf20Sopenharmony_ci SCR_FROM_REG (HF_REG), 6808c2ecf20Sopenharmony_ci 0, 6818c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (0 ,(HF_SENSE|HF_EXT_ERR))), 6828c2ecf20Sopenharmony_ci PADDR_A (complete_error), 6838c2ecf20Sopenharmony_ci}/*-------------------------< DONE >-----------------------------*/,{ 6848c2ecf20Sopenharmony_ci /* 6858c2ecf20Sopenharmony_ci * Copy the DSA to the DONE QUEUE and 6868c2ecf20Sopenharmony_ci * signal completion to the host. 6878c2ecf20Sopenharmony_ci * If we are interrupted between DONE 6888c2ecf20Sopenharmony_ci * and DONE_END, we must reset, otherwise 6898c2ecf20Sopenharmony_ci * the completed CCB may be lost. 6908c2ecf20Sopenharmony_ci */ 6918c2ecf20Sopenharmony_ci SCR_STORE_ABS (dsa, 4), 6928c2ecf20Sopenharmony_ci PADDR_B (scratch), 6938c2ecf20Sopenharmony_ci SCR_LOAD_ABS (dsa, 4), 6948c2ecf20Sopenharmony_ci PADDR_B (done_pos), 6958c2ecf20Sopenharmony_ci SCR_LOAD_ABS (scratcha, 4), 6968c2ecf20Sopenharmony_ci PADDR_B (scratch), 6978c2ecf20Sopenharmony_ci SCR_STORE_REL (scratcha, 4), 6988c2ecf20Sopenharmony_ci 0, 6998c2ecf20Sopenharmony_ci /* 7008c2ecf20Sopenharmony_ci * The instruction below reads the DONE QUEUE next 7018c2ecf20Sopenharmony_ci * free position from memory. 7028c2ecf20Sopenharmony_ci * In addition it ensures that all PCI posted writes 7038c2ecf20Sopenharmony_ci * are flushed and so the DSA value of the done 7048c2ecf20Sopenharmony_ci * CCB is visible by the CPU before INTFLY is raised. 7058c2ecf20Sopenharmony_ci */ 7068c2ecf20Sopenharmony_ci SCR_LOAD_REL (scratcha, 4), 7078c2ecf20Sopenharmony_ci 4, 7088c2ecf20Sopenharmony_ci SCR_INT_FLY, 7098c2ecf20Sopenharmony_ci 0, 7108c2ecf20Sopenharmony_ci SCR_STORE_ABS (scratcha, 4), 7118c2ecf20Sopenharmony_ci PADDR_B (done_pos), 7128c2ecf20Sopenharmony_ci}/*-------------------------< DONE_END >-------------------------*/,{ 7138c2ecf20Sopenharmony_ci SCR_JUMP, 7148c2ecf20Sopenharmony_ci PADDR_A (start), 7158c2ecf20Sopenharmony_ci}/*-------------------------< COMPLETE_ERROR >-------------------*/,{ 7168c2ecf20Sopenharmony_ci SCR_LOAD_ABS (scratcha, 4), 7178c2ecf20Sopenharmony_ci PADDR_B (startpos), 7188c2ecf20Sopenharmony_ci SCR_INT, 7198c2ecf20Sopenharmony_ci SIR_COMPLETE_ERROR, 7208c2ecf20Sopenharmony_ci}/*-------------------------< SAVE_DP >--------------------------*/,{ 7218c2ecf20Sopenharmony_ci /* 7228c2ecf20Sopenharmony_ci * Clear ACK immediately. 7238c2ecf20Sopenharmony_ci * No need to delay it. 7248c2ecf20Sopenharmony_ci */ 7258c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 7268c2ecf20Sopenharmony_ci 0, 7278c2ecf20Sopenharmony_ci /* 7288c2ecf20Sopenharmony_ci * Keep track we received a SAVE DP, so 7298c2ecf20Sopenharmony_ci * we will switch to the other PM context 7308c2ecf20Sopenharmony_ci * on the next PM since the DP may point 7318c2ecf20Sopenharmony_ci * to the current PM context. 7328c2ecf20Sopenharmony_ci */ 7338c2ecf20Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED), 7348c2ecf20Sopenharmony_ci 0, 7358c2ecf20Sopenharmony_ci /* 7368c2ecf20Sopenharmony_ci * SAVE_DP message: 7378c2ecf20Sopenharmony_ci * Copy LASTP to SAVEP. 7388c2ecf20Sopenharmony_ci */ 7398c2ecf20Sopenharmony_ci SCR_LOAD_REL (scratcha, 4), 7408c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.lastp), 7418c2ecf20Sopenharmony_ci SCR_STORE_REL (scratcha, 4), 7428c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.savep), 7438c2ecf20Sopenharmony_ci /* 7448c2ecf20Sopenharmony_ci * Anticipate the MESSAGE PHASE for 7458c2ecf20Sopenharmony_ci * the DISCONNECT message. 7468c2ecf20Sopenharmony_ci */ 7478c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 7488c2ecf20Sopenharmony_ci PADDR_A (msg_in), 7498c2ecf20Sopenharmony_ci SCR_JUMP, 7508c2ecf20Sopenharmony_ci PADDR_A (dispatch), 7518c2ecf20Sopenharmony_ci}/*-------------------------< RESTORE_DP >-----------------------*/,{ 7528c2ecf20Sopenharmony_ci /* 7538c2ecf20Sopenharmony_ci * Clear ACK immediately. 7548c2ecf20Sopenharmony_ci * No need to delay it. 7558c2ecf20Sopenharmony_ci */ 7568c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 7578c2ecf20Sopenharmony_ci 0, 7588c2ecf20Sopenharmony_ci /* 7598c2ecf20Sopenharmony_ci * Copy SAVEP to LASTP. 7608c2ecf20Sopenharmony_ci */ 7618c2ecf20Sopenharmony_ci SCR_LOAD_REL (scratcha, 4), 7628c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.savep), 7638c2ecf20Sopenharmony_ci SCR_STORE_REL (scratcha, 4), 7648c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.lastp), 7658c2ecf20Sopenharmony_ci SCR_JUMP, 7668c2ecf20Sopenharmony_ci PADDR_A (dispatch), 7678c2ecf20Sopenharmony_ci}/*-------------------------< DISCONNECT >-----------------------*/,{ 7688c2ecf20Sopenharmony_ci /* 7698c2ecf20Sopenharmony_ci * DISCONNECTing ... 7708c2ecf20Sopenharmony_ci * 7718c2ecf20Sopenharmony_ci * disable the "unexpected disconnect" feature, 7728c2ecf20Sopenharmony_ci * and remove the ACK signal. 7738c2ecf20Sopenharmony_ci */ 7748c2ecf20Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 7758c2ecf20Sopenharmony_ci 0, 7768c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 7778c2ecf20Sopenharmony_ci 0, 7788c2ecf20Sopenharmony_ci /* 7798c2ecf20Sopenharmony_ci * Wait for the disconnect. 7808c2ecf20Sopenharmony_ci */ 7818c2ecf20Sopenharmony_ci SCR_WAIT_DISC, 7828c2ecf20Sopenharmony_ci 0, 7838c2ecf20Sopenharmony_ci /* 7848c2ecf20Sopenharmony_ci * Status is: DISCONNECTED. 7858c2ecf20Sopenharmony_ci */ 7868c2ecf20Sopenharmony_ci SCR_LOAD_REG (HS_REG, HS_DISCONNECT), 7878c2ecf20Sopenharmony_ci 0, 7888c2ecf20Sopenharmony_ci /* 7898c2ecf20Sopenharmony_ci * Save host status. 7908c2ecf20Sopenharmony_ci */ 7918c2ecf20Sopenharmony_ci SCR_STORE_REL (scr0, 4), 7928c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.status), 7938c2ecf20Sopenharmony_ci SCR_JUMP, 7948c2ecf20Sopenharmony_ci PADDR_A (start), 7958c2ecf20Sopenharmony_ci}/*-------------------------< IDLE >-----------------------------*/,{ 7968c2ecf20Sopenharmony_ci /* 7978c2ecf20Sopenharmony_ci * Nothing to do? 7988c2ecf20Sopenharmony_ci * Switch the LED off and wait for reselect. 7998c2ecf20Sopenharmony_ci * Will be patched with a NO_OP if LED 8008c2ecf20Sopenharmony_ci * not needed or not desired. 8018c2ecf20Sopenharmony_ci */ 8028c2ecf20Sopenharmony_ci SCR_REG_REG (gpreg, SCR_OR, 0x01), 8038c2ecf20Sopenharmony_ci 0, 8048c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 8058c2ecf20Sopenharmony_ci SCR_JUMPR, 8068c2ecf20Sopenharmony_ci 8, 8078c2ecf20Sopenharmony_ci#endif 8088c2ecf20Sopenharmony_ci}/*-------------------------< UNGETJOB >-------------------------*/,{ 8098c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 8108c2ecf20Sopenharmony_ci /* 8118c2ecf20Sopenharmony_ci * Set IMMEDIATE ARBITRATION, for the next time. 8128c2ecf20Sopenharmony_ci * This will give us better chance to win arbitration 8138c2ecf20Sopenharmony_ci * for the job we just wanted to do. 8148c2ecf20Sopenharmony_ci */ 8158c2ecf20Sopenharmony_ci SCR_REG_REG (scntl1, SCR_OR, IARB), 8168c2ecf20Sopenharmony_ci 0, 8178c2ecf20Sopenharmony_ci#endif 8188c2ecf20Sopenharmony_ci /* 8198c2ecf20Sopenharmony_ci * We are not able to restart the SCRIPTS if we are 8208c2ecf20Sopenharmony_ci * interrupted and these instruction haven't been 8218c2ecf20Sopenharmony_ci * all executed. BTW, this is very unlikely to 8228c2ecf20Sopenharmony_ci * happen, but we check that from the C code. 8238c2ecf20Sopenharmony_ci */ 8248c2ecf20Sopenharmony_ci SCR_LOAD_REG (dsa, 0xff), 8258c2ecf20Sopenharmony_ci 0, 8268c2ecf20Sopenharmony_ci SCR_STORE_ABS (scratcha, 4), 8278c2ecf20Sopenharmony_ci PADDR_B (startpos), 8288c2ecf20Sopenharmony_ci}/*-------------------------< RESELECT >-------------------------*/,{ 8298c2ecf20Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 8308c2ecf20Sopenharmony_ci /* 8318c2ecf20Sopenharmony_ci * Make sure we are in initiator mode. 8328c2ecf20Sopenharmony_ci */ 8338c2ecf20Sopenharmony_ci SCR_CLR (SCR_TRG), 8348c2ecf20Sopenharmony_ci 0, 8358c2ecf20Sopenharmony_ci#endif 8368c2ecf20Sopenharmony_ci /* 8378c2ecf20Sopenharmony_ci * Sleep waiting for a reselection. 8388c2ecf20Sopenharmony_ci */ 8398c2ecf20Sopenharmony_ci SCR_WAIT_RESEL, 8408c2ecf20Sopenharmony_ci PADDR_A(start), 8418c2ecf20Sopenharmony_ci}/*-------------------------< RESELECTED >-----------------------*/,{ 8428c2ecf20Sopenharmony_ci /* 8438c2ecf20Sopenharmony_ci * Switch the LED on. 8448c2ecf20Sopenharmony_ci * Will be patched with a NO_OP if LED 8458c2ecf20Sopenharmony_ci * not needed or not desired. 8468c2ecf20Sopenharmony_ci */ 8478c2ecf20Sopenharmony_ci SCR_REG_REG (gpreg, SCR_AND, 0xfe), 8488c2ecf20Sopenharmony_ci 0, 8498c2ecf20Sopenharmony_ci /* 8508c2ecf20Sopenharmony_ci * load the target id into the sdid 8518c2ecf20Sopenharmony_ci */ 8528c2ecf20Sopenharmony_ci SCR_REG_SFBR (ssid, SCR_AND, 0x8F), 8538c2ecf20Sopenharmony_ci 0, 8548c2ecf20Sopenharmony_ci SCR_TO_REG (sdid), 8558c2ecf20Sopenharmony_ci 0, 8568c2ecf20Sopenharmony_ci /* 8578c2ecf20Sopenharmony_ci * Load the target control block address 8588c2ecf20Sopenharmony_ci */ 8598c2ecf20Sopenharmony_ci SCR_LOAD_ABS (dsa, 4), 8608c2ecf20Sopenharmony_ci PADDR_B (targtbl), 8618c2ecf20Sopenharmony_ci SCR_SFBR_REG (dsa, SCR_SHL, 0), 8628c2ecf20Sopenharmony_ci 0, 8638c2ecf20Sopenharmony_ci SCR_REG_REG (dsa, SCR_SHL, 0), 8648c2ecf20Sopenharmony_ci 0, 8658c2ecf20Sopenharmony_ci SCR_REG_REG (dsa, SCR_AND, 0x3c), 8668c2ecf20Sopenharmony_ci 0, 8678c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 8688c2ecf20Sopenharmony_ci 0, 8698c2ecf20Sopenharmony_ci /* 8708c2ecf20Sopenharmony_ci * We expect MESSAGE IN phase. 8718c2ecf20Sopenharmony_ci * If not, get help from the C code. 8728c2ecf20Sopenharmony_ci */ 8738c2ecf20Sopenharmony_ci SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)), 8748c2ecf20Sopenharmony_ci SIR_RESEL_NO_MSG_IN, 8758c2ecf20Sopenharmony_ci /* 8768c2ecf20Sopenharmony_ci * Load the legacy synchronous transfer registers. 8778c2ecf20Sopenharmony_ci */ 8788c2ecf20Sopenharmony_ci SCR_LOAD_REL (scntl3, 1), 8798c2ecf20Sopenharmony_ci offsetof(struct sym_tcb, head.wval), 8808c2ecf20Sopenharmony_ci SCR_LOAD_REL (sxfer, 1), 8818c2ecf20Sopenharmony_ci offsetof(struct sym_tcb, head.sval), 8828c2ecf20Sopenharmony_ci}/*-------------------------< RESEL_SCNTL4 >---------------------*/,{ 8838c2ecf20Sopenharmony_ci /* 8848c2ecf20Sopenharmony_ci * The C1010 uses a new synchronous timing scheme. 8858c2ecf20Sopenharmony_ci * Will be patched with a NO_OP if not a C1010. 8868c2ecf20Sopenharmony_ci */ 8878c2ecf20Sopenharmony_ci SCR_LOAD_REL (scntl4, 1), 8888c2ecf20Sopenharmony_ci offsetof(struct sym_tcb, head.uval), 8898c2ecf20Sopenharmony_ci /* 8908c2ecf20Sopenharmony_ci * Get the IDENTIFY message. 8918c2ecf20Sopenharmony_ci */ 8928c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 8938c2ecf20Sopenharmony_ci HADDR_1 (msgin), 8948c2ecf20Sopenharmony_ci /* 8958c2ecf20Sopenharmony_ci * If IDENTIFY LUN #0, use a faster path 8968c2ecf20Sopenharmony_ci * to find the LCB structure. 8978c2ecf20Sopenharmony_ci */ 8988c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0x80, 0xbf)), 8998c2ecf20Sopenharmony_ci PADDR_A (resel_lun0), 9008c2ecf20Sopenharmony_ci /* 9018c2ecf20Sopenharmony_ci * If message isn't an IDENTIFY, 9028c2ecf20Sopenharmony_ci * tell the C code about. 9038c2ecf20Sopenharmony_ci */ 9048c2ecf20Sopenharmony_ci SCR_INT ^ IFFALSE (MASK (0x80, 0x80)), 9058c2ecf20Sopenharmony_ci SIR_RESEL_NO_IDENTIFY, 9068c2ecf20Sopenharmony_ci /* 9078c2ecf20Sopenharmony_ci * It is an IDENTIFY message, 9088c2ecf20Sopenharmony_ci * Load the LUN control block address. 9098c2ecf20Sopenharmony_ci */ 9108c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 9118c2ecf20Sopenharmony_ci offsetof(struct sym_tcb, head.luntbl_sa), 9128c2ecf20Sopenharmony_ci SCR_SFBR_REG (dsa, SCR_SHL, 0), 9138c2ecf20Sopenharmony_ci 0, 9148c2ecf20Sopenharmony_ci SCR_REG_REG (dsa, SCR_SHL, 0), 9158c2ecf20Sopenharmony_ci 0, 9168c2ecf20Sopenharmony_ci SCR_REG_REG (dsa, SCR_AND, 0xfc), 9178c2ecf20Sopenharmony_ci 0, 9188c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 9198c2ecf20Sopenharmony_ci 0, 9208c2ecf20Sopenharmony_ci SCR_JUMPR, 9218c2ecf20Sopenharmony_ci 8, 9228c2ecf20Sopenharmony_ci}/*-------------------------< RESEL_LUN0 >-----------------------*/,{ 9238c2ecf20Sopenharmony_ci /* 9248c2ecf20Sopenharmony_ci * LUN 0 special case (but usual one :)) 9258c2ecf20Sopenharmony_ci */ 9268c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 9278c2ecf20Sopenharmony_ci offsetof(struct sym_tcb, head.lun0_sa), 9288c2ecf20Sopenharmony_ci /* 9298c2ecf20Sopenharmony_ci * Jump indirectly to the reselect action for this LUN. 9308c2ecf20Sopenharmony_ci */ 9318c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 9328c2ecf20Sopenharmony_ci offsetof(struct sym_lcb, head.resel_sa), 9338c2ecf20Sopenharmony_ci SCR_RETURN, 9348c2ecf20Sopenharmony_ci 0, 9358c2ecf20Sopenharmony_ci /* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */ 9368c2ecf20Sopenharmony_ci}/*-------------------------< RESEL_TAG >------------------------*/,{ 9378c2ecf20Sopenharmony_ci /* 9388c2ecf20Sopenharmony_ci * ACK the IDENTIFY previously received. 9398c2ecf20Sopenharmony_ci */ 9408c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 9418c2ecf20Sopenharmony_ci 0, 9428c2ecf20Sopenharmony_ci /* 9438c2ecf20Sopenharmony_ci * It shall be a tagged command. 9448c2ecf20Sopenharmony_ci * Read SIMPLE+TAG. 9458c2ecf20Sopenharmony_ci * The C code will deal with errors. 9468c2ecf20Sopenharmony_ci * Aggressive optimization, isn't it? :) 9478c2ecf20Sopenharmony_ci */ 9488c2ecf20Sopenharmony_ci SCR_MOVE_ABS (2) ^ SCR_MSG_IN, 9498c2ecf20Sopenharmony_ci HADDR_1 (msgin), 9508c2ecf20Sopenharmony_ci /* 9518c2ecf20Sopenharmony_ci * Load the pointer to the tagged task 9528c2ecf20Sopenharmony_ci * table for this LUN. 9538c2ecf20Sopenharmony_ci */ 9548c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 9558c2ecf20Sopenharmony_ci offsetof(struct sym_lcb, head.itlq_tbl_sa), 9568c2ecf20Sopenharmony_ci /* 9578c2ecf20Sopenharmony_ci * The SIDL still contains the TAG value. 9588c2ecf20Sopenharmony_ci * Aggressive optimization, isn't it? :):) 9598c2ecf20Sopenharmony_ci */ 9608c2ecf20Sopenharmony_ci SCR_REG_SFBR (sidl, SCR_SHL, 0), 9618c2ecf20Sopenharmony_ci 0, 9628c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_TASK*4 > 512 9638c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (CARRYSET), 9648c2ecf20Sopenharmony_ci 8, 9658c2ecf20Sopenharmony_ci SCR_REG_REG (dsa1, SCR_OR, 2), 9668c2ecf20Sopenharmony_ci 0, 9678c2ecf20Sopenharmony_ci SCR_REG_REG (sfbr, SCR_SHL, 0), 9688c2ecf20Sopenharmony_ci 0, 9698c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (CARRYSET), 9708c2ecf20Sopenharmony_ci 8, 9718c2ecf20Sopenharmony_ci SCR_REG_REG (dsa1, SCR_OR, 1), 9728c2ecf20Sopenharmony_ci 0, 9738c2ecf20Sopenharmony_ci#elif SYM_CONF_MAX_TASK*4 > 256 9748c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (CARRYSET), 9758c2ecf20Sopenharmony_ci 8, 9768c2ecf20Sopenharmony_ci SCR_REG_REG (dsa1, SCR_OR, 1), 9778c2ecf20Sopenharmony_ci 0, 9788c2ecf20Sopenharmony_ci#endif 9798c2ecf20Sopenharmony_ci /* 9808c2ecf20Sopenharmony_ci * Retrieve the DSA of this task. 9818c2ecf20Sopenharmony_ci * JUMP indirectly to the restart point of the CCB. 9828c2ecf20Sopenharmony_ci */ 9838c2ecf20Sopenharmony_ci SCR_SFBR_REG (dsa, SCR_AND, 0xfc), 9848c2ecf20Sopenharmony_ci 0, 9858c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 9868c2ecf20Sopenharmony_ci 0, 9878c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 9888c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.head.go.restart), 9898c2ecf20Sopenharmony_ci SCR_RETURN, 9908c2ecf20Sopenharmony_ci 0, 9918c2ecf20Sopenharmony_ci /* In normal situations we branch to RESEL_DSA */ 9928c2ecf20Sopenharmony_ci}/*-------------------------< RESEL_DSA >------------------------*/,{ 9938c2ecf20Sopenharmony_ci /* 9948c2ecf20Sopenharmony_ci * ACK the IDENTIFY or TAG previously received. 9958c2ecf20Sopenharmony_ci */ 9968c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 9978c2ecf20Sopenharmony_ci 0, 9988c2ecf20Sopenharmony_ci}/*-------------------------< RESEL_DSA1 >-----------------------*/,{ 9998c2ecf20Sopenharmony_ci /* 10008c2ecf20Sopenharmony_ci * Initialize the status registers 10018c2ecf20Sopenharmony_ci */ 10028c2ecf20Sopenharmony_ci SCR_LOAD_REL (scr0, 4), 10038c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.head.status), 10048c2ecf20Sopenharmony_ci /* 10058c2ecf20Sopenharmony_ci * Jump to dispatcher. 10068c2ecf20Sopenharmony_ci */ 10078c2ecf20Sopenharmony_ci SCR_JUMP, 10088c2ecf20Sopenharmony_ci PADDR_A (dispatch), 10098c2ecf20Sopenharmony_ci}/*-------------------------< RESEL_NO_TAG >---------------------*/,{ 10108c2ecf20Sopenharmony_ci /* 10118c2ecf20Sopenharmony_ci * Load the DSA with the unique ITL task. 10128c2ecf20Sopenharmony_ci */ 10138c2ecf20Sopenharmony_ci SCR_LOAD_REL (dsa, 4), 10148c2ecf20Sopenharmony_ci offsetof(struct sym_lcb, head.itl_task_sa), 10158c2ecf20Sopenharmony_ci /* 10168c2ecf20Sopenharmony_ci * JUMP indirectly to the restart point of the CCB. 10178c2ecf20Sopenharmony_ci */ 10188c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 10198c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.head.go.restart), 10208c2ecf20Sopenharmony_ci SCR_RETURN, 10218c2ecf20Sopenharmony_ci 0, 10228c2ecf20Sopenharmony_ci /* In normal situations we branch to RESEL_DSA */ 10238c2ecf20Sopenharmony_ci}/*-------------------------< DATA_IN >--------------------------*/,{ 10248c2ecf20Sopenharmony_ci/* 10258c2ecf20Sopenharmony_ci * Because the size depends on the 10268c2ecf20Sopenharmony_ci * #define SYM_CONF_MAX_SG parameter, 10278c2ecf20Sopenharmony_ci * it is filled in at runtime. 10288c2ecf20Sopenharmony_ci * 10298c2ecf20Sopenharmony_ci * ##===========< i=0; i<SYM_CONF_MAX_SG >========= 10308c2ecf20Sopenharmony_ci * || SCR_CHMOV_TBL ^ SCR_DATA_IN, 10318c2ecf20Sopenharmony_ci * || offsetof (struct sym_dsb, data[ i]), 10328c2ecf20Sopenharmony_ci * ##========================================== 10338c2ecf20Sopenharmony_ci */ 10348c2ecf20Sopenharmony_ci0 10358c2ecf20Sopenharmony_ci}/*-------------------------< DATA_IN2 >-------------------------*/,{ 10368c2ecf20Sopenharmony_ci SCR_CALL, 10378c2ecf20Sopenharmony_ci PADDR_A (datai_done), 10388c2ecf20Sopenharmony_ci SCR_JUMP, 10398c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 10408c2ecf20Sopenharmony_ci}/*-------------------------< DATA_OUT >-------------------------*/,{ 10418c2ecf20Sopenharmony_ci/* 10428c2ecf20Sopenharmony_ci * Because the size depends on the 10438c2ecf20Sopenharmony_ci * #define SYM_CONF_MAX_SG parameter, 10448c2ecf20Sopenharmony_ci * it is filled in at runtime. 10458c2ecf20Sopenharmony_ci * 10468c2ecf20Sopenharmony_ci * ##===========< i=0; i<SYM_CONF_MAX_SG >========= 10478c2ecf20Sopenharmony_ci * || SCR_CHMOV_TBL ^ SCR_DATA_OUT, 10488c2ecf20Sopenharmony_ci * || offsetof (struct sym_dsb, data[ i]), 10498c2ecf20Sopenharmony_ci * ##========================================== 10508c2ecf20Sopenharmony_ci */ 10518c2ecf20Sopenharmony_ci0 10528c2ecf20Sopenharmony_ci}/*-------------------------< DATA_OUT2 >------------------------*/,{ 10538c2ecf20Sopenharmony_ci SCR_CALL, 10548c2ecf20Sopenharmony_ci PADDR_A (datao_done), 10558c2ecf20Sopenharmony_ci SCR_JUMP, 10568c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 10578c2ecf20Sopenharmony_ci}/*-------------------------< PM0_DATA >-------------------------*/,{ 10588c2ecf20Sopenharmony_ci /* 10598c2ecf20Sopenharmony_ci * Read our host flags to SFBR, so we will be able 10608c2ecf20Sopenharmony_ci * to check against the data direction we expect. 10618c2ecf20Sopenharmony_ci */ 10628c2ecf20Sopenharmony_ci SCR_FROM_REG (HF_REG), 10638c2ecf20Sopenharmony_ci 0, 10648c2ecf20Sopenharmony_ci /* 10658c2ecf20Sopenharmony_ci * Check against actual DATA PHASE. 10668c2ecf20Sopenharmony_ci */ 10678c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 10688c2ecf20Sopenharmony_ci PADDR_A (pm0_data_out), 10698c2ecf20Sopenharmony_ci /* 10708c2ecf20Sopenharmony_ci * Actual phase is DATA IN. 10718c2ecf20Sopenharmony_ci * Check against expected direction. 10728c2ecf20Sopenharmony_ci */ 10738c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), 10748c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 10758c2ecf20Sopenharmony_ci /* 10768c2ecf20Sopenharmony_ci * Keep track we are moving data from the 10778c2ecf20Sopenharmony_ci * PM0 DATA mini-script. 10788c2ecf20Sopenharmony_ci */ 10798c2ecf20Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 10808c2ecf20Sopenharmony_ci 0, 10818c2ecf20Sopenharmony_ci /* 10828c2ecf20Sopenharmony_ci * Move the data to memory. 10838c2ecf20Sopenharmony_ci */ 10848c2ecf20Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 10858c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.pm0.sg), 10868c2ecf20Sopenharmony_ci SCR_JUMP, 10878c2ecf20Sopenharmony_ci PADDR_A (pm0_data_end), 10888c2ecf20Sopenharmony_ci}/*-------------------------< PM0_DATA_OUT >---------------------*/,{ 10898c2ecf20Sopenharmony_ci /* 10908c2ecf20Sopenharmony_ci * Actual phase is DATA OUT. 10918c2ecf20Sopenharmony_ci * Check against expected direction. 10928c2ecf20Sopenharmony_ci */ 10938c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), 10948c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 10958c2ecf20Sopenharmony_ci /* 10968c2ecf20Sopenharmony_ci * Keep track we are moving data from the 10978c2ecf20Sopenharmony_ci * PM0 DATA mini-script. 10988c2ecf20Sopenharmony_ci */ 10998c2ecf20Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 11008c2ecf20Sopenharmony_ci 0, 11018c2ecf20Sopenharmony_ci /* 11028c2ecf20Sopenharmony_ci * Move the data from memory. 11038c2ecf20Sopenharmony_ci */ 11048c2ecf20Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_OUT, 11058c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.pm0.sg), 11068c2ecf20Sopenharmony_ci}/*-------------------------< PM0_DATA_END >---------------------*/,{ 11078c2ecf20Sopenharmony_ci /* 11088c2ecf20Sopenharmony_ci * Clear the flag that told we were moving 11098c2ecf20Sopenharmony_ci * data from the PM0 DATA mini-script. 11108c2ecf20Sopenharmony_ci */ 11118c2ecf20Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)), 11128c2ecf20Sopenharmony_ci 0, 11138c2ecf20Sopenharmony_ci /* 11148c2ecf20Sopenharmony_ci * Return to the previous DATA script which 11158c2ecf20Sopenharmony_ci * is guaranteed by design (if no bug) to be 11168c2ecf20Sopenharmony_ci * the main DATA script for this transfer. 11178c2ecf20Sopenharmony_ci */ 11188c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 11198c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.pm0.ret), 11208c2ecf20Sopenharmony_ci SCR_RETURN, 11218c2ecf20Sopenharmony_ci 0, 11228c2ecf20Sopenharmony_ci}/*-------------------------< PM1_DATA >-------------------------*/,{ 11238c2ecf20Sopenharmony_ci /* 11248c2ecf20Sopenharmony_ci * Read our host flags to SFBR, so we will be able 11258c2ecf20Sopenharmony_ci * to check against the data direction we expect. 11268c2ecf20Sopenharmony_ci */ 11278c2ecf20Sopenharmony_ci SCR_FROM_REG (HF_REG), 11288c2ecf20Sopenharmony_ci 0, 11298c2ecf20Sopenharmony_ci /* 11308c2ecf20Sopenharmony_ci * Check against actual DATA PHASE. 11318c2ecf20Sopenharmony_ci */ 11328c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 11338c2ecf20Sopenharmony_ci PADDR_A (pm1_data_out), 11348c2ecf20Sopenharmony_ci /* 11358c2ecf20Sopenharmony_ci * Actual phase is DATA IN. 11368c2ecf20Sopenharmony_ci * Check against expected direction. 11378c2ecf20Sopenharmony_ci */ 11388c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), 11398c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 11408c2ecf20Sopenharmony_ci /* 11418c2ecf20Sopenharmony_ci * Keep track we are moving data from the 11428c2ecf20Sopenharmony_ci * PM1 DATA mini-script. 11438c2ecf20Sopenharmony_ci */ 11448c2ecf20Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 11458c2ecf20Sopenharmony_ci 0, 11468c2ecf20Sopenharmony_ci /* 11478c2ecf20Sopenharmony_ci * Move the data to memory. 11488c2ecf20Sopenharmony_ci */ 11498c2ecf20Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 11508c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.pm1.sg), 11518c2ecf20Sopenharmony_ci SCR_JUMP, 11528c2ecf20Sopenharmony_ci PADDR_A (pm1_data_end), 11538c2ecf20Sopenharmony_ci}/*-------------------------< PM1_DATA_OUT >---------------------*/,{ 11548c2ecf20Sopenharmony_ci /* 11558c2ecf20Sopenharmony_ci * Actual phase is DATA OUT. 11568c2ecf20Sopenharmony_ci * Check against expected direction. 11578c2ecf20Sopenharmony_ci */ 11588c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), 11598c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 11608c2ecf20Sopenharmony_ci /* 11618c2ecf20Sopenharmony_ci * Keep track we are moving data from the 11628c2ecf20Sopenharmony_ci * PM1 DATA mini-script. 11638c2ecf20Sopenharmony_ci */ 11648c2ecf20Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 11658c2ecf20Sopenharmony_ci 0, 11668c2ecf20Sopenharmony_ci /* 11678c2ecf20Sopenharmony_ci * Move the data from memory. 11688c2ecf20Sopenharmony_ci */ 11698c2ecf20Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_OUT, 11708c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.pm1.sg), 11718c2ecf20Sopenharmony_ci}/*-------------------------< PM1_DATA_END >---------------------*/,{ 11728c2ecf20Sopenharmony_ci /* 11738c2ecf20Sopenharmony_ci * Clear the flag that told we were moving 11748c2ecf20Sopenharmony_ci * data from the PM1 DATA mini-script. 11758c2ecf20Sopenharmony_ci */ 11768c2ecf20Sopenharmony_ci SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)), 11778c2ecf20Sopenharmony_ci 0, 11788c2ecf20Sopenharmony_ci /* 11798c2ecf20Sopenharmony_ci * Return to the previous DATA script which 11808c2ecf20Sopenharmony_ci * is guaranteed by design (if no bug) to be 11818c2ecf20Sopenharmony_ci * the main DATA script for this transfer. 11828c2ecf20Sopenharmony_ci */ 11838c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 11848c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.pm1.ret), 11858c2ecf20Sopenharmony_ci SCR_RETURN, 11868c2ecf20Sopenharmony_ci 0, 11878c2ecf20Sopenharmony_ci}/*-------------------------<>-----------------------------------*/ 11888c2ecf20Sopenharmony_ci}; 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_cistatic struct SYM_FWB_SCR SYM_FWB_SCR = { 11918c2ecf20Sopenharmony_ci/*--------------------------< START64 >--------------------------*/ { 11928c2ecf20Sopenharmony_ci /* 11938c2ecf20Sopenharmony_ci * SCRIPT entry point for the 895A, 896 and 1010. 11948c2ecf20Sopenharmony_ci * For now, there is no specific stuff for those 11958c2ecf20Sopenharmony_ci * chips at this point, but this may come. 11968c2ecf20Sopenharmony_ci */ 11978c2ecf20Sopenharmony_ci SCR_JUMP, 11988c2ecf20Sopenharmony_ci PADDR_A (init), 11998c2ecf20Sopenharmony_ci}/*-------------------------< NO_DATA >--------------------------*/,{ 12008c2ecf20Sopenharmony_ci SCR_JUMP, 12018c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 12028c2ecf20Sopenharmony_ci}/*-------------------------< SEL_FOR_ABORT >--------------------*/,{ 12038c2ecf20Sopenharmony_ci /* 12048c2ecf20Sopenharmony_ci * We are jumped here by the C code, if we have 12058c2ecf20Sopenharmony_ci * some target to reset or some disconnected 12068c2ecf20Sopenharmony_ci * job to abort. Since error recovery is a serious 12078c2ecf20Sopenharmony_ci * busyness, we will really reset the SCSI BUS, if 12088c2ecf20Sopenharmony_ci * case of a SCSI interrupt occurring in this path. 12098c2ecf20Sopenharmony_ci */ 12108c2ecf20Sopenharmony_ci#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 12118c2ecf20Sopenharmony_ci /* 12128c2ecf20Sopenharmony_ci * Set initiator mode. 12138c2ecf20Sopenharmony_ci */ 12148c2ecf20Sopenharmony_ci SCR_CLR (SCR_TRG), 12158c2ecf20Sopenharmony_ci 0, 12168c2ecf20Sopenharmony_ci#endif 12178c2ecf20Sopenharmony_ci /* 12188c2ecf20Sopenharmony_ci * And try to select this target. 12198c2ecf20Sopenharmony_ci */ 12208c2ecf20Sopenharmony_ci SCR_SEL_TBL_ATN ^ offsetof (struct sym_hcb, abrt_sel), 12218c2ecf20Sopenharmony_ci PADDR_A (reselect), 12228c2ecf20Sopenharmony_ci /* 12238c2ecf20Sopenharmony_ci * Wait for the selection to complete or 12248c2ecf20Sopenharmony_ci * the selection to time out. 12258c2ecf20Sopenharmony_ci */ 12268c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)), 12278c2ecf20Sopenharmony_ci -8, 12288c2ecf20Sopenharmony_ci /* 12298c2ecf20Sopenharmony_ci * Call the C code. 12308c2ecf20Sopenharmony_ci */ 12318c2ecf20Sopenharmony_ci SCR_INT, 12328c2ecf20Sopenharmony_ci SIR_TARGET_SELECTED, 12338c2ecf20Sopenharmony_ci /* 12348c2ecf20Sopenharmony_ci * The C code should let us continue here. 12358c2ecf20Sopenharmony_ci * Send the 'kiss of death' message. 12368c2ecf20Sopenharmony_ci * We expect an immediate disconnect once 12378c2ecf20Sopenharmony_ci * the target has eaten the message. 12388c2ecf20Sopenharmony_ci */ 12398c2ecf20Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 12408c2ecf20Sopenharmony_ci 0, 12418c2ecf20Sopenharmony_ci SCR_MOVE_TBL ^ SCR_MSG_OUT, 12428c2ecf20Sopenharmony_ci offsetof (struct sym_hcb, abrt_tbl), 12438c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 12448c2ecf20Sopenharmony_ci 0, 12458c2ecf20Sopenharmony_ci SCR_WAIT_DISC, 12468c2ecf20Sopenharmony_ci 0, 12478c2ecf20Sopenharmony_ci /* 12488c2ecf20Sopenharmony_ci * Tell the C code that we are done. 12498c2ecf20Sopenharmony_ci */ 12508c2ecf20Sopenharmony_ci SCR_INT, 12518c2ecf20Sopenharmony_ci SIR_ABORT_SENT, 12528c2ecf20Sopenharmony_ci}/*-------------------------< SEL_FOR_ABORT_1 >------------------*/,{ 12538c2ecf20Sopenharmony_ci /* 12548c2ecf20Sopenharmony_ci * Jump at scheduler. 12558c2ecf20Sopenharmony_ci */ 12568c2ecf20Sopenharmony_ci SCR_JUMP, 12578c2ecf20Sopenharmony_ci PADDR_A (start), 12588c2ecf20Sopenharmony_ci}/*-------------------------< MSG_IN_ETC >-----------------------*/,{ 12598c2ecf20Sopenharmony_ci /* 12608c2ecf20Sopenharmony_ci * If it is an EXTENDED (variable size message) 12618c2ecf20Sopenharmony_ci * Handle it. 12628c2ecf20Sopenharmony_ci */ 12638c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), 12648c2ecf20Sopenharmony_ci PADDR_B (msg_extended), 12658c2ecf20Sopenharmony_ci /* 12668c2ecf20Sopenharmony_ci * Let the C code handle any other 12678c2ecf20Sopenharmony_ci * 1 byte message. 12688c2ecf20Sopenharmony_ci */ 12698c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0x00, 0xf0)), 12708c2ecf20Sopenharmony_ci PADDR_B (msg_received), 12718c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0x10, 0xf0)), 12728c2ecf20Sopenharmony_ci PADDR_B (msg_received), 12738c2ecf20Sopenharmony_ci /* 12748c2ecf20Sopenharmony_ci * We donnot handle 2 bytes messages from SCRIPTS. 12758c2ecf20Sopenharmony_ci * So, let the C code deal with these ones too. 12768c2ecf20Sopenharmony_ci */ 12778c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (MASK (0x20, 0xf0)), 12788c2ecf20Sopenharmony_ci PADDR_B (msg_weird_seen), 12798c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 12808c2ecf20Sopenharmony_ci 0, 12818c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 12828c2ecf20Sopenharmony_ci HADDR_1 (msgin[1]), 12838c2ecf20Sopenharmony_ci}/*-------------------------< MSG_RECEIVED >---------------------*/,{ 12848c2ecf20Sopenharmony_ci SCR_LOAD_REL (scratcha, 4), /* DUMMY READ */ 12858c2ecf20Sopenharmony_ci 0, 12868c2ecf20Sopenharmony_ci SCR_INT, 12878c2ecf20Sopenharmony_ci SIR_MSG_RECEIVED, 12888c2ecf20Sopenharmony_ci}/*-------------------------< MSG_WEIRD_SEEN >-------------------*/,{ 12898c2ecf20Sopenharmony_ci SCR_LOAD_REL (scratcha, 4), /* DUMMY READ */ 12908c2ecf20Sopenharmony_ci 0, 12918c2ecf20Sopenharmony_ci SCR_INT, 12928c2ecf20Sopenharmony_ci SIR_MSG_WEIRD, 12938c2ecf20Sopenharmony_ci}/*-------------------------< MSG_EXTENDED >---------------------*/,{ 12948c2ecf20Sopenharmony_ci /* 12958c2ecf20Sopenharmony_ci * Clear ACK and get the next byte 12968c2ecf20Sopenharmony_ci * assumed to be the message length. 12978c2ecf20Sopenharmony_ci */ 12988c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 12998c2ecf20Sopenharmony_ci 0, 13008c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 13018c2ecf20Sopenharmony_ci HADDR_1 (msgin[1]), 13028c2ecf20Sopenharmony_ci /* 13038c2ecf20Sopenharmony_ci * Try to catch some unlikely situations as 0 length 13048c2ecf20Sopenharmony_ci * or too large the length. 13058c2ecf20Sopenharmony_ci */ 13068c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (DATA (0)), 13078c2ecf20Sopenharmony_ci PADDR_B (msg_weird_seen), 13088c2ecf20Sopenharmony_ci SCR_TO_REG (scratcha), 13098c2ecf20Sopenharmony_ci 0, 13108c2ecf20Sopenharmony_ci SCR_REG_REG (sfbr, SCR_ADD, (256-8)), 13118c2ecf20Sopenharmony_ci 0, 13128c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (CARRYSET), 13138c2ecf20Sopenharmony_ci PADDR_B (msg_weird_seen), 13148c2ecf20Sopenharmony_ci /* 13158c2ecf20Sopenharmony_ci * We donnot handle extended messages from SCRIPTS. 13168c2ecf20Sopenharmony_ci * Read the amount of data corresponding to the 13178c2ecf20Sopenharmony_ci * message length and call the C code. 13188c2ecf20Sopenharmony_ci */ 13198c2ecf20Sopenharmony_ci SCR_STORE_REL (scratcha, 1), 13208c2ecf20Sopenharmony_ci offsetof (struct sym_dsb, smsg_ext.size), 13218c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 13228c2ecf20Sopenharmony_ci 0, 13238c2ecf20Sopenharmony_ci SCR_MOVE_TBL ^ SCR_MSG_IN, 13248c2ecf20Sopenharmony_ci offsetof (struct sym_dsb, smsg_ext), 13258c2ecf20Sopenharmony_ci SCR_JUMP, 13268c2ecf20Sopenharmony_ci PADDR_B (msg_received), 13278c2ecf20Sopenharmony_ci}/*-------------------------< MSG_BAD >--------------------------*/,{ 13288c2ecf20Sopenharmony_ci /* 13298c2ecf20Sopenharmony_ci * unimplemented message - reject it. 13308c2ecf20Sopenharmony_ci */ 13318c2ecf20Sopenharmony_ci SCR_INT, 13328c2ecf20Sopenharmony_ci SIR_REJECT_TO_SEND, 13338c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), 13348c2ecf20Sopenharmony_ci 0, 13358c2ecf20Sopenharmony_ci SCR_JUMP, 13368c2ecf20Sopenharmony_ci PADDR_A (clrack), 13378c2ecf20Sopenharmony_ci}/*-------------------------< MSG_WEIRD >------------------------*/,{ 13388c2ecf20Sopenharmony_ci /* 13398c2ecf20Sopenharmony_ci * weird message received 13408c2ecf20Sopenharmony_ci * ignore all MSG IN phases and reject it. 13418c2ecf20Sopenharmony_ci */ 13428c2ecf20Sopenharmony_ci SCR_INT, 13438c2ecf20Sopenharmony_ci SIR_REJECT_TO_SEND, 13448c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), 13458c2ecf20Sopenharmony_ci 0, 13468c2ecf20Sopenharmony_ci}/*-------------------------< MSG_WEIRD1 >-----------------------*/,{ 13478c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 13488c2ecf20Sopenharmony_ci 0, 13498c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 13508c2ecf20Sopenharmony_ci PADDR_A (dispatch), 13518c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 13528c2ecf20Sopenharmony_ci HADDR_1 (scratch), 13538c2ecf20Sopenharmony_ci SCR_JUMP, 13548c2ecf20Sopenharmony_ci PADDR_B (msg_weird1), 13558c2ecf20Sopenharmony_ci}/*-------------------------< WDTR_RESP >------------------------*/,{ 13568c2ecf20Sopenharmony_ci /* 13578c2ecf20Sopenharmony_ci * let the target fetch our answer. 13588c2ecf20Sopenharmony_ci */ 13598c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), 13608c2ecf20Sopenharmony_ci 0, 13618c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 13628c2ecf20Sopenharmony_ci 0, 13638c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 13648c2ecf20Sopenharmony_ci PADDR_B (nego_bad_phase), 13658c2ecf20Sopenharmony_ci}/*-------------------------< SEND_WDTR >------------------------*/,{ 13668c2ecf20Sopenharmony_ci /* 13678c2ecf20Sopenharmony_ci * Send the M_X_WIDE_REQ 13688c2ecf20Sopenharmony_ci */ 13698c2ecf20Sopenharmony_ci SCR_MOVE_ABS (4) ^ SCR_MSG_OUT, 13708c2ecf20Sopenharmony_ci HADDR_1 (msgout), 13718c2ecf20Sopenharmony_ci SCR_JUMP, 13728c2ecf20Sopenharmony_ci PADDR_B (msg_out_done), 13738c2ecf20Sopenharmony_ci}/*-------------------------< SDTR_RESP >------------------------*/,{ 13748c2ecf20Sopenharmony_ci /* 13758c2ecf20Sopenharmony_ci * let the target fetch our answer. 13768c2ecf20Sopenharmony_ci */ 13778c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), 13788c2ecf20Sopenharmony_ci 0, 13798c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 13808c2ecf20Sopenharmony_ci 0, 13818c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 13828c2ecf20Sopenharmony_ci PADDR_B (nego_bad_phase), 13838c2ecf20Sopenharmony_ci}/*-------------------------< SEND_SDTR >------------------------*/,{ 13848c2ecf20Sopenharmony_ci /* 13858c2ecf20Sopenharmony_ci * Send the M_X_SYNC_REQ 13868c2ecf20Sopenharmony_ci */ 13878c2ecf20Sopenharmony_ci SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, 13888c2ecf20Sopenharmony_ci HADDR_1 (msgout), 13898c2ecf20Sopenharmony_ci SCR_JUMP, 13908c2ecf20Sopenharmony_ci PADDR_B (msg_out_done), 13918c2ecf20Sopenharmony_ci}/*-------------------------< PPR_RESP >-------------------------*/,{ 13928c2ecf20Sopenharmony_ci /* 13938c2ecf20Sopenharmony_ci * let the target fetch our answer. 13948c2ecf20Sopenharmony_ci */ 13958c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), 13968c2ecf20Sopenharmony_ci 0, 13978c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 13988c2ecf20Sopenharmony_ci 0, 13998c2ecf20Sopenharmony_ci SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 14008c2ecf20Sopenharmony_ci PADDR_B (nego_bad_phase), 14018c2ecf20Sopenharmony_ci}/*-------------------------< SEND_PPR >-------------------------*/,{ 14028c2ecf20Sopenharmony_ci /* 14038c2ecf20Sopenharmony_ci * Send the M_X_PPR_REQ 14048c2ecf20Sopenharmony_ci */ 14058c2ecf20Sopenharmony_ci SCR_MOVE_ABS (8) ^ SCR_MSG_OUT, 14068c2ecf20Sopenharmony_ci HADDR_1 (msgout), 14078c2ecf20Sopenharmony_ci SCR_JUMP, 14088c2ecf20Sopenharmony_ci PADDR_B (msg_out_done), 14098c2ecf20Sopenharmony_ci}/*-------------------------< NEGO_BAD_PHASE >-------------------*/,{ 14108c2ecf20Sopenharmony_ci SCR_INT, 14118c2ecf20Sopenharmony_ci SIR_NEGO_PROTO, 14128c2ecf20Sopenharmony_ci SCR_JUMP, 14138c2ecf20Sopenharmony_ci PADDR_A (dispatch), 14148c2ecf20Sopenharmony_ci}/*-------------------------< MSG_OUT >--------------------------*/,{ 14158c2ecf20Sopenharmony_ci /* 14168c2ecf20Sopenharmony_ci * The target requests a message. 14178c2ecf20Sopenharmony_ci * We donnot send messages that may 14188c2ecf20Sopenharmony_ci * require the device to go to bus free. 14198c2ecf20Sopenharmony_ci */ 14208c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 14218c2ecf20Sopenharmony_ci HADDR_1 (msgout), 14228c2ecf20Sopenharmony_ci /* 14238c2ecf20Sopenharmony_ci * ... wait for the next phase 14248c2ecf20Sopenharmony_ci * if it's a message out, send it again, ... 14258c2ecf20Sopenharmony_ci */ 14268c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), 14278c2ecf20Sopenharmony_ci PADDR_B (msg_out), 14288c2ecf20Sopenharmony_ci}/*-------------------------< MSG_OUT_DONE >---------------------*/,{ 14298c2ecf20Sopenharmony_ci /* 14308c2ecf20Sopenharmony_ci * Let the C code be aware of the 14318c2ecf20Sopenharmony_ci * sent message and clear the message. 14328c2ecf20Sopenharmony_ci */ 14338c2ecf20Sopenharmony_ci SCR_INT, 14348c2ecf20Sopenharmony_ci SIR_MSG_OUT_DONE, 14358c2ecf20Sopenharmony_ci /* 14368c2ecf20Sopenharmony_ci * ... and process the next phase 14378c2ecf20Sopenharmony_ci */ 14388c2ecf20Sopenharmony_ci SCR_JUMP, 14398c2ecf20Sopenharmony_ci PADDR_A (dispatch), 14408c2ecf20Sopenharmony_ci}/*-------------------------< DATA_OVRUN >-----------------------*/,{ 14418c2ecf20Sopenharmony_ci /* 14428c2ecf20Sopenharmony_ci * Use scratcha to count the extra bytes. 14438c2ecf20Sopenharmony_ci */ 14448c2ecf20Sopenharmony_ci SCR_LOAD_ABS (scratcha, 4), 14458c2ecf20Sopenharmony_ci PADDR_B (zero), 14468c2ecf20Sopenharmony_ci}/*-------------------------< DATA_OVRUN1 >----------------------*/,{ 14478c2ecf20Sopenharmony_ci /* 14488c2ecf20Sopenharmony_ci * The target may want to transfer too much data. 14498c2ecf20Sopenharmony_ci * 14508c2ecf20Sopenharmony_ci * If phase is DATA OUT write 1 byte and count it. 14518c2ecf20Sopenharmony_ci */ 14528c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)), 14538c2ecf20Sopenharmony_ci 16, 14548c2ecf20Sopenharmony_ci SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT, 14558c2ecf20Sopenharmony_ci HADDR_1 (scratch), 14568c2ecf20Sopenharmony_ci SCR_JUMP, 14578c2ecf20Sopenharmony_ci PADDR_B (data_ovrun2), 14588c2ecf20Sopenharmony_ci /* 14598c2ecf20Sopenharmony_ci * If WSR is set, clear this condition, and 14608c2ecf20Sopenharmony_ci * count this byte. 14618c2ecf20Sopenharmony_ci */ 14628c2ecf20Sopenharmony_ci SCR_FROM_REG (scntl2), 14638c2ecf20Sopenharmony_ci 0, 14648c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)), 14658c2ecf20Sopenharmony_ci 16, 14668c2ecf20Sopenharmony_ci SCR_REG_REG (scntl2, SCR_OR, WSR), 14678c2ecf20Sopenharmony_ci 0, 14688c2ecf20Sopenharmony_ci SCR_JUMP, 14698c2ecf20Sopenharmony_ci PADDR_B (data_ovrun2), 14708c2ecf20Sopenharmony_ci /* 14718c2ecf20Sopenharmony_ci * Finally check against DATA IN phase. 14728c2ecf20Sopenharmony_ci * Signal data overrun to the C code 14738c2ecf20Sopenharmony_ci * and jump to dispatcher if not so. 14748c2ecf20Sopenharmony_ci * Read 1 byte otherwise and count it. 14758c2ecf20Sopenharmony_ci */ 14768c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFTRUE (WHEN (SCR_DATA_IN)), 14778c2ecf20Sopenharmony_ci 16, 14788c2ecf20Sopenharmony_ci SCR_INT, 14798c2ecf20Sopenharmony_ci SIR_DATA_OVERRUN, 14808c2ecf20Sopenharmony_ci SCR_JUMP, 14818c2ecf20Sopenharmony_ci PADDR_A (dispatch), 14828c2ecf20Sopenharmony_ci SCR_CHMOV_ABS (1) ^ SCR_DATA_IN, 14838c2ecf20Sopenharmony_ci HADDR_1 (scratch), 14848c2ecf20Sopenharmony_ci}/*-------------------------< DATA_OVRUN2 >----------------------*/,{ 14858c2ecf20Sopenharmony_ci /* 14868c2ecf20Sopenharmony_ci * Count this byte. 14878c2ecf20Sopenharmony_ci * This will allow to return a negative 14888c2ecf20Sopenharmony_ci * residual to user. 14898c2ecf20Sopenharmony_ci */ 14908c2ecf20Sopenharmony_ci SCR_REG_REG (scratcha, SCR_ADD, 0x01), 14918c2ecf20Sopenharmony_ci 0, 14928c2ecf20Sopenharmony_ci SCR_REG_REG (scratcha1, SCR_ADDC, 0), 14938c2ecf20Sopenharmony_ci 0, 14948c2ecf20Sopenharmony_ci SCR_REG_REG (scratcha2, SCR_ADDC, 0), 14958c2ecf20Sopenharmony_ci 0, 14968c2ecf20Sopenharmony_ci /* 14978c2ecf20Sopenharmony_ci * .. and repeat as required. 14988c2ecf20Sopenharmony_ci */ 14998c2ecf20Sopenharmony_ci SCR_JUMP, 15008c2ecf20Sopenharmony_ci PADDR_B (data_ovrun1), 15018c2ecf20Sopenharmony_ci}/*-------------------------< ABORT_RESEL >----------------------*/,{ 15028c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), 15038c2ecf20Sopenharmony_ci 0, 15048c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK), 15058c2ecf20Sopenharmony_ci 0, 15068c2ecf20Sopenharmony_ci /* 15078c2ecf20Sopenharmony_ci * send the abort/abortag/reset message 15088c2ecf20Sopenharmony_ci * we expect an immediate disconnect 15098c2ecf20Sopenharmony_ci */ 15108c2ecf20Sopenharmony_ci SCR_REG_REG (scntl2, SCR_AND, 0x7f), 15118c2ecf20Sopenharmony_ci 0, 15128c2ecf20Sopenharmony_ci SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 15138c2ecf20Sopenharmony_ci HADDR_1 (msgout), 15148c2ecf20Sopenharmony_ci SCR_CLR (SCR_ACK|SCR_ATN), 15158c2ecf20Sopenharmony_ci 0, 15168c2ecf20Sopenharmony_ci SCR_WAIT_DISC, 15178c2ecf20Sopenharmony_ci 0, 15188c2ecf20Sopenharmony_ci SCR_INT, 15198c2ecf20Sopenharmony_ci SIR_RESEL_ABORTED, 15208c2ecf20Sopenharmony_ci SCR_JUMP, 15218c2ecf20Sopenharmony_ci PADDR_A (start), 15228c2ecf20Sopenharmony_ci}/*-------------------------< RESEND_IDENT >---------------------*/,{ 15238c2ecf20Sopenharmony_ci /* 15248c2ecf20Sopenharmony_ci * The target stays in MSG OUT phase after having acked 15258c2ecf20Sopenharmony_ci * Identify [+ Tag [+ Extended message ]]. Targets shall 15268c2ecf20Sopenharmony_ci * behave this way on parity error. 15278c2ecf20Sopenharmony_ci * We must send it again all the messages. 15288c2ecf20Sopenharmony_ci */ 15298c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), /* Shall be asserted 2 deskew delays before the */ 15308c2ecf20Sopenharmony_ci 0, /* 1rst ACK = 90 ns. Hope the chip isn't too fast */ 15318c2ecf20Sopenharmony_ci SCR_JUMP, 15328c2ecf20Sopenharmony_ci PADDR_A (send_ident), 15338c2ecf20Sopenharmony_ci}/*-------------------------< IDENT_BREAK >----------------------*/,{ 15348c2ecf20Sopenharmony_ci SCR_CLR (SCR_ATN), 15358c2ecf20Sopenharmony_ci 0, 15368c2ecf20Sopenharmony_ci SCR_JUMP, 15378c2ecf20Sopenharmony_ci PADDR_A (select2), 15388c2ecf20Sopenharmony_ci}/*-------------------------< IDENT_BREAK_ATN >------------------*/,{ 15398c2ecf20Sopenharmony_ci SCR_SET (SCR_ATN), 15408c2ecf20Sopenharmony_ci 0, 15418c2ecf20Sopenharmony_ci SCR_JUMP, 15428c2ecf20Sopenharmony_ci PADDR_A (select2), 15438c2ecf20Sopenharmony_ci}/*-------------------------< SDATA_IN >-------------------------*/,{ 15448c2ecf20Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 15458c2ecf20Sopenharmony_ci offsetof (struct sym_dsb, sense), 15468c2ecf20Sopenharmony_ci SCR_CALL, 15478c2ecf20Sopenharmony_ci PADDR_A (datai_done), 15488c2ecf20Sopenharmony_ci SCR_JUMP, 15498c2ecf20Sopenharmony_ci PADDR_B (data_ovrun), 15508c2ecf20Sopenharmony_ci}/*-------------------------< RESEL_BAD_LUN >--------------------*/,{ 15518c2ecf20Sopenharmony_ci /* 15528c2ecf20Sopenharmony_ci * Message is an IDENTIFY, but lun is unknown. 15538c2ecf20Sopenharmony_ci * Signal problem to C code for logging the event. 15548c2ecf20Sopenharmony_ci * Send a M_ABORT to clear all pending tasks. 15558c2ecf20Sopenharmony_ci */ 15568c2ecf20Sopenharmony_ci SCR_INT, 15578c2ecf20Sopenharmony_ci SIR_RESEL_BAD_LUN, 15588c2ecf20Sopenharmony_ci SCR_JUMP, 15598c2ecf20Sopenharmony_ci PADDR_B (abort_resel), 15608c2ecf20Sopenharmony_ci}/*-------------------------< BAD_I_T_L >------------------------*/,{ 15618c2ecf20Sopenharmony_ci /* 15628c2ecf20Sopenharmony_ci * We donnot have a task for that I_T_L. 15638c2ecf20Sopenharmony_ci * Signal problem to C code for logging the event. 15648c2ecf20Sopenharmony_ci * Send a M_ABORT message. 15658c2ecf20Sopenharmony_ci */ 15668c2ecf20Sopenharmony_ci SCR_INT, 15678c2ecf20Sopenharmony_ci SIR_RESEL_BAD_I_T_L, 15688c2ecf20Sopenharmony_ci SCR_JUMP, 15698c2ecf20Sopenharmony_ci PADDR_B (abort_resel), 15708c2ecf20Sopenharmony_ci}/*-------------------------< BAD_I_T_L_Q >----------------------*/,{ 15718c2ecf20Sopenharmony_ci /* 15728c2ecf20Sopenharmony_ci * We donnot have a task that matches the tag. 15738c2ecf20Sopenharmony_ci * Signal problem to C code for logging the event. 15748c2ecf20Sopenharmony_ci * Send a M_ABORTTAG message. 15758c2ecf20Sopenharmony_ci */ 15768c2ecf20Sopenharmony_ci SCR_INT, 15778c2ecf20Sopenharmony_ci SIR_RESEL_BAD_I_T_L_Q, 15788c2ecf20Sopenharmony_ci SCR_JUMP, 15798c2ecf20Sopenharmony_ci PADDR_B (abort_resel), 15808c2ecf20Sopenharmony_ci}/*-------------------------< BAD_STATUS >-----------------------*/,{ 15818c2ecf20Sopenharmony_ci /* 15828c2ecf20Sopenharmony_ci * Anything different from INTERMEDIATE 15838c2ecf20Sopenharmony_ci * CONDITION MET should be a bad SCSI status, 15848c2ecf20Sopenharmony_ci * given that GOOD status has already been tested. 15858c2ecf20Sopenharmony_ci * Call the C code. 15868c2ecf20Sopenharmony_ci */ 15878c2ecf20Sopenharmony_ci SCR_LOAD_ABS (scratcha, 4), 15888c2ecf20Sopenharmony_ci PADDR_B (startpos), 15898c2ecf20Sopenharmony_ci SCR_INT ^ IFFALSE (DATA (S_COND_MET)), 15908c2ecf20Sopenharmony_ci SIR_BAD_SCSI_STATUS, 15918c2ecf20Sopenharmony_ci SCR_RETURN, 15928c2ecf20Sopenharmony_ci 0, 15938c2ecf20Sopenharmony_ci}/*-------------------------< PM_HANDLE >------------------------*/,{ 15948c2ecf20Sopenharmony_ci /* 15958c2ecf20Sopenharmony_ci * Phase mismatch handling. 15968c2ecf20Sopenharmony_ci * 15978c2ecf20Sopenharmony_ci * Since we have to deal with 2 SCSI data pointers 15988c2ecf20Sopenharmony_ci * (current and saved), we need at least 2 contexts. 15998c2ecf20Sopenharmony_ci * Each context (pm0 and pm1) has a saved area, a 16008c2ecf20Sopenharmony_ci * SAVE mini-script and a DATA phase mini-script. 16018c2ecf20Sopenharmony_ci */ 16028c2ecf20Sopenharmony_ci /* 16038c2ecf20Sopenharmony_ci * Get the PM handling flags. 16048c2ecf20Sopenharmony_ci */ 16058c2ecf20Sopenharmony_ci SCR_FROM_REG (HF_REG), 16068c2ecf20Sopenharmony_ci 0, 16078c2ecf20Sopenharmony_ci /* 16088c2ecf20Sopenharmony_ci * If no flags (1rst PM for example), avoid 16098c2ecf20Sopenharmony_ci * all the below heavy flags testing. 16108c2ecf20Sopenharmony_ci * This makes the normal case a bit faster. 16118c2ecf20Sopenharmony_ci */ 16128c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED))), 16138c2ecf20Sopenharmony_ci PADDR_B (pm_handle1), 16148c2ecf20Sopenharmony_ci /* 16158c2ecf20Sopenharmony_ci * If we received a SAVE DP, switch to the 16168c2ecf20Sopenharmony_ci * other PM context since the savep may point 16178c2ecf20Sopenharmony_ci * to the current PM context. 16188c2ecf20Sopenharmony_ci */ 16198c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (MASK (HF_DP_SAVED, HF_DP_SAVED)), 16208c2ecf20Sopenharmony_ci 8, 16218c2ecf20Sopenharmony_ci SCR_REG_REG (sfbr, SCR_XOR, HF_ACT_PM), 16228c2ecf20Sopenharmony_ci 0, 16238c2ecf20Sopenharmony_ci /* 16248c2ecf20Sopenharmony_ci * If we have been interrupt in a PM DATA mini-script, 16258c2ecf20Sopenharmony_ci * we take the return address from the corresponding 16268c2ecf20Sopenharmony_ci * saved area. 16278c2ecf20Sopenharmony_ci * This ensure the return address always points to the 16288c2ecf20Sopenharmony_ci * main DATA script for this transfer. 16298c2ecf20Sopenharmony_ci */ 16308c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1))), 16318c2ecf20Sopenharmony_ci PADDR_B (pm_handle1), 16328c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (MASK (HF_IN_PM0, HF_IN_PM0)), 16338c2ecf20Sopenharmony_ci 16, 16348c2ecf20Sopenharmony_ci SCR_LOAD_REL (ia, 4), 16358c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm0.ret), 16368c2ecf20Sopenharmony_ci SCR_JUMP, 16378c2ecf20Sopenharmony_ci PADDR_B (pm_save), 16388c2ecf20Sopenharmony_ci SCR_LOAD_REL (ia, 4), 16398c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm1.ret), 16408c2ecf20Sopenharmony_ci SCR_JUMP, 16418c2ecf20Sopenharmony_ci PADDR_B (pm_save), 16428c2ecf20Sopenharmony_ci}/*-------------------------< PM_HANDLE1 >-----------------------*/,{ 16438c2ecf20Sopenharmony_ci /* 16448c2ecf20Sopenharmony_ci * Normal case. 16458c2ecf20Sopenharmony_ci * Update the return address so that it 16468c2ecf20Sopenharmony_ci * will point after the interrupted MOVE. 16478c2ecf20Sopenharmony_ci */ 16488c2ecf20Sopenharmony_ci SCR_REG_REG (ia, SCR_ADD, 8), 16498c2ecf20Sopenharmony_ci 0, 16508c2ecf20Sopenharmony_ci SCR_REG_REG (ia1, SCR_ADDC, 0), 16518c2ecf20Sopenharmony_ci 0, 16528c2ecf20Sopenharmony_ci}/*-------------------------< PM_SAVE >--------------------------*/,{ 16538c2ecf20Sopenharmony_ci /* 16548c2ecf20Sopenharmony_ci * Clear all the flags that told us if we were 16558c2ecf20Sopenharmony_ci * interrupted in a PM DATA mini-script and/or 16568c2ecf20Sopenharmony_ci * we received a SAVE DP. 16578c2ecf20Sopenharmony_ci */ 16588c2ecf20Sopenharmony_ci SCR_SFBR_REG (HF_REG, SCR_AND, (~(HF_IN_PM0|HF_IN_PM1|HF_DP_SAVED))), 16598c2ecf20Sopenharmony_ci 0, 16608c2ecf20Sopenharmony_ci /* 16618c2ecf20Sopenharmony_ci * Choose the current PM context. 16628c2ecf20Sopenharmony_ci */ 16638c2ecf20Sopenharmony_ci SCR_JUMP ^ IFTRUE (MASK (HF_ACT_PM, HF_ACT_PM)), 16648c2ecf20Sopenharmony_ci PADDR_B (pm1_save), 16658c2ecf20Sopenharmony_ci}/*-------------------------< PM0_SAVE >-------------------------*/,{ 16668c2ecf20Sopenharmony_ci SCR_STORE_REL (ia, 4), 16678c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm0.ret), 16688c2ecf20Sopenharmony_ci /* 16698c2ecf20Sopenharmony_ci * If WSR bit is set, either UA and RBC may 16708c2ecf20Sopenharmony_ci * have to be changed whether the device wants 16718c2ecf20Sopenharmony_ci * to ignore this residue or not. 16728c2ecf20Sopenharmony_ci */ 16738c2ecf20Sopenharmony_ci SCR_FROM_REG (scntl2), 16748c2ecf20Sopenharmony_ci 0, 16758c2ecf20Sopenharmony_ci SCR_CALL ^ IFTRUE (MASK (WSR, WSR)), 16768c2ecf20Sopenharmony_ci PADDR_B (pm_wsr_handle), 16778c2ecf20Sopenharmony_ci /* 16788c2ecf20Sopenharmony_ci * Save the remaining byte count, the updated 16798c2ecf20Sopenharmony_ci * address and the return address. 16808c2ecf20Sopenharmony_ci */ 16818c2ecf20Sopenharmony_ci SCR_STORE_REL (rbc, 4), 16828c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm0.sg.size), 16838c2ecf20Sopenharmony_ci SCR_STORE_REL (ua, 4), 16848c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm0.sg.addr), 16858c2ecf20Sopenharmony_ci /* 16868c2ecf20Sopenharmony_ci * Set the current pointer at the PM0 DATA mini-script. 16878c2ecf20Sopenharmony_ci */ 16888c2ecf20Sopenharmony_ci SCR_LOAD_ABS (ia, 4), 16898c2ecf20Sopenharmony_ci PADDR_B (pm0_data_addr), 16908c2ecf20Sopenharmony_ci}/*-------------------------< PM_SAVE_END >----------------------*/,{ 16918c2ecf20Sopenharmony_ci SCR_STORE_REL (ia, 4), 16928c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.head.lastp), 16938c2ecf20Sopenharmony_ci SCR_JUMP, 16948c2ecf20Sopenharmony_ci PADDR_A (dispatch), 16958c2ecf20Sopenharmony_ci}/*-------------------------< PM1_SAVE >-------------------------*/,{ 16968c2ecf20Sopenharmony_ci SCR_STORE_REL (ia, 4), 16978c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm1.ret), 16988c2ecf20Sopenharmony_ci /* 16998c2ecf20Sopenharmony_ci * If WSR bit is set, either UA and RBC may 17008c2ecf20Sopenharmony_ci * have to be changed whether the device wants 17018c2ecf20Sopenharmony_ci * to ignore this residue or not. 17028c2ecf20Sopenharmony_ci */ 17038c2ecf20Sopenharmony_ci SCR_FROM_REG (scntl2), 17048c2ecf20Sopenharmony_ci 0, 17058c2ecf20Sopenharmony_ci SCR_CALL ^ IFTRUE (MASK (WSR, WSR)), 17068c2ecf20Sopenharmony_ci PADDR_B (pm_wsr_handle), 17078c2ecf20Sopenharmony_ci /* 17088c2ecf20Sopenharmony_ci * Save the remaining byte count, the updated 17098c2ecf20Sopenharmony_ci * address and the return address. 17108c2ecf20Sopenharmony_ci */ 17118c2ecf20Sopenharmony_ci SCR_STORE_REL (rbc, 4), 17128c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm1.sg.size), 17138c2ecf20Sopenharmony_ci SCR_STORE_REL (ua, 4), 17148c2ecf20Sopenharmony_ci offsetof(struct sym_ccb, phys.pm1.sg.addr), 17158c2ecf20Sopenharmony_ci /* 17168c2ecf20Sopenharmony_ci * Set the current pointer at the PM1 DATA mini-script. 17178c2ecf20Sopenharmony_ci */ 17188c2ecf20Sopenharmony_ci SCR_LOAD_ABS (ia, 4), 17198c2ecf20Sopenharmony_ci PADDR_B (pm1_data_addr), 17208c2ecf20Sopenharmony_ci SCR_JUMP, 17218c2ecf20Sopenharmony_ci PADDR_B (pm_save_end), 17228c2ecf20Sopenharmony_ci}/*-------------------------< PM_WSR_HANDLE >--------------------*/,{ 17238c2ecf20Sopenharmony_ci /* 17248c2ecf20Sopenharmony_ci * Phase mismatch handling from SCRIPT with WSR set. 17258c2ecf20Sopenharmony_ci * Such a condition can occur if the chip wants to 17268c2ecf20Sopenharmony_ci * execute a CHMOV(size > 1) when the WSR bit is 17278c2ecf20Sopenharmony_ci * set and the target changes PHASE. 17288c2ecf20Sopenharmony_ci * 17298c2ecf20Sopenharmony_ci * We must move the residual byte to memory. 17308c2ecf20Sopenharmony_ci * 17318c2ecf20Sopenharmony_ci * UA contains bit 0..31 of the address to 17328c2ecf20Sopenharmony_ci * move the residual byte. 17338c2ecf20Sopenharmony_ci * Move it to the table indirect. 17348c2ecf20Sopenharmony_ci */ 17358c2ecf20Sopenharmony_ci SCR_STORE_REL (ua, 4), 17368c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.wresid.addr), 17378c2ecf20Sopenharmony_ci /* 17388c2ecf20Sopenharmony_ci * Increment UA (move address to next position). 17398c2ecf20Sopenharmony_ci */ 17408c2ecf20Sopenharmony_ci SCR_REG_REG (ua, SCR_ADD, 1), 17418c2ecf20Sopenharmony_ci 0, 17428c2ecf20Sopenharmony_ci SCR_REG_REG (ua1, SCR_ADDC, 0), 17438c2ecf20Sopenharmony_ci 0, 17448c2ecf20Sopenharmony_ci SCR_REG_REG (ua2, SCR_ADDC, 0), 17458c2ecf20Sopenharmony_ci 0, 17468c2ecf20Sopenharmony_ci SCR_REG_REG (ua3, SCR_ADDC, 0), 17478c2ecf20Sopenharmony_ci 0, 17488c2ecf20Sopenharmony_ci /* 17498c2ecf20Sopenharmony_ci * Compute SCRATCHA as: 17508c2ecf20Sopenharmony_ci * - size to transfer = 1 byte. 17518c2ecf20Sopenharmony_ci * - bit 24..31 = high address bit [32...39]. 17528c2ecf20Sopenharmony_ci */ 17538c2ecf20Sopenharmony_ci SCR_LOAD_ABS (scratcha, 4), 17548c2ecf20Sopenharmony_ci PADDR_B (zero), 17558c2ecf20Sopenharmony_ci SCR_REG_REG (scratcha, SCR_OR, 1), 17568c2ecf20Sopenharmony_ci 0, 17578c2ecf20Sopenharmony_ci SCR_FROM_REG (rbc3), 17588c2ecf20Sopenharmony_ci 0, 17598c2ecf20Sopenharmony_ci SCR_TO_REG (scratcha3), 17608c2ecf20Sopenharmony_ci 0, 17618c2ecf20Sopenharmony_ci /* 17628c2ecf20Sopenharmony_ci * Move this value to the table indirect. 17638c2ecf20Sopenharmony_ci */ 17648c2ecf20Sopenharmony_ci SCR_STORE_REL (scratcha, 4), 17658c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.wresid.size), 17668c2ecf20Sopenharmony_ci /* 17678c2ecf20Sopenharmony_ci * Wait for a valid phase. 17688c2ecf20Sopenharmony_ci * While testing with bogus QUANTUM drives, the C1010 17698c2ecf20Sopenharmony_ci * sometimes raised a spurious phase mismatch with 17708c2ecf20Sopenharmony_ci * WSR and the CHMOV(1) triggered another PM. 17718c2ecf20Sopenharmony_ci * Waiting explicitly for the PHASE seemed to avoid 17728c2ecf20Sopenharmony_ci * the nested phase mismatch. Btw, this didn't happen 17738c2ecf20Sopenharmony_ci * using my IBM drives. 17748c2ecf20Sopenharmony_ci */ 17758c2ecf20Sopenharmony_ci SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)), 17768c2ecf20Sopenharmony_ci 0, 17778c2ecf20Sopenharmony_ci /* 17788c2ecf20Sopenharmony_ci * Perform the move of the residual byte. 17798c2ecf20Sopenharmony_ci */ 17808c2ecf20Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 17818c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.wresid), 17828c2ecf20Sopenharmony_ci /* 17838c2ecf20Sopenharmony_ci * We can now handle the phase mismatch with UA fixed. 17848c2ecf20Sopenharmony_ci * RBC[0..23]=0 is a special case that does not require 17858c2ecf20Sopenharmony_ci * a PM context. The C code also checks against this. 17868c2ecf20Sopenharmony_ci */ 17878c2ecf20Sopenharmony_ci SCR_FROM_REG (rbc), 17888c2ecf20Sopenharmony_ci 0, 17898c2ecf20Sopenharmony_ci SCR_RETURN ^ IFFALSE (DATA (0)), 17908c2ecf20Sopenharmony_ci 0, 17918c2ecf20Sopenharmony_ci SCR_FROM_REG (rbc1), 17928c2ecf20Sopenharmony_ci 0, 17938c2ecf20Sopenharmony_ci SCR_RETURN ^ IFFALSE (DATA (0)), 17948c2ecf20Sopenharmony_ci 0, 17958c2ecf20Sopenharmony_ci SCR_FROM_REG (rbc2), 17968c2ecf20Sopenharmony_ci 0, 17978c2ecf20Sopenharmony_ci SCR_RETURN ^ IFFALSE (DATA (0)), 17988c2ecf20Sopenharmony_ci 0, 17998c2ecf20Sopenharmony_ci /* 18008c2ecf20Sopenharmony_ci * RBC[0..23]=0. 18018c2ecf20Sopenharmony_ci * Not only we donnot need a PM context, but this would 18028c2ecf20Sopenharmony_ci * lead to a bogus CHMOV(0). This condition means that 18038c2ecf20Sopenharmony_ci * the residual was the last byte to move from this CHMOV. 18048c2ecf20Sopenharmony_ci * So, we just have to move the current data script pointer 18058c2ecf20Sopenharmony_ci * (i.e. TEMP) to the SCRIPTS address following the 18068c2ecf20Sopenharmony_ci * interrupted CHMOV and jump to dispatcher. 18078c2ecf20Sopenharmony_ci * IA contains the data pointer to save. 18088c2ecf20Sopenharmony_ci */ 18098c2ecf20Sopenharmony_ci SCR_JUMP, 18108c2ecf20Sopenharmony_ci PADDR_B (pm_save_end), 18118c2ecf20Sopenharmony_ci}/*-------------------------< WSR_MA_HELPER >--------------------*/,{ 18128c2ecf20Sopenharmony_ci /* 18138c2ecf20Sopenharmony_ci * Helper for the C code when WSR bit is set. 18148c2ecf20Sopenharmony_ci * Perform the move of the residual byte. 18158c2ecf20Sopenharmony_ci */ 18168c2ecf20Sopenharmony_ci SCR_CHMOV_TBL ^ SCR_DATA_IN, 18178c2ecf20Sopenharmony_ci offsetof (struct sym_ccb, phys.wresid), 18188c2ecf20Sopenharmony_ci SCR_JUMP, 18198c2ecf20Sopenharmony_ci PADDR_A (dispatch), 18208c2ecf20Sopenharmony_ci 18218c2ecf20Sopenharmony_ci}/*-------------------------< ZERO >-----------------------------*/,{ 18228c2ecf20Sopenharmony_ci SCR_DATA_ZERO, 18238c2ecf20Sopenharmony_ci}/*-------------------------< SCRATCH >--------------------------*/,{ 18248c2ecf20Sopenharmony_ci SCR_DATA_ZERO, 18258c2ecf20Sopenharmony_ci}/*-------------------------< PM0_DATA_ADDR >--------------------*/,{ 18268c2ecf20Sopenharmony_ci SCR_DATA_ZERO, 18278c2ecf20Sopenharmony_ci}/*-------------------------< PM1_DATA_ADDR >--------------------*/,{ 18288c2ecf20Sopenharmony_ci SCR_DATA_ZERO, 18298c2ecf20Sopenharmony_ci}/*-------------------------< DONE_POS >-------------------------*/,{ 18308c2ecf20Sopenharmony_ci SCR_DATA_ZERO, 18318c2ecf20Sopenharmony_ci}/*-------------------------< STARTPOS >-------------------------*/,{ 18328c2ecf20Sopenharmony_ci SCR_DATA_ZERO, 18338c2ecf20Sopenharmony_ci}/*-------------------------< TARGTBL >--------------------------*/,{ 18348c2ecf20Sopenharmony_ci SCR_DATA_ZERO, 18358c2ecf20Sopenharmony_ci}/*-------------------------<>-----------------------------------*/ 18368c2ecf20Sopenharmony_ci}; 18378c2ecf20Sopenharmony_ci 18388c2ecf20Sopenharmony_cistatic struct SYM_FWZ_SCR SYM_FWZ_SCR = { 18398c2ecf20Sopenharmony_ci /*-------------------------< SNOOPTEST >------------------------*/{ 18408c2ecf20Sopenharmony_ci /* 18418c2ecf20Sopenharmony_ci * Read the variable from memory. 18428c2ecf20Sopenharmony_ci */ 18438c2ecf20Sopenharmony_ci SCR_LOAD_REL (scratcha, 4), 18448c2ecf20Sopenharmony_ci offsetof(struct sym_hcb, scratch), 18458c2ecf20Sopenharmony_ci /* 18468c2ecf20Sopenharmony_ci * Write the variable to memory. 18478c2ecf20Sopenharmony_ci */ 18488c2ecf20Sopenharmony_ci SCR_STORE_REL (temp, 4), 18498c2ecf20Sopenharmony_ci offsetof(struct sym_hcb, scratch), 18508c2ecf20Sopenharmony_ci /* 18518c2ecf20Sopenharmony_ci * Read back the variable from memory. 18528c2ecf20Sopenharmony_ci */ 18538c2ecf20Sopenharmony_ci SCR_LOAD_REL (temp, 4), 18548c2ecf20Sopenharmony_ci offsetof(struct sym_hcb, scratch), 18558c2ecf20Sopenharmony_ci}/*-------------------------< SNOOPEND >-------------------------*/,{ 18568c2ecf20Sopenharmony_ci /* 18578c2ecf20Sopenharmony_ci * And stop. 18588c2ecf20Sopenharmony_ci */ 18598c2ecf20Sopenharmony_ci SCR_INT, 18608c2ecf20Sopenharmony_ci 99, 18618c2ecf20Sopenharmony_ci}/*-------------------------<>-----------------------------------*/ 18628c2ecf20Sopenharmony_ci}; 1863