1*1a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 41da177e4SLinus Torvalds * of PCI-SCSI IO processors. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * This driver is derived from the Linux sym53c8xx driver. 91da177e4SLinus Torvalds * Copyright (C) 1998-2000 Gerard Roudier 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 121da177e4SLinus Torvalds * a port of the FreeBSD ncr driver to Linux-1.2.13. 131da177e4SLinus Torvalds * 141da177e4SLinus Torvalds * The original ncr driver has been written for 386bsd and FreeBSD by 151da177e4SLinus Torvalds * Wolfgang Stanglmeier <wolf@cologne.de> 161da177e4SLinus Torvalds * Stefan Esser <se@mi.Uni-Koeln.de> 171da177e4SLinus Torvalds * Copyright (C) 1994 Wolfgang Stanglmeier 181da177e4SLinus Torvalds * 191da177e4SLinus Torvalds * Other major contributions: 201da177e4SLinus Torvalds * 211da177e4SLinus Torvalds * NVRAM detection and reading. 221da177e4SLinus Torvalds * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 231da177e4SLinus Torvalds * 241da177e4SLinus Torvalds *----------------------------------------------------------------------------- 251da177e4SLinus Torvalds */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds /* 281da177e4SLinus Torvalds * Scripts for SYMBIOS-Processor 291da177e4SLinus Torvalds * 301da177e4SLinus Torvalds * We have to know the offsets of all labels before we reach 311da177e4SLinus Torvalds * them (for forward jumps). Therefore we declare a struct 321da177e4SLinus Torvalds * here. If you make changes inside the script, 331da177e4SLinus Torvalds * 341da177e4SLinus Torvalds * DONT FORGET TO CHANGE THE LENGTHS HERE! 351da177e4SLinus Torvalds */ 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds /* 381da177e4SLinus Torvalds * Script fragments which are loaded into the on-chip RAM 391da177e4SLinus Torvalds * of 825A, 875, 876, 895, 895A, 896 and 1010 chips. 401da177e4SLinus Torvalds * Must not exceed 4K bytes. 411da177e4SLinus Torvalds */ 421da177e4SLinus Torvalds struct SYM_FWA_SCR { 431da177e4SLinus Torvalds u32 start [ 14]; 441da177e4SLinus Torvalds u32 getjob_begin [ 4]; 451da177e4SLinus Torvalds u32 getjob_end [ 4]; 461da177e4SLinus Torvalds #ifdef SYM_CONF_TARGET_ROLE_SUPPORT 471da177e4SLinus Torvalds u32 select [ 6]; 481da177e4SLinus Torvalds #else 491da177e4SLinus Torvalds u32 select [ 4]; 501da177e4SLinus Torvalds #endif 511da177e4SLinus Torvalds #if SYM_CONF_DMA_ADDRESSING_MODE == 2 521da177e4SLinus Torvalds u32 is_dmap_dirty [ 4]; 531da177e4SLinus Torvalds #endif 541da177e4SLinus Torvalds u32 wf_sel_done [ 2]; 551da177e4SLinus Torvalds u32 sel_done [ 2]; 561da177e4SLinus Torvalds u32 send_ident [ 2]; 571da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 581da177e4SLinus Torvalds u32 select2 [ 8]; 591da177e4SLinus Torvalds #else 601da177e4SLinus Torvalds u32 select2 [ 2]; 611da177e4SLinus Torvalds #endif 621da177e4SLinus Torvalds u32 command [ 2]; 631da177e4SLinus Torvalds u32 dispatch [ 28]; 641da177e4SLinus Torvalds u32 sel_no_cmd [ 10]; 651da177e4SLinus Torvalds u32 init [ 6]; 661da177e4SLinus Torvalds u32 clrack [ 4]; 671da177e4SLinus Torvalds u32 datai_done [ 10]; 681da177e4SLinus Torvalds u32 datai_done_wsr [ 20]; 691da177e4SLinus Torvalds u32 datao_done [ 10]; 701da177e4SLinus Torvalds u32 datao_done_wss [ 6]; 711da177e4SLinus Torvalds u32 datai_phase [ 4]; 721da177e4SLinus Torvalds u32 datao_phase [ 6]; 731da177e4SLinus Torvalds u32 msg_in [ 2]; 741da177e4SLinus Torvalds u32 msg_in2 [ 10]; 751da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 761da177e4SLinus Torvalds u32 status [ 14]; 771da177e4SLinus Torvalds #else 781da177e4SLinus Torvalds u32 status [ 10]; 791da177e4SLinus Torvalds #endif 801da177e4SLinus Torvalds u32 complete [ 6]; 811da177e4SLinus Torvalds u32 complete2 [ 12]; 821da177e4SLinus Torvalds u32 done [ 14]; 831da177e4SLinus Torvalds u32 done_end [ 2]; 841da177e4SLinus Torvalds u32 complete_error [ 4]; 851da177e4SLinus Torvalds u32 save_dp [ 12]; 861da177e4SLinus Torvalds u32 restore_dp [ 8]; 871da177e4SLinus Torvalds u32 disconnect [ 12]; 881da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 891da177e4SLinus Torvalds u32 idle [ 4]; 901da177e4SLinus Torvalds #else 911da177e4SLinus Torvalds u32 idle [ 2]; 921da177e4SLinus Torvalds #endif 931da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 941da177e4SLinus Torvalds u32 ungetjob [ 6]; 951da177e4SLinus Torvalds #else 961da177e4SLinus Torvalds u32 ungetjob [ 4]; 971da177e4SLinus Torvalds #endif 981da177e4SLinus Torvalds #ifdef SYM_CONF_TARGET_ROLE_SUPPORT 991da177e4SLinus Torvalds u32 reselect [ 4]; 1001da177e4SLinus Torvalds #else 1011da177e4SLinus Torvalds u32 reselect [ 2]; 1021da177e4SLinus Torvalds #endif 1031da177e4SLinus Torvalds u32 reselected [ 22]; 1041da177e4SLinus Torvalds u32 resel_scntl4 [ 20]; 1051da177e4SLinus Torvalds u32 resel_lun0 [ 6]; 1061da177e4SLinus Torvalds #if SYM_CONF_MAX_TASK*4 > 512 1071da177e4SLinus Torvalds u32 resel_tag [ 26]; 1081da177e4SLinus Torvalds #elif SYM_CONF_MAX_TASK*4 > 256 1091da177e4SLinus Torvalds u32 resel_tag [ 20]; 1101da177e4SLinus Torvalds #else 1111da177e4SLinus Torvalds u32 resel_tag [ 16]; 1121da177e4SLinus Torvalds #endif 1131da177e4SLinus Torvalds u32 resel_dsa [ 2]; 1141da177e4SLinus Torvalds u32 resel_dsa1 [ 4]; 1151da177e4SLinus Torvalds u32 resel_no_tag [ 6]; 1161da177e4SLinus Torvalds u32 data_in [SYM_CONF_MAX_SG * 2]; 1171da177e4SLinus Torvalds u32 data_in2 [ 4]; 1181da177e4SLinus Torvalds u32 data_out [SYM_CONF_MAX_SG * 2]; 1191da177e4SLinus Torvalds u32 data_out2 [ 4]; 1201da177e4SLinus Torvalds u32 pm0_data [ 12]; 1211da177e4SLinus Torvalds u32 pm0_data_out [ 6]; 1221da177e4SLinus Torvalds u32 pm0_data_end [ 6]; 1231da177e4SLinus Torvalds u32 pm1_data [ 12]; 1241da177e4SLinus Torvalds u32 pm1_data_out [ 6]; 1251da177e4SLinus Torvalds u32 pm1_data_end [ 6]; 1261da177e4SLinus Torvalds }; 1271da177e4SLinus Torvalds 1281da177e4SLinus Torvalds /* 1291da177e4SLinus Torvalds * Script fragments which stay in main memory for all chips 1301da177e4SLinus Torvalds * except for chips that support 8K on-chip RAM. 1311da177e4SLinus Torvalds */ 1321da177e4SLinus Torvalds struct SYM_FWB_SCR { 1331da177e4SLinus Torvalds u32 start64 [ 2]; 1341da177e4SLinus Torvalds u32 no_data [ 2]; 1351da177e4SLinus Torvalds #ifdef SYM_CONF_TARGET_ROLE_SUPPORT 1361da177e4SLinus Torvalds u32 sel_for_abort [ 18]; 1371da177e4SLinus Torvalds #else 1381da177e4SLinus Torvalds u32 sel_for_abort [ 16]; 1391da177e4SLinus Torvalds #endif 1401da177e4SLinus Torvalds u32 sel_for_abort_1 [ 2]; 1411da177e4SLinus Torvalds u32 msg_in_etc [ 12]; 1421da177e4SLinus Torvalds u32 msg_received [ 4]; 1431da177e4SLinus Torvalds u32 msg_weird_seen [ 4]; 1441da177e4SLinus Torvalds u32 msg_extended [ 20]; 1451da177e4SLinus Torvalds u32 msg_bad [ 6]; 1461da177e4SLinus Torvalds u32 msg_weird [ 4]; 1471da177e4SLinus Torvalds u32 msg_weird1 [ 8]; 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds u32 wdtr_resp [ 6]; 1501da177e4SLinus Torvalds u32 send_wdtr [ 4]; 1511da177e4SLinus Torvalds u32 sdtr_resp [ 6]; 1521da177e4SLinus Torvalds u32 send_sdtr [ 4]; 1531da177e4SLinus Torvalds u32 ppr_resp [ 6]; 1541da177e4SLinus Torvalds u32 send_ppr [ 4]; 1551da177e4SLinus Torvalds u32 nego_bad_phase [ 4]; 1561da177e4SLinus Torvalds u32 msg_out [ 4]; 1571da177e4SLinus Torvalds u32 msg_out_done [ 4]; 1581da177e4SLinus Torvalds u32 data_ovrun [ 2]; 1591da177e4SLinus Torvalds u32 data_ovrun1 [ 22]; 1601da177e4SLinus Torvalds u32 data_ovrun2 [ 8]; 1611da177e4SLinus Torvalds u32 abort_resel [ 16]; 1621da177e4SLinus Torvalds u32 resend_ident [ 4]; 1631da177e4SLinus Torvalds u32 ident_break [ 4]; 1641da177e4SLinus Torvalds u32 ident_break_atn [ 4]; 1651da177e4SLinus Torvalds u32 sdata_in [ 6]; 1661da177e4SLinus Torvalds u32 resel_bad_lun [ 4]; 1671da177e4SLinus Torvalds u32 bad_i_t_l [ 4]; 1681da177e4SLinus Torvalds u32 bad_i_t_l_q [ 4]; 1691da177e4SLinus Torvalds u32 bad_status [ 6]; 1701da177e4SLinus Torvalds u32 pm_handle [ 20]; 1711da177e4SLinus Torvalds u32 pm_handle1 [ 4]; 1721da177e4SLinus Torvalds u32 pm_save [ 4]; 1731da177e4SLinus Torvalds u32 pm0_save [ 12]; 1741da177e4SLinus Torvalds u32 pm_save_end [ 4]; 1751da177e4SLinus Torvalds u32 pm1_save [ 14]; 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds /* WSR handling */ 1781da177e4SLinus Torvalds u32 pm_wsr_handle [ 38]; 1791da177e4SLinus Torvalds u32 wsr_ma_helper [ 4]; 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds /* Data area */ 1821da177e4SLinus Torvalds u32 zero [ 1]; 1831da177e4SLinus Torvalds u32 scratch [ 1]; 1841da177e4SLinus Torvalds u32 pm0_data_addr [ 1]; 1851da177e4SLinus Torvalds u32 pm1_data_addr [ 1]; 1861da177e4SLinus Torvalds u32 done_pos [ 1]; 1871da177e4SLinus Torvalds u32 startpos [ 1]; 1881da177e4SLinus Torvalds u32 targtbl [ 1]; 1891da177e4SLinus Torvalds }; 1901da177e4SLinus Torvalds 1911da177e4SLinus Torvalds /* 1921da177e4SLinus Torvalds * Script fragments used at initialisations. 1931da177e4SLinus Torvalds * Only runs out of main memory. 1941da177e4SLinus Torvalds */ 1951da177e4SLinus Torvalds struct SYM_FWZ_SCR { 1961da177e4SLinus Torvalds u32 snooptest [ 6]; 1971da177e4SLinus Torvalds u32 snoopend [ 2]; 1981da177e4SLinus Torvalds }; 1991da177e4SLinus Torvalds 2001da177e4SLinus Torvalds static struct SYM_FWA_SCR SYM_FWA_SCR = { 2011da177e4SLinus Torvalds /*--------------------------< START >----------------------------*/ { 2021da177e4SLinus Torvalds /* 2031da177e4SLinus Torvalds * Switch the LED on. 2041da177e4SLinus Torvalds * Will be patched with a NO_OP if LED 2051da177e4SLinus Torvalds * not needed or not desired. 2061da177e4SLinus Torvalds */ 2071da177e4SLinus Torvalds SCR_REG_REG (gpreg, SCR_AND, 0xfe), 2081da177e4SLinus Torvalds 0, 2091da177e4SLinus Torvalds /* 2101da177e4SLinus Torvalds * Clear SIGP. 2111da177e4SLinus Torvalds */ 2121da177e4SLinus Torvalds SCR_FROM_REG (ctest2), 2131da177e4SLinus Torvalds 0, 2141da177e4SLinus Torvalds /* 2151da177e4SLinus Torvalds * Stop here if the C code wants to perform 2161da177e4SLinus Torvalds * some error recovery procedure manually. 2171da177e4SLinus Torvalds * (Indicate this by setting SEM in ISTAT) 2181da177e4SLinus Torvalds */ 2191da177e4SLinus Torvalds SCR_FROM_REG (istat), 2201da177e4SLinus Torvalds 0, 2211da177e4SLinus Torvalds /* 2221da177e4SLinus Torvalds * Report to the C code the next position in 2231da177e4SLinus Torvalds * the start queue the SCRIPTS will schedule. 2241da177e4SLinus Torvalds * The C code must not change SCRATCHA. 2251da177e4SLinus Torvalds */ 2261da177e4SLinus Torvalds SCR_LOAD_ABS (scratcha, 4), 2271da177e4SLinus Torvalds PADDR_B (startpos), 2281da177e4SLinus Torvalds SCR_INT ^ IFTRUE (MASK (SEM, SEM)), 2291da177e4SLinus Torvalds SIR_SCRIPT_STOPPED, 2301da177e4SLinus Torvalds /* 2311da177e4SLinus Torvalds * Start the next job. 2321da177e4SLinus Torvalds * 2331da177e4SLinus Torvalds * @DSA = start point for this job. 2341da177e4SLinus Torvalds * SCRATCHA = address of this job in the start queue. 2351da177e4SLinus Torvalds * 2361da177e4SLinus Torvalds * We will restore startpos with SCRATCHA if we fails the 2371da177e4SLinus Torvalds * arbitration or if it is the idle job. 2381da177e4SLinus Torvalds * 2391da177e4SLinus Torvalds * The below GETJOB_BEGIN to GETJOB_END section of SCRIPTS 2401da177e4SLinus Torvalds * is a critical path. If it is partially executed, it then 2411da177e4SLinus Torvalds * may happen that the job address is not yet in the DSA 2421da177e4SLinus Torvalds * and the next queue position points to the next JOB. 2431da177e4SLinus Torvalds */ 2441da177e4SLinus Torvalds SCR_LOAD_ABS (dsa, 4), 2451da177e4SLinus Torvalds PADDR_B (startpos), 2461da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 2471da177e4SLinus Torvalds 4, 2481da177e4SLinus Torvalds }/*-------------------------< GETJOB_BEGIN >---------------------*/,{ 2491da177e4SLinus Torvalds SCR_STORE_ABS (temp, 4), 2501da177e4SLinus Torvalds PADDR_B (startpos), 2511da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 2521da177e4SLinus Torvalds 0, 2531da177e4SLinus Torvalds }/*-------------------------< GETJOB_END >-----------------------*/,{ 2541da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 2551da177e4SLinus Torvalds 0, 2561da177e4SLinus Torvalds SCR_RETURN, 2571da177e4SLinus Torvalds 0, 2581da177e4SLinus Torvalds }/*-------------------------< SELECT >---------------------------*/,{ 2591da177e4SLinus Torvalds /* 2601da177e4SLinus Torvalds * DSA contains the address of a scheduled 2611da177e4SLinus Torvalds * data structure. 2621da177e4SLinus Torvalds * 2631da177e4SLinus Torvalds * SCRATCHA contains the address of the start queue 2641da177e4SLinus Torvalds * entry which points to the next job. 2651da177e4SLinus Torvalds * 2661da177e4SLinus Torvalds * Set Initiator mode. 2671da177e4SLinus Torvalds * 2681da177e4SLinus Torvalds * (Target mode is left as an exercise for the reader) 2691da177e4SLinus Torvalds */ 2701da177e4SLinus Torvalds #ifdef SYM_CONF_TARGET_ROLE_SUPPORT 2711da177e4SLinus Torvalds SCR_CLR (SCR_TRG), 2721da177e4SLinus Torvalds 0, 2731da177e4SLinus Torvalds #endif 2741da177e4SLinus Torvalds /* 2751da177e4SLinus Torvalds * And try to select this target. 2761da177e4SLinus Torvalds */ 2771da177e4SLinus Torvalds SCR_SEL_TBL_ATN ^ offsetof (struct sym_dsb, select), 2781da177e4SLinus Torvalds PADDR_A (ungetjob), 2791da177e4SLinus Torvalds /* 2801da177e4SLinus Torvalds * Now there are 4 possibilities: 2811da177e4SLinus Torvalds * 2821da177e4SLinus Torvalds * (1) The chip loses arbitration. 2831da177e4SLinus Torvalds * This is ok, because it will try again, 2841da177e4SLinus Torvalds * when the bus becomes idle. 2851da177e4SLinus Torvalds * (But beware of the timeout function!) 2861da177e4SLinus Torvalds * 2871da177e4SLinus Torvalds * (2) The chip is reselected. 2881da177e4SLinus Torvalds * Then the script processor takes the jump 2891da177e4SLinus Torvalds * to the RESELECT label. 2901da177e4SLinus Torvalds * 2911da177e4SLinus Torvalds * (3) The chip wins arbitration. 2921da177e4SLinus Torvalds * Then it will execute SCRIPTS instruction until 2931da177e4SLinus Torvalds * the next instruction that checks SCSI phase. 2941da177e4SLinus Torvalds * Then will stop and wait for selection to be 2951da177e4SLinus Torvalds * complete or selection time-out to occur. 2961da177e4SLinus Torvalds * 2971da177e4SLinus Torvalds * After having won arbitration, the SCRIPTS 2981da177e4SLinus Torvalds * processor is able to execute instructions while 2991da177e4SLinus Torvalds * the SCSI core is performing SCSI selection. 3001da177e4SLinus Torvalds */ 3011da177e4SLinus Torvalds /* 3021da177e4SLinus Torvalds * Initialize the status registers 3031da177e4SLinus Torvalds */ 3041da177e4SLinus Torvalds SCR_LOAD_REL (scr0, 4), 3051da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.status), 3061da177e4SLinus Torvalds /* 3071da177e4SLinus Torvalds * We may need help from CPU if the DMA segment 3081da177e4SLinus Torvalds * registers aren't up-to-date for this IO. 3091da177e4SLinus Torvalds * Patched with NOOP for chips that donnot 3101da177e4SLinus Torvalds * support DAC addressing. 3111da177e4SLinus Torvalds */ 3121da177e4SLinus Torvalds #if SYM_CONF_DMA_ADDRESSING_MODE == 2 3131da177e4SLinus Torvalds }/*-------------------------< IS_DMAP_DIRTY >--------------------*/,{ 3141da177e4SLinus Torvalds SCR_FROM_REG (HX_REG), 3151da177e4SLinus Torvalds 0, 3161da177e4SLinus Torvalds SCR_INT ^ IFTRUE (MASK (HX_DMAP_DIRTY, HX_DMAP_DIRTY)), 3171da177e4SLinus Torvalds SIR_DMAP_DIRTY, 3181da177e4SLinus Torvalds #endif 3191da177e4SLinus Torvalds }/*-------------------------< WF_SEL_DONE >----------------------*/,{ 3201da177e4SLinus Torvalds SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), 3211da177e4SLinus Torvalds SIR_SEL_ATN_NO_MSG_OUT, 3221da177e4SLinus Torvalds }/*-------------------------< SEL_DONE >-------------------------*/,{ 3231da177e4SLinus Torvalds /* 3241da177e4SLinus Torvalds * C1010-33 errata work-around. 3251da177e4SLinus Torvalds * Due to a race, the SCSI core may not have 3261da177e4SLinus Torvalds * loaded SCNTL3 on SEL_TBL instruction. 3271da177e4SLinus Torvalds * We reload it once phase is stable. 3281da177e4SLinus Torvalds * Patched with a NOOP for other chips. 3291da177e4SLinus Torvalds */ 3301da177e4SLinus Torvalds SCR_LOAD_REL (scntl3, 1), 3311da177e4SLinus Torvalds offsetof(struct sym_dsb, select.sel_scntl3), 3321da177e4SLinus Torvalds }/*-------------------------< SEND_IDENT >-----------------------*/,{ 3331da177e4SLinus Torvalds /* 3341da177e4SLinus Torvalds * Selection complete. 3351da177e4SLinus Torvalds * Send the IDENTIFY and possibly the TAG message 3361da177e4SLinus Torvalds * and negotiation message if present. 3371da177e4SLinus Torvalds */ 3381da177e4SLinus Torvalds SCR_MOVE_TBL ^ SCR_MSG_OUT, 3391da177e4SLinus Torvalds offsetof (struct sym_dsb, smsg), 3401da177e4SLinus Torvalds }/*-------------------------< SELECT2 >--------------------------*/,{ 3411da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 3421da177e4SLinus Torvalds /* 3431da177e4SLinus Torvalds * Set IMMEDIATE ARBITRATION if we have been given 3441da177e4SLinus Torvalds * a hint to do so. (Some job to do after this one). 3451da177e4SLinus Torvalds */ 3461da177e4SLinus Torvalds SCR_FROM_REG (HF_REG), 3471da177e4SLinus Torvalds 0, 3481da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (MASK (HF_HINT_IARB, HF_HINT_IARB)), 3491da177e4SLinus Torvalds 8, 3501da177e4SLinus Torvalds SCR_REG_REG (scntl1, SCR_OR, IARB), 3511da177e4SLinus Torvalds 0, 3521da177e4SLinus Torvalds #endif 3531da177e4SLinus Torvalds /* 3541da177e4SLinus Torvalds * Anticipate the COMMAND phase. 3551da177e4SLinus Torvalds * This is the PHASE we expect at this point. 3561da177e4SLinus Torvalds */ 3571da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_COMMAND)), 3581da177e4SLinus Torvalds PADDR_A (sel_no_cmd), 3591da177e4SLinus Torvalds }/*-------------------------< COMMAND >--------------------------*/,{ 3601da177e4SLinus Torvalds /* 3611da177e4SLinus Torvalds * ... and send the command 3621da177e4SLinus Torvalds */ 3631da177e4SLinus Torvalds SCR_MOVE_TBL ^ SCR_COMMAND, 3641da177e4SLinus Torvalds offsetof (struct sym_dsb, cmd), 3651da177e4SLinus Torvalds }/*-------------------------< DISPATCH >-------------------------*/,{ 3661da177e4SLinus Torvalds /* 3671da177e4SLinus Torvalds * MSG_IN is the only phase that shall be 3681da177e4SLinus Torvalds * entered at least once for each (re)selection. 3691da177e4SLinus Torvalds * So we test it first. 3701da177e4SLinus Torvalds */ 3711da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 3721da177e4SLinus Torvalds PADDR_A (msg_in), 3731da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)), 3741da177e4SLinus Torvalds PADDR_A (datao_phase), 3751da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)), 3761da177e4SLinus Torvalds PADDR_A (datai_phase), 3771da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)), 3781da177e4SLinus Torvalds PADDR_A (status), 3791da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)), 3801da177e4SLinus Torvalds PADDR_A (command), 3811da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)), 3821da177e4SLinus Torvalds PADDR_B (msg_out), 3831da177e4SLinus Torvalds /* 3841da177e4SLinus Torvalds * Discard as many illegal phases as 3851da177e4SLinus Torvalds * required and tell the C code about. 3861da177e4SLinus Torvalds */ 3871da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_OUT)), 3881da177e4SLinus Torvalds 16, 3891da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_ILG_OUT, 3901da177e4SLinus Torvalds HADDR_1 (scratch), 3911da177e4SLinus Torvalds SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_OUT)), 3921da177e4SLinus Torvalds -16, 3931da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_IN)), 3941da177e4SLinus Torvalds 16, 3951da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_ILG_IN, 3961da177e4SLinus Torvalds HADDR_1 (scratch), 3971da177e4SLinus Torvalds SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_IN)), 3981da177e4SLinus Torvalds -16, 3991da177e4SLinus Torvalds SCR_INT, 4001da177e4SLinus Torvalds SIR_BAD_PHASE, 4011da177e4SLinus Torvalds SCR_JUMP, 4021da177e4SLinus Torvalds PADDR_A (dispatch), 4031da177e4SLinus Torvalds }/*-------------------------< SEL_NO_CMD >-----------------------*/,{ 4041da177e4SLinus Torvalds /* 4051da177e4SLinus Torvalds * The target does not switch to command 4061da177e4SLinus Torvalds * phase after IDENTIFY has been sent. 4071da177e4SLinus Torvalds * 4081da177e4SLinus Torvalds * If it stays in MSG OUT phase send it 4091da177e4SLinus Torvalds * the IDENTIFY again. 4101da177e4SLinus Torvalds */ 4111da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), 4121da177e4SLinus Torvalds PADDR_B (resend_ident), 4131da177e4SLinus Torvalds /* 4141da177e4SLinus Torvalds * If target does not switch to MSG IN phase 4151da177e4SLinus Torvalds * and we sent a negotiation, assert the 4161da177e4SLinus Torvalds * failure immediately. 4171da177e4SLinus Torvalds */ 4181da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 4191da177e4SLinus Torvalds PADDR_A (dispatch), 4201da177e4SLinus Torvalds SCR_FROM_REG (HS_REG), 4211da177e4SLinus Torvalds 0, 4221da177e4SLinus Torvalds SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), 4231da177e4SLinus Torvalds SIR_NEGO_FAILED, 4241da177e4SLinus Torvalds /* 4251da177e4SLinus Torvalds * Jump to dispatcher. 4261da177e4SLinus Torvalds */ 4271da177e4SLinus Torvalds SCR_JUMP, 4281da177e4SLinus Torvalds PADDR_A (dispatch), 4291da177e4SLinus Torvalds }/*-------------------------< INIT >-----------------------------*/,{ 4301da177e4SLinus Torvalds /* 4311da177e4SLinus Torvalds * Wait for the SCSI RESET signal to be 4321da177e4SLinus Torvalds * inactive before restarting operations, 4331da177e4SLinus Torvalds * since the chip may hang on SEL_ATN 4341da177e4SLinus Torvalds * if SCSI RESET is active. 4351da177e4SLinus Torvalds */ 4361da177e4SLinus Torvalds SCR_FROM_REG (sstat0), 4371da177e4SLinus Torvalds 0, 4381da177e4SLinus Torvalds SCR_JUMPR ^ IFTRUE (MASK (IRST, IRST)), 4391da177e4SLinus Torvalds -16, 4401da177e4SLinus Torvalds SCR_JUMP, 4411da177e4SLinus Torvalds PADDR_A (start), 4421da177e4SLinus Torvalds }/*-------------------------< CLRACK >---------------------------*/,{ 4431da177e4SLinus Torvalds /* 4441da177e4SLinus Torvalds * Terminate possible pending message phase. 4451da177e4SLinus Torvalds */ 4461da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 4471da177e4SLinus Torvalds 0, 4481da177e4SLinus Torvalds SCR_JUMP, 4491da177e4SLinus Torvalds PADDR_A (dispatch), 4501da177e4SLinus Torvalds }/*-------------------------< DATAI_DONE >-----------------------*/,{ 4511da177e4SLinus Torvalds /* 4521da177e4SLinus Torvalds * Save current pointer to LASTP. 4531da177e4SLinus Torvalds */ 4541da177e4SLinus Torvalds SCR_STORE_REL (temp, 4), 4551da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.lastp), 4561da177e4SLinus Torvalds /* 4571da177e4SLinus Torvalds * If the SWIDE is not full, jump to dispatcher. 4581da177e4SLinus Torvalds * We anticipate a STATUS phase. 4591da177e4SLinus Torvalds */ 4601da177e4SLinus Torvalds SCR_FROM_REG (scntl2), 4611da177e4SLinus Torvalds 0, 4621da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (WSR, WSR)), 4631da177e4SLinus Torvalds PADDR_A (datai_done_wsr), 4641da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)), 4651da177e4SLinus Torvalds PADDR_A (status), 4661da177e4SLinus Torvalds SCR_JUMP, 4671da177e4SLinus Torvalds PADDR_A (dispatch), 4681da177e4SLinus Torvalds }/*-------------------------< DATAI_DONE_WSR >-------------------*/,{ 4691da177e4SLinus Torvalds /* 4701da177e4SLinus Torvalds * The SWIDE is full. 4711da177e4SLinus Torvalds * Clear this condition. 4721da177e4SLinus Torvalds */ 4731da177e4SLinus Torvalds SCR_REG_REG (scntl2, SCR_OR, WSR), 4741da177e4SLinus Torvalds 0, 4751da177e4SLinus Torvalds /* 4761da177e4SLinus Torvalds * We are expecting an IGNORE RESIDUE message 4771da177e4SLinus Torvalds * from the device, otherwise we are in data 4781da177e4SLinus Torvalds * overrun condition. Check against MSG_IN phase. 4791da177e4SLinus Torvalds */ 4801da177e4SLinus Torvalds SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)), 4811da177e4SLinus Torvalds SIR_SWIDE_OVERRUN, 4821da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 4831da177e4SLinus Torvalds PADDR_A (dispatch), 4841da177e4SLinus Torvalds /* 4851da177e4SLinus Torvalds * We are in MSG_IN phase, 4861da177e4SLinus Torvalds * Read the first byte of the message. 4871da177e4SLinus Torvalds * If it is not an IGNORE RESIDUE message, 4881da177e4SLinus Torvalds * signal overrun and jump to message 4891da177e4SLinus Torvalds * processing. 4901da177e4SLinus Torvalds */ 4911da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 4921da177e4SLinus Torvalds HADDR_1 (msgin[0]), 4931da177e4SLinus Torvalds SCR_INT ^ IFFALSE (DATA (M_IGN_RESIDUE)), 4941da177e4SLinus Torvalds SIR_SWIDE_OVERRUN, 4951da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)), 4961da177e4SLinus Torvalds PADDR_A (msg_in2), 4971da177e4SLinus Torvalds /* 4981da177e4SLinus Torvalds * We got the message we expected. 4991da177e4SLinus Torvalds * Read the 2nd byte, and jump to dispatcher. 5001da177e4SLinus Torvalds */ 5011da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 5021da177e4SLinus Torvalds 0, 5031da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 5041da177e4SLinus Torvalds HADDR_1 (msgin[1]), 5051da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 5061da177e4SLinus Torvalds 0, 5071da177e4SLinus Torvalds SCR_JUMP, 5081da177e4SLinus Torvalds PADDR_A (dispatch), 5091da177e4SLinus Torvalds }/*-------------------------< DATAO_DONE >-----------------------*/,{ 5101da177e4SLinus Torvalds /* 5111da177e4SLinus Torvalds * Save current pointer to LASTP. 5121da177e4SLinus Torvalds */ 5131da177e4SLinus Torvalds SCR_STORE_REL (temp, 4), 5141da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.lastp), 5151da177e4SLinus Torvalds /* 5161da177e4SLinus Torvalds * If the SODL is not full jump to dispatcher. 5171da177e4SLinus Torvalds * We anticipate a STATUS phase. 5181da177e4SLinus Torvalds */ 5191da177e4SLinus Torvalds SCR_FROM_REG (scntl2), 5201da177e4SLinus Torvalds 0, 5211da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (WSS, WSS)), 5221da177e4SLinus Torvalds PADDR_A (datao_done_wss), 5231da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)), 5241da177e4SLinus Torvalds PADDR_A (status), 5251da177e4SLinus Torvalds SCR_JUMP, 5261da177e4SLinus Torvalds PADDR_A (dispatch), 5271da177e4SLinus Torvalds }/*-------------------------< DATAO_DONE_WSS >-------------------*/,{ 5281da177e4SLinus Torvalds /* 5291da177e4SLinus Torvalds * The SODL is full, clear this condition. 5301da177e4SLinus Torvalds */ 5311da177e4SLinus Torvalds SCR_REG_REG (scntl2, SCR_OR, WSS), 5321da177e4SLinus Torvalds 0, 5331da177e4SLinus Torvalds /* 5341da177e4SLinus Torvalds * And signal a DATA UNDERRUN condition 5351da177e4SLinus Torvalds * to the C code. 5361da177e4SLinus Torvalds */ 5371da177e4SLinus Torvalds SCR_INT, 5381da177e4SLinus Torvalds SIR_SODL_UNDERRUN, 5391da177e4SLinus Torvalds SCR_JUMP, 5401da177e4SLinus Torvalds PADDR_A (dispatch), 5411da177e4SLinus Torvalds }/*-------------------------< DATAI_PHASE >----------------------*/,{ 5421da177e4SLinus Torvalds /* 5431da177e4SLinus Torvalds * Jump to current pointer. 5441da177e4SLinus Torvalds */ 5451da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 5461da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.lastp), 5471da177e4SLinus Torvalds SCR_RETURN, 5481da177e4SLinus Torvalds 0, 5491da177e4SLinus Torvalds }/*-------------------------< DATAO_PHASE >----------------------*/,{ 5501da177e4SLinus Torvalds /* 5511da177e4SLinus Torvalds * C1010-66 errata work-around. 5521da177e4SLinus Torvalds * Extra clocks of data hold must be inserted 5531da177e4SLinus Torvalds * in DATA OUT phase on 33 MHz PCI BUS. 5541da177e4SLinus Torvalds * Patched with a NOOP for other chips. 5551da177e4SLinus Torvalds */ 5561da177e4SLinus Torvalds SCR_REG_REG (scntl4, SCR_OR, (XCLKH_DT|XCLKH_ST)), 5571da177e4SLinus Torvalds 0, 5581da177e4SLinus Torvalds /* 5591da177e4SLinus Torvalds * Jump to current pointer. 5601da177e4SLinus Torvalds */ 5611da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 5621da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.lastp), 5631da177e4SLinus Torvalds SCR_RETURN, 5641da177e4SLinus Torvalds 0, 5651da177e4SLinus Torvalds }/*-------------------------< MSG_IN >---------------------------*/,{ 5661da177e4SLinus Torvalds /* 5671da177e4SLinus Torvalds * Get the first byte of the message. 5681da177e4SLinus Torvalds * 5691da177e4SLinus Torvalds * The script processor doesn't negate the 5701da177e4SLinus Torvalds * ACK signal after this transfer. 5711da177e4SLinus Torvalds */ 5721da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 5731da177e4SLinus Torvalds HADDR_1 (msgin[0]), 5741da177e4SLinus Torvalds }/*-------------------------< MSG_IN2 >--------------------------*/,{ 5751da177e4SLinus Torvalds /* 5761da177e4SLinus Torvalds * Check first against 1 byte messages 5771da177e4SLinus Torvalds * that we handle from SCRIPTS. 5781da177e4SLinus Torvalds */ 5791da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)), 5801da177e4SLinus Torvalds PADDR_A (complete), 5811da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)), 5821da177e4SLinus Torvalds PADDR_A (disconnect), 5831da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)), 5841da177e4SLinus Torvalds PADDR_A (save_dp), 5851da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)), 5861da177e4SLinus Torvalds PADDR_A (restore_dp), 5871da177e4SLinus Torvalds /* 5881da177e4SLinus Torvalds * We handle all other messages from the 5891da177e4SLinus Torvalds * C code, so no need to waste on-chip RAM 5901da177e4SLinus Torvalds * for those ones. 5911da177e4SLinus Torvalds */ 5921da177e4SLinus Torvalds SCR_JUMP, 5931da177e4SLinus Torvalds PADDR_B (msg_in_etc), 5941da177e4SLinus Torvalds }/*-------------------------< STATUS >---------------------------*/,{ 5951da177e4SLinus Torvalds /* 5961da177e4SLinus Torvalds * get the status 5971da177e4SLinus Torvalds */ 5981da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_STATUS, 5991da177e4SLinus Torvalds HADDR_1 (scratch), 6001da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 6011da177e4SLinus Torvalds /* 6021da177e4SLinus Torvalds * If STATUS is not GOOD, clear IMMEDIATE ARBITRATION, 6031da177e4SLinus Torvalds * since we may have to tamper the start queue from 6041da177e4SLinus Torvalds * the C code. 6051da177e4SLinus Torvalds */ 6061da177e4SLinus Torvalds SCR_JUMPR ^ IFTRUE (DATA (S_GOOD)), 6071da177e4SLinus Torvalds 8, 6081da177e4SLinus Torvalds SCR_REG_REG (scntl1, SCR_AND, ~IARB), 6091da177e4SLinus Torvalds 0, 6101da177e4SLinus Torvalds #endif 6111da177e4SLinus Torvalds /* 6121da177e4SLinus Torvalds * save status to scsi_status. 6131da177e4SLinus Torvalds * mark as complete. 6141da177e4SLinus Torvalds */ 6151da177e4SLinus Torvalds SCR_TO_REG (SS_REG), 6161da177e4SLinus Torvalds 0, 6171da177e4SLinus Torvalds SCR_LOAD_REG (HS_REG, HS_COMPLETE), 6181da177e4SLinus Torvalds 0, 6191da177e4SLinus Torvalds /* 6201da177e4SLinus Torvalds * Anticipate the MESSAGE PHASE for 6211da177e4SLinus Torvalds * the TASK COMPLETE message. 6221da177e4SLinus Torvalds */ 6231da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 6241da177e4SLinus Torvalds PADDR_A (msg_in), 6251da177e4SLinus Torvalds SCR_JUMP, 6261da177e4SLinus Torvalds PADDR_A (dispatch), 6271da177e4SLinus Torvalds }/*-------------------------< COMPLETE >-------------------------*/,{ 6281da177e4SLinus Torvalds /* 6291da177e4SLinus Torvalds * Complete message. 6301da177e4SLinus Torvalds * 6311da177e4SLinus Torvalds * When we terminate the cycle by clearing ACK, 6321da177e4SLinus Torvalds * the target may disconnect immediately. 6331da177e4SLinus Torvalds * 6341da177e4SLinus Torvalds * We don't want to be told of an "unexpected disconnect", 6351da177e4SLinus Torvalds * so we disable this feature. 6361da177e4SLinus Torvalds */ 6371da177e4SLinus Torvalds SCR_REG_REG (scntl2, SCR_AND, 0x7f), 6381da177e4SLinus Torvalds 0, 6391da177e4SLinus Torvalds /* 6401da177e4SLinus Torvalds * Terminate cycle ... 6411da177e4SLinus Torvalds */ 6421da177e4SLinus Torvalds SCR_CLR (SCR_ACK|SCR_ATN), 6431da177e4SLinus Torvalds 0, 6441da177e4SLinus Torvalds /* 6451da177e4SLinus Torvalds * ... and wait for the disconnect. 6461da177e4SLinus Torvalds */ 6471da177e4SLinus Torvalds SCR_WAIT_DISC, 6481da177e4SLinus Torvalds 0, 6491da177e4SLinus Torvalds }/*-------------------------< COMPLETE2 >------------------------*/,{ 6501da177e4SLinus Torvalds /* 6511da177e4SLinus Torvalds * Save host status. 6521da177e4SLinus Torvalds */ 6531da177e4SLinus Torvalds SCR_STORE_REL (scr0, 4), 6541da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.status), 6551da177e4SLinus Torvalds /* 6561da177e4SLinus Torvalds * Some bridges may reorder DMA writes to memory. 6571da177e4SLinus Torvalds * We donnot want the CPU to deal with completions 6581da177e4SLinus Torvalds * without all the posted write having been flushed 6591da177e4SLinus Torvalds * to memory. This DUMMY READ should flush posted 6601da177e4SLinus Torvalds * buffers prior to the CPU having to deal with 6611da177e4SLinus Torvalds * completions. 6621da177e4SLinus Torvalds */ 6631da177e4SLinus Torvalds SCR_LOAD_REL (scr0, 4), /* DUMMY READ */ 6641da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.status), 6651da177e4SLinus Torvalds 6661da177e4SLinus Torvalds /* 6671da177e4SLinus Torvalds * If command resulted in not GOOD status, 6681da177e4SLinus Torvalds * call the C code if needed. 6691da177e4SLinus Torvalds */ 6701da177e4SLinus Torvalds SCR_FROM_REG (SS_REG), 6711da177e4SLinus Torvalds 0, 6721da177e4SLinus Torvalds SCR_CALL ^ IFFALSE (DATA (S_GOOD)), 6731da177e4SLinus Torvalds PADDR_B (bad_status), 6741da177e4SLinus Torvalds /* 6751da177e4SLinus Torvalds * If we performed an auto-sense, call 6761da177e4SLinus Torvalds * the C code to synchronyze task aborts 6771da177e4SLinus Torvalds * with UNIT ATTENTION conditions. 6781da177e4SLinus Torvalds */ 6791da177e4SLinus Torvalds SCR_FROM_REG (HF_REG), 6801da177e4SLinus Torvalds 0, 6811da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (MASK (0 ,(HF_SENSE|HF_EXT_ERR))), 6821da177e4SLinus Torvalds PADDR_A (complete_error), 6831da177e4SLinus Torvalds }/*-------------------------< DONE >-----------------------------*/,{ 6841da177e4SLinus Torvalds /* 6851da177e4SLinus Torvalds * Copy the DSA to the DONE QUEUE and 6861da177e4SLinus Torvalds * signal completion to the host. 6871da177e4SLinus Torvalds * If we are interrupted between DONE 6881da177e4SLinus Torvalds * and DONE_END, we must reset, otherwise 6891da177e4SLinus Torvalds * the completed CCB may be lost. 6901da177e4SLinus Torvalds */ 6911da177e4SLinus Torvalds SCR_STORE_ABS (dsa, 4), 6921da177e4SLinus Torvalds PADDR_B (scratch), 6931da177e4SLinus Torvalds SCR_LOAD_ABS (dsa, 4), 6941da177e4SLinus Torvalds PADDR_B (done_pos), 6951da177e4SLinus Torvalds SCR_LOAD_ABS (scratcha, 4), 6961da177e4SLinus Torvalds PADDR_B (scratch), 6971da177e4SLinus Torvalds SCR_STORE_REL (scratcha, 4), 6981da177e4SLinus Torvalds 0, 6991da177e4SLinus Torvalds /* 7001da177e4SLinus Torvalds * The instruction below reads the DONE QUEUE next 7011da177e4SLinus Torvalds * free position from memory. 7021da177e4SLinus Torvalds * In addition it ensures that all PCI posted writes 7031da177e4SLinus Torvalds * are flushed and so the DSA value of the done 7041da177e4SLinus Torvalds * CCB is visible by the CPU before INTFLY is raised. 7051da177e4SLinus Torvalds */ 7061da177e4SLinus Torvalds SCR_LOAD_REL (scratcha, 4), 7071da177e4SLinus Torvalds 4, 7081da177e4SLinus Torvalds SCR_INT_FLY, 7091da177e4SLinus Torvalds 0, 7101da177e4SLinus Torvalds SCR_STORE_ABS (scratcha, 4), 7111da177e4SLinus Torvalds PADDR_B (done_pos), 7121da177e4SLinus Torvalds }/*-------------------------< DONE_END >-------------------------*/,{ 7131da177e4SLinus Torvalds SCR_JUMP, 7141da177e4SLinus Torvalds PADDR_A (start), 7151da177e4SLinus Torvalds }/*-------------------------< COMPLETE_ERROR >-------------------*/,{ 7161da177e4SLinus Torvalds SCR_LOAD_ABS (scratcha, 4), 7171da177e4SLinus Torvalds PADDR_B (startpos), 7181da177e4SLinus Torvalds SCR_INT, 7191da177e4SLinus Torvalds SIR_COMPLETE_ERROR, 7201da177e4SLinus Torvalds }/*-------------------------< SAVE_DP >--------------------------*/,{ 7211da177e4SLinus Torvalds /* 7221da177e4SLinus Torvalds * Clear ACK immediately. 7231da177e4SLinus Torvalds * No need to delay it. 7241da177e4SLinus Torvalds */ 7251da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 7261da177e4SLinus Torvalds 0, 7271da177e4SLinus Torvalds /* 7281da177e4SLinus Torvalds * Keep track we received a SAVE DP, so 7291da177e4SLinus Torvalds * we will switch to the other PM context 7301da177e4SLinus Torvalds * on the next PM since the DP may point 7311da177e4SLinus Torvalds * to the current PM context. 7321da177e4SLinus Torvalds */ 7331da177e4SLinus Torvalds SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED), 7341da177e4SLinus Torvalds 0, 7351da177e4SLinus Torvalds /* 7361da177e4SLinus Torvalds * SAVE_DP message: 7371da177e4SLinus Torvalds * Copy LASTP to SAVEP. 7381da177e4SLinus Torvalds */ 7391da177e4SLinus Torvalds SCR_LOAD_REL (scratcha, 4), 7401da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.lastp), 7411da177e4SLinus Torvalds SCR_STORE_REL (scratcha, 4), 7421da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.savep), 7431da177e4SLinus Torvalds /* 7441da177e4SLinus Torvalds * Anticipate the MESSAGE PHASE for 7451da177e4SLinus Torvalds * the DISCONNECT message. 7461da177e4SLinus Torvalds */ 7471da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)), 7481da177e4SLinus Torvalds PADDR_A (msg_in), 7491da177e4SLinus Torvalds SCR_JUMP, 7501da177e4SLinus Torvalds PADDR_A (dispatch), 7511da177e4SLinus Torvalds }/*-------------------------< RESTORE_DP >-----------------------*/,{ 7521da177e4SLinus Torvalds /* 7531da177e4SLinus Torvalds * Clear ACK immediately. 7541da177e4SLinus Torvalds * No need to delay it. 7551da177e4SLinus Torvalds */ 7561da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 7571da177e4SLinus Torvalds 0, 7581da177e4SLinus Torvalds /* 7591da177e4SLinus Torvalds * Copy SAVEP to LASTP. 7601da177e4SLinus Torvalds */ 7611da177e4SLinus Torvalds SCR_LOAD_REL (scratcha, 4), 7621da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.savep), 7631da177e4SLinus Torvalds SCR_STORE_REL (scratcha, 4), 7641da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.lastp), 7651da177e4SLinus Torvalds SCR_JUMP, 7661da177e4SLinus Torvalds PADDR_A (dispatch), 7671da177e4SLinus Torvalds }/*-------------------------< DISCONNECT >-----------------------*/,{ 7681da177e4SLinus Torvalds /* 7691da177e4SLinus Torvalds * DISCONNECTing ... 7701da177e4SLinus Torvalds * 7711da177e4SLinus Torvalds * disable the "unexpected disconnect" feature, 7721da177e4SLinus Torvalds * and remove the ACK signal. 7731da177e4SLinus Torvalds */ 7741da177e4SLinus Torvalds SCR_REG_REG (scntl2, SCR_AND, 0x7f), 7751da177e4SLinus Torvalds 0, 7761da177e4SLinus Torvalds SCR_CLR (SCR_ACK|SCR_ATN), 7771da177e4SLinus Torvalds 0, 7781da177e4SLinus Torvalds /* 7791da177e4SLinus Torvalds * Wait for the disconnect. 7801da177e4SLinus Torvalds */ 7811da177e4SLinus Torvalds SCR_WAIT_DISC, 7821da177e4SLinus Torvalds 0, 7831da177e4SLinus Torvalds /* 7841da177e4SLinus Torvalds * Status is: DISCONNECTED. 7851da177e4SLinus Torvalds */ 7861da177e4SLinus Torvalds SCR_LOAD_REG (HS_REG, HS_DISCONNECT), 7871da177e4SLinus Torvalds 0, 7881da177e4SLinus Torvalds /* 7891da177e4SLinus Torvalds * Save host status. 7901da177e4SLinus Torvalds */ 7911da177e4SLinus Torvalds SCR_STORE_REL (scr0, 4), 7921da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.status), 7931da177e4SLinus Torvalds SCR_JUMP, 7941da177e4SLinus Torvalds PADDR_A (start), 7951da177e4SLinus Torvalds }/*-------------------------< IDLE >-----------------------------*/,{ 7961da177e4SLinus Torvalds /* 7971da177e4SLinus Torvalds * Nothing to do? 7981da177e4SLinus Torvalds * Switch the LED off and wait for reselect. 7991da177e4SLinus Torvalds * Will be patched with a NO_OP if LED 8001da177e4SLinus Torvalds * not needed or not desired. 8011da177e4SLinus Torvalds */ 8021da177e4SLinus Torvalds SCR_REG_REG (gpreg, SCR_OR, 0x01), 8031da177e4SLinus Torvalds 0, 8041da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 8051da177e4SLinus Torvalds SCR_JUMPR, 8061da177e4SLinus Torvalds 8, 8071da177e4SLinus Torvalds #endif 8081da177e4SLinus Torvalds }/*-------------------------< UNGETJOB >-------------------------*/,{ 8091da177e4SLinus Torvalds #ifdef SYM_CONF_IARB_SUPPORT 8101da177e4SLinus Torvalds /* 8111da177e4SLinus Torvalds * Set IMMEDIATE ARBITRATION, for the next time. 8121da177e4SLinus Torvalds * This will give us better chance to win arbitration 8131da177e4SLinus Torvalds * for the job we just wanted to do. 8141da177e4SLinus Torvalds */ 8151da177e4SLinus Torvalds SCR_REG_REG (scntl1, SCR_OR, IARB), 8161da177e4SLinus Torvalds 0, 8171da177e4SLinus Torvalds #endif 8181da177e4SLinus Torvalds /* 8191da177e4SLinus Torvalds * We are not able to restart the SCRIPTS if we are 8201da177e4SLinus Torvalds * interrupted and these instruction haven't been 8211da177e4SLinus Torvalds * all executed. BTW, this is very unlikely to 8221da177e4SLinus Torvalds * happen, but we check that from the C code. 8231da177e4SLinus Torvalds */ 8241da177e4SLinus Torvalds SCR_LOAD_REG (dsa, 0xff), 8251da177e4SLinus Torvalds 0, 8261da177e4SLinus Torvalds SCR_STORE_ABS (scratcha, 4), 8271da177e4SLinus Torvalds PADDR_B (startpos), 8281da177e4SLinus Torvalds }/*-------------------------< RESELECT >-------------------------*/,{ 8291da177e4SLinus Torvalds #ifdef SYM_CONF_TARGET_ROLE_SUPPORT 8301da177e4SLinus Torvalds /* 8311da177e4SLinus Torvalds * Make sure we are in initiator mode. 8321da177e4SLinus Torvalds */ 8331da177e4SLinus Torvalds SCR_CLR (SCR_TRG), 8341da177e4SLinus Torvalds 0, 8351da177e4SLinus Torvalds #endif 8361da177e4SLinus Torvalds /* 8371da177e4SLinus Torvalds * Sleep waiting for a reselection. 8381da177e4SLinus Torvalds */ 8391da177e4SLinus Torvalds SCR_WAIT_RESEL, 8401da177e4SLinus Torvalds PADDR_A(start), 8411da177e4SLinus Torvalds }/*-------------------------< RESELECTED >-----------------------*/,{ 8421da177e4SLinus Torvalds /* 8431da177e4SLinus Torvalds * Switch the LED on. 8441da177e4SLinus Torvalds * Will be patched with a NO_OP if LED 8451da177e4SLinus Torvalds * not needed or not desired. 8461da177e4SLinus Torvalds */ 8471da177e4SLinus Torvalds SCR_REG_REG (gpreg, SCR_AND, 0xfe), 8481da177e4SLinus Torvalds 0, 8491da177e4SLinus Torvalds /* 8501da177e4SLinus Torvalds * load the target id into the sdid 8511da177e4SLinus Torvalds */ 8521da177e4SLinus Torvalds SCR_REG_SFBR (ssid, SCR_AND, 0x8F), 8531da177e4SLinus Torvalds 0, 8541da177e4SLinus Torvalds SCR_TO_REG (sdid), 8551da177e4SLinus Torvalds 0, 8561da177e4SLinus Torvalds /* 8571da177e4SLinus Torvalds * Load the target control block address 8581da177e4SLinus Torvalds */ 8591da177e4SLinus Torvalds SCR_LOAD_ABS (dsa, 4), 8601da177e4SLinus Torvalds PADDR_B (targtbl), 8611da177e4SLinus Torvalds SCR_SFBR_REG (dsa, SCR_SHL, 0), 8621da177e4SLinus Torvalds 0, 8631da177e4SLinus Torvalds SCR_REG_REG (dsa, SCR_SHL, 0), 8641da177e4SLinus Torvalds 0, 8651da177e4SLinus Torvalds SCR_REG_REG (dsa, SCR_AND, 0x3c), 8661da177e4SLinus Torvalds 0, 8671da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 8681da177e4SLinus Torvalds 0, 8691da177e4SLinus Torvalds /* 8701da177e4SLinus Torvalds * We expect MESSAGE IN phase. 8711da177e4SLinus Torvalds * If not, get help from the C code. 8721da177e4SLinus Torvalds */ 8731da177e4SLinus Torvalds SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)), 8741da177e4SLinus Torvalds SIR_RESEL_NO_MSG_IN, 8751da177e4SLinus Torvalds /* 8761da177e4SLinus Torvalds * Load the legacy synchronous transfer registers. 8771da177e4SLinus Torvalds */ 8781da177e4SLinus Torvalds SCR_LOAD_REL (scntl3, 1), 8791da177e4SLinus Torvalds offsetof(struct sym_tcb, head.wval), 8801da177e4SLinus Torvalds SCR_LOAD_REL (sxfer, 1), 8811da177e4SLinus Torvalds offsetof(struct sym_tcb, head.sval), 8821da177e4SLinus Torvalds }/*-------------------------< RESEL_SCNTL4 >---------------------*/,{ 8831da177e4SLinus Torvalds /* 8841da177e4SLinus Torvalds * The C1010 uses a new synchronous timing scheme. 8851da177e4SLinus Torvalds * Will be patched with a NO_OP if not a C1010. 8861da177e4SLinus Torvalds */ 8871da177e4SLinus Torvalds SCR_LOAD_REL (scntl4, 1), 8881da177e4SLinus Torvalds offsetof(struct sym_tcb, head.uval), 8891da177e4SLinus Torvalds /* 8901da177e4SLinus Torvalds * Get the IDENTIFY message. 8911da177e4SLinus Torvalds */ 8921da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 8931da177e4SLinus Torvalds HADDR_1 (msgin), 8941da177e4SLinus Torvalds /* 8951da177e4SLinus Torvalds * If IDENTIFY LUN #0, use a faster path 8961da177e4SLinus Torvalds * to find the LCB structure. 8971da177e4SLinus Torvalds */ 8981da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (0x80, 0xbf)), 8991da177e4SLinus Torvalds PADDR_A (resel_lun0), 9001da177e4SLinus Torvalds /* 9011da177e4SLinus Torvalds * If message isn't an IDENTIFY, 9021da177e4SLinus Torvalds * tell the C code about. 9031da177e4SLinus Torvalds */ 9041da177e4SLinus Torvalds SCR_INT ^ IFFALSE (MASK (0x80, 0x80)), 9051da177e4SLinus Torvalds SIR_RESEL_NO_IDENTIFY, 9061da177e4SLinus Torvalds /* 9071da177e4SLinus Torvalds * It is an IDENTIFY message, 9081da177e4SLinus Torvalds * Load the LUN control block address. 9091da177e4SLinus Torvalds */ 9101da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 9111da177e4SLinus Torvalds offsetof(struct sym_tcb, head.luntbl_sa), 9121da177e4SLinus Torvalds SCR_SFBR_REG (dsa, SCR_SHL, 0), 9131da177e4SLinus Torvalds 0, 9141da177e4SLinus Torvalds SCR_REG_REG (dsa, SCR_SHL, 0), 9151da177e4SLinus Torvalds 0, 9161da177e4SLinus Torvalds SCR_REG_REG (dsa, SCR_AND, 0xfc), 9171da177e4SLinus Torvalds 0, 9181da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 9191da177e4SLinus Torvalds 0, 9201da177e4SLinus Torvalds SCR_JUMPR, 9211da177e4SLinus Torvalds 8, 9221da177e4SLinus Torvalds }/*-------------------------< RESEL_LUN0 >-----------------------*/,{ 9231da177e4SLinus Torvalds /* 9241da177e4SLinus Torvalds * LUN 0 special case (but usual one :)) 9251da177e4SLinus Torvalds */ 9261da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 9271da177e4SLinus Torvalds offsetof(struct sym_tcb, head.lun0_sa), 9281da177e4SLinus Torvalds /* 9291da177e4SLinus Torvalds * Jump indirectly to the reselect action for this LUN. 9301da177e4SLinus Torvalds */ 9311da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 9321da177e4SLinus Torvalds offsetof(struct sym_lcb, head.resel_sa), 9331da177e4SLinus Torvalds SCR_RETURN, 9341da177e4SLinus Torvalds 0, 9351da177e4SLinus Torvalds /* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */ 9361da177e4SLinus Torvalds }/*-------------------------< RESEL_TAG >------------------------*/,{ 9371da177e4SLinus Torvalds /* 9381da177e4SLinus Torvalds * ACK the IDENTIFY previously received. 9391da177e4SLinus Torvalds */ 9401da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 9411da177e4SLinus Torvalds 0, 9421da177e4SLinus Torvalds /* 9431da177e4SLinus Torvalds * It shall be a tagged command. 9441da177e4SLinus Torvalds * Read SIMPLE+TAG. 9451da177e4SLinus Torvalds * The C code will deal with errors. 946bbf2f9fbSRobert P. J. Day * Aggressive optimization, isn't it? :) 9471da177e4SLinus Torvalds */ 9481da177e4SLinus Torvalds SCR_MOVE_ABS (2) ^ SCR_MSG_IN, 9491da177e4SLinus Torvalds HADDR_1 (msgin), 9501da177e4SLinus Torvalds /* 9511da177e4SLinus Torvalds * Load the pointer to the tagged task 9521da177e4SLinus Torvalds * table for this LUN. 9531da177e4SLinus Torvalds */ 9541da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 9551da177e4SLinus Torvalds offsetof(struct sym_lcb, head.itlq_tbl_sa), 9561da177e4SLinus Torvalds /* 9571da177e4SLinus Torvalds * The SIDL still contains the TAG value. 958bbf2f9fbSRobert P. J. Day * Aggressive optimization, isn't it? :):) 9591da177e4SLinus Torvalds */ 9601da177e4SLinus Torvalds SCR_REG_SFBR (sidl, SCR_SHL, 0), 9611da177e4SLinus Torvalds 0, 9621da177e4SLinus Torvalds #if SYM_CONF_MAX_TASK*4 > 512 9631da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (CARRYSET), 9641da177e4SLinus Torvalds 8, 9651da177e4SLinus Torvalds SCR_REG_REG (dsa1, SCR_OR, 2), 9661da177e4SLinus Torvalds 0, 9671da177e4SLinus Torvalds SCR_REG_REG (sfbr, SCR_SHL, 0), 9681da177e4SLinus Torvalds 0, 9691da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (CARRYSET), 9701da177e4SLinus Torvalds 8, 9711da177e4SLinus Torvalds SCR_REG_REG (dsa1, SCR_OR, 1), 9721da177e4SLinus Torvalds 0, 9731da177e4SLinus Torvalds #elif SYM_CONF_MAX_TASK*4 > 256 9741da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (CARRYSET), 9751da177e4SLinus Torvalds 8, 9761da177e4SLinus Torvalds SCR_REG_REG (dsa1, SCR_OR, 1), 9771da177e4SLinus Torvalds 0, 9781da177e4SLinus Torvalds #endif 9791da177e4SLinus Torvalds /* 9801da177e4SLinus Torvalds * Retrieve the DSA of this task. 9811da177e4SLinus Torvalds * JUMP indirectly to the restart point of the CCB. 9821da177e4SLinus Torvalds */ 9831da177e4SLinus Torvalds SCR_SFBR_REG (dsa, SCR_AND, 0xfc), 9841da177e4SLinus Torvalds 0, 9851da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 9861da177e4SLinus Torvalds 0, 9871da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 9881da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.head.go.restart), 9891da177e4SLinus Torvalds SCR_RETURN, 9901da177e4SLinus Torvalds 0, 9911da177e4SLinus Torvalds /* In normal situations we branch to RESEL_DSA */ 9921da177e4SLinus Torvalds }/*-------------------------< RESEL_DSA >------------------------*/,{ 9931da177e4SLinus Torvalds /* 9941da177e4SLinus Torvalds * ACK the IDENTIFY or TAG previously received. 9951da177e4SLinus Torvalds */ 9961da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 9971da177e4SLinus Torvalds 0, 9981da177e4SLinus Torvalds }/*-------------------------< RESEL_DSA1 >-----------------------*/,{ 9991da177e4SLinus Torvalds /* 10001da177e4SLinus Torvalds * Initialize the status registers 10011da177e4SLinus Torvalds */ 10021da177e4SLinus Torvalds SCR_LOAD_REL (scr0, 4), 10031da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.head.status), 10041da177e4SLinus Torvalds /* 10051da177e4SLinus Torvalds * Jump to dispatcher. 10061da177e4SLinus Torvalds */ 10071da177e4SLinus Torvalds SCR_JUMP, 10081da177e4SLinus Torvalds PADDR_A (dispatch), 10091da177e4SLinus Torvalds }/*-------------------------< RESEL_NO_TAG >---------------------*/,{ 10101da177e4SLinus Torvalds /* 10111da177e4SLinus Torvalds * Load the DSA with the unique ITL task. 10121da177e4SLinus Torvalds */ 10131da177e4SLinus Torvalds SCR_LOAD_REL (dsa, 4), 10141da177e4SLinus Torvalds offsetof(struct sym_lcb, head.itl_task_sa), 10151da177e4SLinus Torvalds /* 10161da177e4SLinus Torvalds * JUMP indirectly to the restart point of the CCB. 10171da177e4SLinus Torvalds */ 10181da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 10191da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.head.go.restart), 10201da177e4SLinus Torvalds SCR_RETURN, 10211da177e4SLinus Torvalds 0, 10221da177e4SLinus Torvalds /* In normal situations we branch to RESEL_DSA */ 10231da177e4SLinus Torvalds }/*-------------------------< DATA_IN >--------------------------*/,{ 10241da177e4SLinus Torvalds /* 10251da177e4SLinus Torvalds * Because the size depends on the 10261da177e4SLinus Torvalds * #define SYM_CONF_MAX_SG parameter, 10271da177e4SLinus Torvalds * it is filled in at runtime. 10281da177e4SLinus Torvalds * 10291da177e4SLinus Torvalds * ##===========< i=0; i<SYM_CONF_MAX_SG >========= 10301da177e4SLinus Torvalds * || SCR_CHMOV_TBL ^ SCR_DATA_IN, 10311da177e4SLinus Torvalds * || offsetof (struct sym_dsb, data[ i]), 10321da177e4SLinus Torvalds * ##========================================== 10331da177e4SLinus Torvalds */ 10341da177e4SLinus Torvalds 0 10351da177e4SLinus Torvalds }/*-------------------------< DATA_IN2 >-------------------------*/,{ 10361da177e4SLinus Torvalds SCR_CALL, 10371da177e4SLinus Torvalds PADDR_A (datai_done), 10381da177e4SLinus Torvalds SCR_JUMP, 10391da177e4SLinus Torvalds PADDR_B (data_ovrun), 10401da177e4SLinus Torvalds }/*-------------------------< DATA_OUT >-------------------------*/,{ 10411da177e4SLinus Torvalds /* 10421da177e4SLinus Torvalds * Because the size depends on the 10431da177e4SLinus Torvalds * #define SYM_CONF_MAX_SG parameter, 10441da177e4SLinus Torvalds * it is filled in at runtime. 10451da177e4SLinus Torvalds * 10461da177e4SLinus Torvalds * ##===========< i=0; i<SYM_CONF_MAX_SG >========= 10471da177e4SLinus Torvalds * || SCR_CHMOV_TBL ^ SCR_DATA_OUT, 10481da177e4SLinus Torvalds * || offsetof (struct sym_dsb, data[ i]), 10491da177e4SLinus Torvalds * ##========================================== 10501da177e4SLinus Torvalds */ 10511da177e4SLinus Torvalds 0 10521da177e4SLinus Torvalds }/*-------------------------< DATA_OUT2 >------------------------*/,{ 10531da177e4SLinus Torvalds SCR_CALL, 10541da177e4SLinus Torvalds PADDR_A (datao_done), 10551da177e4SLinus Torvalds SCR_JUMP, 10561da177e4SLinus Torvalds PADDR_B (data_ovrun), 10571da177e4SLinus Torvalds }/*-------------------------< PM0_DATA >-------------------------*/,{ 10581da177e4SLinus Torvalds /* 10591da177e4SLinus Torvalds * Read our host flags to SFBR, so we will be able 10601da177e4SLinus Torvalds * to check against the data direction we expect. 10611da177e4SLinus Torvalds */ 10621da177e4SLinus Torvalds SCR_FROM_REG (HF_REG), 10631da177e4SLinus Torvalds 0, 10641da177e4SLinus Torvalds /* 10651da177e4SLinus Torvalds * Check against actual DATA PHASE. 10661da177e4SLinus Torvalds */ 10671da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 10681da177e4SLinus Torvalds PADDR_A (pm0_data_out), 10691da177e4SLinus Torvalds /* 10701da177e4SLinus Torvalds * Actual phase is DATA IN. 10711da177e4SLinus Torvalds * Check against expected direction. 10721da177e4SLinus Torvalds */ 10731da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), 10741da177e4SLinus Torvalds PADDR_B (data_ovrun), 10751da177e4SLinus Torvalds /* 10761da177e4SLinus Torvalds * Keep track we are moving data from the 10771da177e4SLinus Torvalds * PM0 DATA mini-script. 10781da177e4SLinus Torvalds */ 10791da177e4SLinus Torvalds SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 10801da177e4SLinus Torvalds 0, 10811da177e4SLinus Torvalds /* 10821da177e4SLinus Torvalds * Move the data to memory. 10831da177e4SLinus Torvalds */ 10841da177e4SLinus Torvalds SCR_CHMOV_TBL ^ SCR_DATA_IN, 10851da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.pm0.sg), 10861da177e4SLinus Torvalds SCR_JUMP, 10871da177e4SLinus Torvalds PADDR_A (pm0_data_end), 10881da177e4SLinus Torvalds }/*-------------------------< PM0_DATA_OUT >---------------------*/,{ 10891da177e4SLinus Torvalds /* 10901da177e4SLinus Torvalds * Actual phase is DATA OUT. 10911da177e4SLinus Torvalds * Check against expected direction. 10921da177e4SLinus Torvalds */ 10931da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), 10941da177e4SLinus Torvalds PADDR_B (data_ovrun), 10951da177e4SLinus Torvalds /* 10961da177e4SLinus Torvalds * Keep track we are moving data from the 10971da177e4SLinus Torvalds * PM0 DATA mini-script. 10981da177e4SLinus Torvalds */ 10991da177e4SLinus Torvalds SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0), 11001da177e4SLinus Torvalds 0, 11011da177e4SLinus Torvalds /* 11021da177e4SLinus Torvalds * Move the data from memory. 11031da177e4SLinus Torvalds */ 11041da177e4SLinus Torvalds SCR_CHMOV_TBL ^ SCR_DATA_OUT, 11051da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.pm0.sg), 11061da177e4SLinus Torvalds }/*-------------------------< PM0_DATA_END >---------------------*/,{ 11071da177e4SLinus Torvalds /* 11081da177e4SLinus Torvalds * Clear the flag that told we were moving 11091da177e4SLinus Torvalds * data from the PM0 DATA mini-script. 11101da177e4SLinus Torvalds */ 11111da177e4SLinus Torvalds SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)), 11121da177e4SLinus Torvalds 0, 11131da177e4SLinus Torvalds /* 11141da177e4SLinus Torvalds * Return to the previous DATA script which 11151da177e4SLinus Torvalds * is guaranteed by design (if no bug) to be 11161da177e4SLinus Torvalds * the main DATA script for this transfer. 11171da177e4SLinus Torvalds */ 11181da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 11191da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.pm0.ret), 11201da177e4SLinus Torvalds SCR_RETURN, 11211da177e4SLinus Torvalds 0, 11221da177e4SLinus Torvalds }/*-------------------------< PM1_DATA >-------------------------*/,{ 11231da177e4SLinus Torvalds /* 11241da177e4SLinus Torvalds * Read our host flags to SFBR, so we will be able 11251da177e4SLinus Torvalds * to check against the data direction we expect. 11261da177e4SLinus Torvalds */ 11271da177e4SLinus Torvalds SCR_FROM_REG (HF_REG), 11281da177e4SLinus Torvalds 0, 11291da177e4SLinus Torvalds /* 11301da177e4SLinus Torvalds * Check against actual DATA PHASE. 11311da177e4SLinus Torvalds */ 11321da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 11331da177e4SLinus Torvalds PADDR_A (pm1_data_out), 11341da177e4SLinus Torvalds /* 11351da177e4SLinus Torvalds * Actual phase is DATA IN. 11361da177e4SLinus Torvalds * Check against expected direction. 11371da177e4SLinus Torvalds */ 11381da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)), 11391da177e4SLinus Torvalds PADDR_B (data_ovrun), 11401da177e4SLinus Torvalds /* 11411da177e4SLinus Torvalds * Keep track we are moving data from the 11421da177e4SLinus Torvalds * PM1 DATA mini-script. 11431da177e4SLinus Torvalds */ 11441da177e4SLinus Torvalds SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 11451da177e4SLinus Torvalds 0, 11461da177e4SLinus Torvalds /* 11471da177e4SLinus Torvalds * Move the data to memory. 11481da177e4SLinus Torvalds */ 11491da177e4SLinus Torvalds SCR_CHMOV_TBL ^ SCR_DATA_IN, 11501da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.pm1.sg), 11511da177e4SLinus Torvalds SCR_JUMP, 11521da177e4SLinus Torvalds PADDR_A (pm1_data_end), 11531da177e4SLinus Torvalds }/*-------------------------< PM1_DATA_OUT >---------------------*/,{ 11541da177e4SLinus Torvalds /* 11551da177e4SLinus Torvalds * Actual phase is DATA OUT. 11561da177e4SLinus Torvalds * Check against expected direction. 11571da177e4SLinus Torvalds */ 11581da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)), 11591da177e4SLinus Torvalds PADDR_B (data_ovrun), 11601da177e4SLinus Torvalds /* 11611da177e4SLinus Torvalds * Keep track we are moving data from the 11621da177e4SLinus Torvalds * PM1 DATA mini-script. 11631da177e4SLinus Torvalds */ 11641da177e4SLinus Torvalds SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1), 11651da177e4SLinus Torvalds 0, 11661da177e4SLinus Torvalds /* 11671da177e4SLinus Torvalds * Move the data from memory. 11681da177e4SLinus Torvalds */ 11691da177e4SLinus Torvalds SCR_CHMOV_TBL ^ SCR_DATA_OUT, 11701da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.pm1.sg), 11711da177e4SLinus Torvalds }/*-------------------------< PM1_DATA_END >---------------------*/,{ 11721da177e4SLinus Torvalds /* 11731da177e4SLinus Torvalds * Clear the flag that told we were moving 11741da177e4SLinus Torvalds * data from the PM1 DATA mini-script. 11751da177e4SLinus Torvalds */ 11761da177e4SLinus Torvalds SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)), 11771da177e4SLinus Torvalds 0, 11781da177e4SLinus Torvalds /* 11791da177e4SLinus Torvalds * Return to the previous DATA script which 11801da177e4SLinus Torvalds * is guaranteed by design (if no bug) to be 11811da177e4SLinus Torvalds * the main DATA script for this transfer. 11821da177e4SLinus Torvalds */ 11831da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 11841da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.pm1.ret), 11851da177e4SLinus Torvalds SCR_RETURN, 11861da177e4SLinus Torvalds 0, 11871da177e4SLinus Torvalds }/*-------------------------<>-----------------------------------*/ 11881da177e4SLinus Torvalds }; 11891da177e4SLinus Torvalds 11901da177e4SLinus Torvalds static struct SYM_FWB_SCR SYM_FWB_SCR = { 11911da177e4SLinus Torvalds /*--------------------------< START64 >--------------------------*/ { 11921da177e4SLinus Torvalds /* 11931da177e4SLinus Torvalds * SCRIPT entry point for the 895A, 896 and 1010. 11941da177e4SLinus Torvalds * For now, there is no specific stuff for those 11951da177e4SLinus Torvalds * chips at this point, but this may come. 11961da177e4SLinus Torvalds */ 11971da177e4SLinus Torvalds SCR_JUMP, 11981da177e4SLinus Torvalds PADDR_A (init), 11991da177e4SLinus Torvalds }/*-------------------------< NO_DATA >--------------------------*/,{ 12001da177e4SLinus Torvalds SCR_JUMP, 12011da177e4SLinus Torvalds PADDR_B (data_ovrun), 12021da177e4SLinus Torvalds }/*-------------------------< SEL_FOR_ABORT >--------------------*/,{ 12031da177e4SLinus Torvalds /* 12041da177e4SLinus Torvalds * We are jumped here by the C code, if we have 12051da177e4SLinus Torvalds * some target to reset or some disconnected 12061da177e4SLinus Torvalds * job to abort. Since error recovery is a serious 12071da177e4SLinus Torvalds * busyness, we will really reset the SCSI BUS, if 12081da177e4SLinus Torvalds * case of a SCSI interrupt occurring in this path. 12091da177e4SLinus Torvalds */ 12101da177e4SLinus Torvalds #ifdef SYM_CONF_TARGET_ROLE_SUPPORT 12111da177e4SLinus Torvalds /* 12121da177e4SLinus Torvalds * Set initiator mode. 12131da177e4SLinus Torvalds */ 12141da177e4SLinus Torvalds SCR_CLR (SCR_TRG), 12151da177e4SLinus Torvalds 0, 12161da177e4SLinus Torvalds #endif 12171da177e4SLinus Torvalds /* 12181da177e4SLinus Torvalds * And try to select this target. 12191da177e4SLinus Torvalds */ 12201da177e4SLinus Torvalds SCR_SEL_TBL_ATN ^ offsetof (struct sym_hcb, abrt_sel), 12211da177e4SLinus Torvalds PADDR_A (reselect), 12221da177e4SLinus Torvalds /* 12231da177e4SLinus Torvalds * Wait for the selection to complete or 12241da177e4SLinus Torvalds * the selection to time out. 12251da177e4SLinus Torvalds */ 12261da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)), 12271da177e4SLinus Torvalds -8, 12281da177e4SLinus Torvalds /* 12291da177e4SLinus Torvalds * Call the C code. 12301da177e4SLinus Torvalds */ 12311da177e4SLinus Torvalds SCR_INT, 12321da177e4SLinus Torvalds SIR_TARGET_SELECTED, 12331da177e4SLinus Torvalds /* 12341da177e4SLinus Torvalds * The C code should let us continue here. 12351da177e4SLinus Torvalds * Send the 'kiss of death' message. 12361da177e4SLinus Torvalds * We expect an immediate disconnect once 12371da177e4SLinus Torvalds * the target has eaten the message. 12381da177e4SLinus Torvalds */ 12391da177e4SLinus Torvalds SCR_REG_REG (scntl2, SCR_AND, 0x7f), 12401da177e4SLinus Torvalds 0, 12411da177e4SLinus Torvalds SCR_MOVE_TBL ^ SCR_MSG_OUT, 12421da177e4SLinus Torvalds offsetof (struct sym_hcb, abrt_tbl), 12431da177e4SLinus Torvalds SCR_CLR (SCR_ACK|SCR_ATN), 12441da177e4SLinus Torvalds 0, 12451da177e4SLinus Torvalds SCR_WAIT_DISC, 12461da177e4SLinus Torvalds 0, 12471da177e4SLinus Torvalds /* 12481da177e4SLinus Torvalds * Tell the C code that we are done. 12491da177e4SLinus Torvalds */ 12501da177e4SLinus Torvalds SCR_INT, 12511da177e4SLinus Torvalds SIR_ABORT_SENT, 12521da177e4SLinus Torvalds }/*-------------------------< SEL_FOR_ABORT_1 >------------------*/,{ 12531da177e4SLinus Torvalds /* 12541da177e4SLinus Torvalds * Jump at scheduler. 12551da177e4SLinus Torvalds */ 12561da177e4SLinus Torvalds SCR_JUMP, 12571da177e4SLinus Torvalds PADDR_A (start), 12581da177e4SLinus Torvalds }/*-------------------------< MSG_IN_ETC >-----------------------*/,{ 12591da177e4SLinus Torvalds /* 12601da177e4SLinus Torvalds * If it is an EXTENDED (variable size message) 12611da177e4SLinus Torvalds * Handle it. 12621da177e4SLinus Torvalds */ 12631da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), 12641da177e4SLinus Torvalds PADDR_B (msg_extended), 12651da177e4SLinus Torvalds /* 12661da177e4SLinus Torvalds * Let the C code handle any other 12671da177e4SLinus Torvalds * 1 byte message. 12681da177e4SLinus Torvalds */ 12691da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (0x00, 0xf0)), 12701da177e4SLinus Torvalds PADDR_B (msg_received), 12711da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (0x10, 0xf0)), 12721da177e4SLinus Torvalds PADDR_B (msg_received), 12731da177e4SLinus Torvalds /* 12741da177e4SLinus Torvalds * We donnot handle 2 bytes messages from SCRIPTS. 12751da177e4SLinus Torvalds * So, let the C code deal with these ones too. 12761da177e4SLinus Torvalds */ 12771da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (MASK (0x20, 0xf0)), 12781da177e4SLinus Torvalds PADDR_B (msg_weird_seen), 12791da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 12801da177e4SLinus Torvalds 0, 12811da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 12821da177e4SLinus Torvalds HADDR_1 (msgin[1]), 12831da177e4SLinus Torvalds }/*-------------------------< MSG_RECEIVED >---------------------*/,{ 12841da177e4SLinus Torvalds SCR_LOAD_REL (scratcha, 4), /* DUMMY READ */ 12851da177e4SLinus Torvalds 0, 12861da177e4SLinus Torvalds SCR_INT, 12871da177e4SLinus Torvalds SIR_MSG_RECEIVED, 12881da177e4SLinus Torvalds }/*-------------------------< MSG_WEIRD_SEEN >-------------------*/,{ 12891da177e4SLinus Torvalds SCR_LOAD_REL (scratcha, 4), /* DUMMY READ */ 12901da177e4SLinus Torvalds 0, 12911da177e4SLinus Torvalds SCR_INT, 12921da177e4SLinus Torvalds SIR_MSG_WEIRD, 12931da177e4SLinus Torvalds }/*-------------------------< MSG_EXTENDED >---------------------*/,{ 12941da177e4SLinus Torvalds /* 12951da177e4SLinus Torvalds * Clear ACK and get the next byte 12961da177e4SLinus Torvalds * assumed to be the message length. 12971da177e4SLinus Torvalds */ 12981da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 12991da177e4SLinus Torvalds 0, 13001da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 13011da177e4SLinus Torvalds HADDR_1 (msgin[1]), 13021da177e4SLinus Torvalds /* 13031da177e4SLinus Torvalds * Try to catch some unlikely situations as 0 length 13041da177e4SLinus Torvalds * or too large the length. 13051da177e4SLinus Torvalds */ 13061da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (DATA (0)), 13071da177e4SLinus Torvalds PADDR_B (msg_weird_seen), 13081da177e4SLinus Torvalds SCR_TO_REG (scratcha), 13091da177e4SLinus Torvalds 0, 13101da177e4SLinus Torvalds SCR_REG_REG (sfbr, SCR_ADD, (256-8)), 13111da177e4SLinus Torvalds 0, 13121da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (CARRYSET), 13131da177e4SLinus Torvalds PADDR_B (msg_weird_seen), 13141da177e4SLinus Torvalds /* 13151da177e4SLinus Torvalds * We donnot handle extended messages from SCRIPTS. 131625985edcSLucas De Marchi * Read the amount of data corresponding to the 13171da177e4SLinus Torvalds * message length and call the C code. 13181da177e4SLinus Torvalds */ 13191da177e4SLinus Torvalds SCR_STORE_REL (scratcha, 1), 13201da177e4SLinus Torvalds offsetof (struct sym_dsb, smsg_ext.size), 13211da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 13221da177e4SLinus Torvalds 0, 13231da177e4SLinus Torvalds SCR_MOVE_TBL ^ SCR_MSG_IN, 13241da177e4SLinus Torvalds offsetof (struct sym_dsb, smsg_ext), 13251da177e4SLinus Torvalds SCR_JUMP, 13261da177e4SLinus Torvalds PADDR_B (msg_received), 13271da177e4SLinus Torvalds }/*-------------------------< MSG_BAD >--------------------------*/,{ 13281da177e4SLinus Torvalds /* 13291da177e4SLinus Torvalds * unimplemented message - reject it. 13301da177e4SLinus Torvalds */ 13311da177e4SLinus Torvalds SCR_INT, 13321da177e4SLinus Torvalds SIR_REJECT_TO_SEND, 13331da177e4SLinus Torvalds SCR_SET (SCR_ATN), 13341da177e4SLinus Torvalds 0, 13351da177e4SLinus Torvalds SCR_JUMP, 13361da177e4SLinus Torvalds PADDR_A (clrack), 13371da177e4SLinus Torvalds }/*-------------------------< MSG_WEIRD >------------------------*/,{ 13381da177e4SLinus Torvalds /* 13391da177e4SLinus Torvalds * weird message received 13401da177e4SLinus Torvalds * ignore all MSG IN phases and reject it. 13411da177e4SLinus Torvalds */ 13421da177e4SLinus Torvalds SCR_INT, 13431da177e4SLinus Torvalds SIR_REJECT_TO_SEND, 13441da177e4SLinus Torvalds SCR_SET (SCR_ATN), 13451da177e4SLinus Torvalds 0, 13461da177e4SLinus Torvalds }/*-------------------------< MSG_WEIRD1 >-----------------------*/,{ 13471da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 13481da177e4SLinus Torvalds 0, 13491da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 13501da177e4SLinus Torvalds PADDR_A (dispatch), 13511da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 13521da177e4SLinus Torvalds HADDR_1 (scratch), 13531da177e4SLinus Torvalds SCR_JUMP, 13541da177e4SLinus Torvalds PADDR_B (msg_weird1), 13551da177e4SLinus Torvalds }/*-------------------------< WDTR_RESP >------------------------*/,{ 13561da177e4SLinus Torvalds /* 13571da177e4SLinus Torvalds * let the target fetch our answer. 13581da177e4SLinus Torvalds */ 13591da177e4SLinus Torvalds SCR_SET (SCR_ATN), 13601da177e4SLinus Torvalds 0, 13611da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 13621da177e4SLinus Torvalds 0, 13631da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 13641da177e4SLinus Torvalds PADDR_B (nego_bad_phase), 13651da177e4SLinus Torvalds }/*-------------------------< SEND_WDTR >------------------------*/,{ 13661da177e4SLinus Torvalds /* 13671da177e4SLinus Torvalds * Send the M_X_WIDE_REQ 13681da177e4SLinus Torvalds */ 13691da177e4SLinus Torvalds SCR_MOVE_ABS (4) ^ SCR_MSG_OUT, 13701da177e4SLinus Torvalds HADDR_1 (msgout), 13711da177e4SLinus Torvalds SCR_JUMP, 13721da177e4SLinus Torvalds PADDR_B (msg_out_done), 13731da177e4SLinus Torvalds }/*-------------------------< SDTR_RESP >------------------------*/,{ 13741da177e4SLinus Torvalds /* 13751da177e4SLinus Torvalds * let the target fetch our answer. 13761da177e4SLinus Torvalds */ 13771da177e4SLinus Torvalds SCR_SET (SCR_ATN), 13781da177e4SLinus Torvalds 0, 13791da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 13801da177e4SLinus Torvalds 0, 13811da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 13821da177e4SLinus Torvalds PADDR_B (nego_bad_phase), 13831da177e4SLinus Torvalds }/*-------------------------< SEND_SDTR >------------------------*/,{ 13841da177e4SLinus Torvalds /* 13851da177e4SLinus Torvalds * Send the M_X_SYNC_REQ 13861da177e4SLinus Torvalds */ 13871da177e4SLinus Torvalds SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, 13881da177e4SLinus Torvalds HADDR_1 (msgout), 13891da177e4SLinus Torvalds SCR_JUMP, 13901da177e4SLinus Torvalds PADDR_B (msg_out_done), 13911da177e4SLinus Torvalds }/*-------------------------< PPR_RESP >-------------------------*/,{ 13921da177e4SLinus Torvalds /* 13931da177e4SLinus Torvalds * let the target fetch our answer. 13941da177e4SLinus Torvalds */ 13951da177e4SLinus Torvalds SCR_SET (SCR_ATN), 13961da177e4SLinus Torvalds 0, 13971da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 13981da177e4SLinus Torvalds 0, 13991da177e4SLinus Torvalds SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)), 14001da177e4SLinus Torvalds PADDR_B (nego_bad_phase), 14011da177e4SLinus Torvalds }/*-------------------------< SEND_PPR >-------------------------*/,{ 14021da177e4SLinus Torvalds /* 14031da177e4SLinus Torvalds * Send the M_X_PPR_REQ 14041da177e4SLinus Torvalds */ 14051da177e4SLinus Torvalds SCR_MOVE_ABS (8) ^ SCR_MSG_OUT, 14061da177e4SLinus Torvalds HADDR_1 (msgout), 14071da177e4SLinus Torvalds SCR_JUMP, 14081da177e4SLinus Torvalds PADDR_B (msg_out_done), 14091da177e4SLinus Torvalds }/*-------------------------< NEGO_BAD_PHASE >-------------------*/,{ 14101da177e4SLinus Torvalds SCR_INT, 14111da177e4SLinus Torvalds SIR_NEGO_PROTO, 14121da177e4SLinus Torvalds SCR_JUMP, 14131da177e4SLinus Torvalds PADDR_A (dispatch), 14141da177e4SLinus Torvalds }/*-------------------------< MSG_OUT >--------------------------*/,{ 14151da177e4SLinus Torvalds /* 14161da177e4SLinus Torvalds * The target requests a message. 14171da177e4SLinus Torvalds * We donnot send messages that may 14181da177e4SLinus Torvalds * require the device to go to bus free. 14191da177e4SLinus Torvalds */ 14201da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 14211da177e4SLinus Torvalds HADDR_1 (msgout), 14221da177e4SLinus Torvalds /* 14231da177e4SLinus Torvalds * ... wait for the next phase 14241da177e4SLinus Torvalds * if it's a message out, send it again, ... 14251da177e4SLinus Torvalds */ 14261da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), 14271da177e4SLinus Torvalds PADDR_B (msg_out), 14281da177e4SLinus Torvalds }/*-------------------------< MSG_OUT_DONE >---------------------*/,{ 14291da177e4SLinus Torvalds /* 14301da177e4SLinus Torvalds * Let the C code be aware of the 14311da177e4SLinus Torvalds * sent message and clear the message. 14321da177e4SLinus Torvalds */ 14331da177e4SLinus Torvalds SCR_INT, 14341da177e4SLinus Torvalds SIR_MSG_OUT_DONE, 14351da177e4SLinus Torvalds /* 14361da177e4SLinus Torvalds * ... and process the next phase 14371da177e4SLinus Torvalds */ 14381da177e4SLinus Torvalds SCR_JUMP, 14391da177e4SLinus Torvalds PADDR_A (dispatch), 14401da177e4SLinus Torvalds }/*-------------------------< DATA_OVRUN >-----------------------*/,{ 14411da177e4SLinus Torvalds /* 14421da177e4SLinus Torvalds * Use scratcha to count the extra bytes. 14431da177e4SLinus Torvalds */ 14441da177e4SLinus Torvalds SCR_LOAD_ABS (scratcha, 4), 14451da177e4SLinus Torvalds PADDR_B (zero), 14461da177e4SLinus Torvalds }/*-------------------------< DATA_OVRUN1 >----------------------*/,{ 14471da177e4SLinus Torvalds /* 14481da177e4SLinus Torvalds * The target may want to transfer too much data. 14491da177e4SLinus Torvalds * 14501da177e4SLinus Torvalds * If phase is DATA OUT write 1 byte and count it. 14511da177e4SLinus Torvalds */ 14521da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)), 14531da177e4SLinus Torvalds 16, 14541da177e4SLinus Torvalds SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT, 14551da177e4SLinus Torvalds HADDR_1 (scratch), 14561da177e4SLinus Torvalds SCR_JUMP, 14571da177e4SLinus Torvalds PADDR_B (data_ovrun2), 14581da177e4SLinus Torvalds /* 14591da177e4SLinus Torvalds * If WSR is set, clear this condition, and 14601da177e4SLinus Torvalds * count this byte. 14611da177e4SLinus Torvalds */ 14621da177e4SLinus Torvalds SCR_FROM_REG (scntl2), 14631da177e4SLinus Torvalds 0, 14641da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)), 14651da177e4SLinus Torvalds 16, 14661da177e4SLinus Torvalds SCR_REG_REG (scntl2, SCR_OR, WSR), 14671da177e4SLinus Torvalds 0, 14681da177e4SLinus Torvalds SCR_JUMP, 14691da177e4SLinus Torvalds PADDR_B (data_ovrun2), 14701da177e4SLinus Torvalds /* 14711da177e4SLinus Torvalds * Finally check against DATA IN phase. 14721da177e4SLinus Torvalds * Signal data overrun to the C code 14731da177e4SLinus Torvalds * and jump to dispatcher if not so. 14741da177e4SLinus Torvalds * Read 1 byte otherwise and count it. 14751da177e4SLinus Torvalds */ 14761da177e4SLinus Torvalds SCR_JUMPR ^ IFTRUE (WHEN (SCR_DATA_IN)), 14771da177e4SLinus Torvalds 16, 14781da177e4SLinus Torvalds SCR_INT, 14791da177e4SLinus Torvalds SIR_DATA_OVERRUN, 14801da177e4SLinus Torvalds SCR_JUMP, 14811da177e4SLinus Torvalds PADDR_A (dispatch), 14821da177e4SLinus Torvalds SCR_CHMOV_ABS (1) ^ SCR_DATA_IN, 14831da177e4SLinus Torvalds HADDR_1 (scratch), 14841da177e4SLinus Torvalds }/*-------------------------< DATA_OVRUN2 >----------------------*/,{ 14851da177e4SLinus Torvalds /* 14861da177e4SLinus Torvalds * Count this byte. 14871da177e4SLinus Torvalds * This will allow to return a negative 14881da177e4SLinus Torvalds * residual to user. 14891da177e4SLinus Torvalds */ 14901da177e4SLinus Torvalds SCR_REG_REG (scratcha, SCR_ADD, 0x01), 14911da177e4SLinus Torvalds 0, 14921da177e4SLinus Torvalds SCR_REG_REG (scratcha1, SCR_ADDC, 0), 14931da177e4SLinus Torvalds 0, 14941da177e4SLinus Torvalds SCR_REG_REG (scratcha2, SCR_ADDC, 0), 14951da177e4SLinus Torvalds 0, 14961da177e4SLinus Torvalds /* 14971da177e4SLinus Torvalds * .. and repeat as required. 14981da177e4SLinus Torvalds */ 14991da177e4SLinus Torvalds SCR_JUMP, 15001da177e4SLinus Torvalds PADDR_B (data_ovrun1), 15011da177e4SLinus Torvalds }/*-------------------------< ABORT_RESEL >----------------------*/,{ 15021da177e4SLinus Torvalds SCR_SET (SCR_ATN), 15031da177e4SLinus Torvalds 0, 15041da177e4SLinus Torvalds SCR_CLR (SCR_ACK), 15051da177e4SLinus Torvalds 0, 15061da177e4SLinus Torvalds /* 15071da177e4SLinus Torvalds * send the abort/abortag/reset message 15081da177e4SLinus Torvalds * we expect an immediate disconnect 15091da177e4SLinus Torvalds */ 15101da177e4SLinus Torvalds SCR_REG_REG (scntl2, SCR_AND, 0x7f), 15111da177e4SLinus Torvalds 0, 15121da177e4SLinus Torvalds SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 15131da177e4SLinus Torvalds HADDR_1 (msgout), 15141da177e4SLinus Torvalds SCR_CLR (SCR_ACK|SCR_ATN), 15151da177e4SLinus Torvalds 0, 15161da177e4SLinus Torvalds SCR_WAIT_DISC, 15171da177e4SLinus Torvalds 0, 15181da177e4SLinus Torvalds SCR_INT, 15191da177e4SLinus Torvalds SIR_RESEL_ABORTED, 15201da177e4SLinus Torvalds SCR_JUMP, 15211da177e4SLinus Torvalds PADDR_A (start), 15221da177e4SLinus Torvalds }/*-------------------------< RESEND_IDENT >---------------------*/,{ 15231da177e4SLinus Torvalds /* 15241da177e4SLinus Torvalds * The target stays in MSG OUT phase after having acked 15251da177e4SLinus Torvalds * Identify [+ Tag [+ Extended message ]]. Targets shall 15261da177e4SLinus Torvalds * behave this way on parity error. 15271da177e4SLinus Torvalds * We must send it again all the messages. 15281da177e4SLinus Torvalds */ 15291da177e4SLinus Torvalds SCR_SET (SCR_ATN), /* Shall be asserted 2 deskew delays before the */ 15301da177e4SLinus Torvalds 0, /* 1rst ACK = 90 ns. Hope the chip isn't too fast */ 15311da177e4SLinus Torvalds SCR_JUMP, 15321da177e4SLinus Torvalds PADDR_A (send_ident), 15331da177e4SLinus Torvalds }/*-------------------------< IDENT_BREAK >----------------------*/,{ 15341da177e4SLinus Torvalds SCR_CLR (SCR_ATN), 15351da177e4SLinus Torvalds 0, 15361da177e4SLinus Torvalds SCR_JUMP, 15371da177e4SLinus Torvalds PADDR_A (select2), 15381da177e4SLinus Torvalds }/*-------------------------< IDENT_BREAK_ATN >------------------*/,{ 15391da177e4SLinus Torvalds SCR_SET (SCR_ATN), 15401da177e4SLinus Torvalds 0, 15411da177e4SLinus Torvalds SCR_JUMP, 15421da177e4SLinus Torvalds PADDR_A (select2), 15431da177e4SLinus Torvalds }/*-------------------------< SDATA_IN >-------------------------*/,{ 15441da177e4SLinus Torvalds SCR_CHMOV_TBL ^ SCR_DATA_IN, 15451da177e4SLinus Torvalds offsetof (struct sym_dsb, sense), 15461da177e4SLinus Torvalds SCR_CALL, 15471da177e4SLinus Torvalds PADDR_A (datai_done), 15481da177e4SLinus Torvalds SCR_JUMP, 15491da177e4SLinus Torvalds PADDR_B (data_ovrun), 15501da177e4SLinus Torvalds }/*-------------------------< RESEL_BAD_LUN >--------------------*/,{ 15511da177e4SLinus Torvalds /* 15521da177e4SLinus Torvalds * Message is an IDENTIFY, but lun is unknown. 15531da177e4SLinus Torvalds * Signal problem to C code for logging the event. 15541da177e4SLinus Torvalds * Send a M_ABORT to clear all pending tasks. 15551da177e4SLinus Torvalds */ 15561da177e4SLinus Torvalds SCR_INT, 15571da177e4SLinus Torvalds SIR_RESEL_BAD_LUN, 15581da177e4SLinus Torvalds SCR_JUMP, 15591da177e4SLinus Torvalds PADDR_B (abort_resel), 15601da177e4SLinus Torvalds }/*-------------------------< BAD_I_T_L >------------------------*/,{ 15611da177e4SLinus Torvalds /* 15621da177e4SLinus Torvalds * We donnot have a task for that I_T_L. 15631da177e4SLinus Torvalds * Signal problem to C code for logging the event. 15641da177e4SLinus Torvalds * Send a M_ABORT message. 15651da177e4SLinus Torvalds */ 15661da177e4SLinus Torvalds SCR_INT, 15671da177e4SLinus Torvalds SIR_RESEL_BAD_I_T_L, 15681da177e4SLinus Torvalds SCR_JUMP, 15691da177e4SLinus Torvalds PADDR_B (abort_resel), 15701da177e4SLinus Torvalds }/*-------------------------< BAD_I_T_L_Q >----------------------*/,{ 15711da177e4SLinus Torvalds /* 15721da177e4SLinus Torvalds * We donnot have a task that matches the tag. 15731da177e4SLinus Torvalds * Signal problem to C code for logging the event. 15741da177e4SLinus Torvalds * Send a M_ABORTTAG message. 15751da177e4SLinus Torvalds */ 15761da177e4SLinus Torvalds SCR_INT, 15771da177e4SLinus Torvalds SIR_RESEL_BAD_I_T_L_Q, 15781da177e4SLinus Torvalds SCR_JUMP, 15791da177e4SLinus Torvalds PADDR_B (abort_resel), 15801da177e4SLinus Torvalds }/*-------------------------< BAD_STATUS >-----------------------*/,{ 15811da177e4SLinus Torvalds /* 15821da177e4SLinus Torvalds * Anything different from INTERMEDIATE 15831da177e4SLinus Torvalds * CONDITION MET should be a bad SCSI status, 15841da177e4SLinus Torvalds * given that GOOD status has already been tested. 15851da177e4SLinus Torvalds * Call the C code. 15861da177e4SLinus Torvalds */ 15871da177e4SLinus Torvalds SCR_LOAD_ABS (scratcha, 4), 15881da177e4SLinus Torvalds PADDR_B (startpos), 15891da177e4SLinus Torvalds SCR_INT ^ IFFALSE (DATA (S_COND_MET)), 15901da177e4SLinus Torvalds SIR_BAD_SCSI_STATUS, 15911da177e4SLinus Torvalds SCR_RETURN, 15921da177e4SLinus Torvalds 0, 15931da177e4SLinus Torvalds }/*-------------------------< PM_HANDLE >------------------------*/,{ 15941da177e4SLinus Torvalds /* 15951da177e4SLinus Torvalds * Phase mismatch handling. 15961da177e4SLinus Torvalds * 15971da177e4SLinus Torvalds * Since we have to deal with 2 SCSI data pointers 15981da177e4SLinus Torvalds * (current and saved), we need at least 2 contexts. 15991da177e4SLinus Torvalds * Each context (pm0 and pm1) has a saved area, a 16001da177e4SLinus Torvalds * SAVE mini-script and a DATA phase mini-script. 16011da177e4SLinus Torvalds */ 16021da177e4SLinus Torvalds /* 16031da177e4SLinus Torvalds * Get the PM handling flags. 16041da177e4SLinus Torvalds */ 16051da177e4SLinus Torvalds SCR_FROM_REG (HF_REG), 16061da177e4SLinus Torvalds 0, 16071da177e4SLinus Torvalds /* 16081da177e4SLinus Torvalds * If no flags (1rst PM for example), avoid 16091da177e4SLinus Torvalds * all the below heavy flags testing. 16101da177e4SLinus Torvalds * This makes the normal case a bit faster. 16111da177e4SLinus Torvalds */ 16121da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED))), 16131da177e4SLinus Torvalds PADDR_B (pm_handle1), 16141da177e4SLinus Torvalds /* 16151da177e4SLinus Torvalds * If we received a SAVE DP, switch to the 16161da177e4SLinus Torvalds * other PM context since the savep may point 16171da177e4SLinus Torvalds * to the current PM context. 16181da177e4SLinus Torvalds */ 16191da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (MASK (HF_DP_SAVED, HF_DP_SAVED)), 16201da177e4SLinus Torvalds 8, 16211da177e4SLinus Torvalds SCR_REG_REG (sfbr, SCR_XOR, HF_ACT_PM), 16221da177e4SLinus Torvalds 0, 16231da177e4SLinus Torvalds /* 16241da177e4SLinus Torvalds * If we have been interrupt in a PM DATA mini-script, 16251da177e4SLinus Torvalds * we take the return address from the corresponding 16261da177e4SLinus Torvalds * saved area. 16271da177e4SLinus Torvalds * This ensure the return address always points to the 16281da177e4SLinus Torvalds * main DATA script for this transfer. 16291da177e4SLinus Torvalds */ 16301da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1))), 16311da177e4SLinus Torvalds PADDR_B (pm_handle1), 16321da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (MASK (HF_IN_PM0, HF_IN_PM0)), 16331da177e4SLinus Torvalds 16, 16341da177e4SLinus Torvalds SCR_LOAD_REL (ia, 4), 16351da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm0.ret), 16361da177e4SLinus Torvalds SCR_JUMP, 16371da177e4SLinus Torvalds PADDR_B (pm_save), 16381da177e4SLinus Torvalds SCR_LOAD_REL (ia, 4), 16391da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm1.ret), 16401da177e4SLinus Torvalds SCR_JUMP, 16411da177e4SLinus Torvalds PADDR_B (pm_save), 16421da177e4SLinus Torvalds }/*-------------------------< PM_HANDLE1 >-----------------------*/,{ 16431da177e4SLinus Torvalds /* 16441da177e4SLinus Torvalds * Normal case. 16451da177e4SLinus Torvalds * Update the return address so that it 16461da177e4SLinus Torvalds * will point after the interrupted MOVE. 16471da177e4SLinus Torvalds */ 16481da177e4SLinus Torvalds SCR_REG_REG (ia, SCR_ADD, 8), 16491da177e4SLinus Torvalds 0, 16501da177e4SLinus Torvalds SCR_REG_REG (ia1, SCR_ADDC, 0), 16511da177e4SLinus Torvalds 0, 16521da177e4SLinus Torvalds }/*-------------------------< PM_SAVE >--------------------------*/,{ 16531da177e4SLinus Torvalds /* 16541da177e4SLinus Torvalds * Clear all the flags that told us if we were 16551da177e4SLinus Torvalds * interrupted in a PM DATA mini-script and/or 16561da177e4SLinus Torvalds * we received a SAVE DP. 16571da177e4SLinus Torvalds */ 16581da177e4SLinus Torvalds SCR_SFBR_REG (HF_REG, SCR_AND, (~(HF_IN_PM0|HF_IN_PM1|HF_DP_SAVED))), 16591da177e4SLinus Torvalds 0, 16601da177e4SLinus Torvalds /* 16611da177e4SLinus Torvalds * Choose the current PM context. 16621da177e4SLinus Torvalds */ 16631da177e4SLinus Torvalds SCR_JUMP ^ IFTRUE (MASK (HF_ACT_PM, HF_ACT_PM)), 16641da177e4SLinus Torvalds PADDR_B (pm1_save), 16651da177e4SLinus Torvalds }/*-------------------------< PM0_SAVE >-------------------------*/,{ 16661da177e4SLinus Torvalds SCR_STORE_REL (ia, 4), 16671da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm0.ret), 16681da177e4SLinus Torvalds /* 16691da177e4SLinus Torvalds * If WSR bit is set, either UA and RBC may 16701da177e4SLinus Torvalds * have to be changed whether the device wants 16711da177e4SLinus Torvalds * to ignore this residue or not. 16721da177e4SLinus Torvalds */ 16731da177e4SLinus Torvalds SCR_FROM_REG (scntl2), 16741da177e4SLinus Torvalds 0, 16751da177e4SLinus Torvalds SCR_CALL ^ IFTRUE (MASK (WSR, WSR)), 16761da177e4SLinus Torvalds PADDR_B (pm_wsr_handle), 16771da177e4SLinus Torvalds /* 16781da177e4SLinus Torvalds * Save the remaining byte count, the updated 16791da177e4SLinus Torvalds * address and the return address. 16801da177e4SLinus Torvalds */ 16811da177e4SLinus Torvalds SCR_STORE_REL (rbc, 4), 16821da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm0.sg.size), 16831da177e4SLinus Torvalds SCR_STORE_REL (ua, 4), 16841da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm0.sg.addr), 16851da177e4SLinus Torvalds /* 16861da177e4SLinus Torvalds * Set the current pointer at the PM0 DATA mini-script. 16871da177e4SLinus Torvalds */ 16881da177e4SLinus Torvalds SCR_LOAD_ABS (ia, 4), 16891da177e4SLinus Torvalds PADDR_B (pm0_data_addr), 16901da177e4SLinus Torvalds }/*-------------------------< PM_SAVE_END >----------------------*/,{ 16911da177e4SLinus Torvalds SCR_STORE_REL (ia, 4), 16921da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.head.lastp), 16931da177e4SLinus Torvalds SCR_JUMP, 16941da177e4SLinus Torvalds PADDR_A (dispatch), 16951da177e4SLinus Torvalds }/*-------------------------< PM1_SAVE >-------------------------*/,{ 16961da177e4SLinus Torvalds SCR_STORE_REL (ia, 4), 16971da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm1.ret), 16981da177e4SLinus Torvalds /* 16991da177e4SLinus Torvalds * If WSR bit is set, either UA and RBC may 17001da177e4SLinus Torvalds * have to be changed whether the device wants 17011da177e4SLinus Torvalds * to ignore this residue or not. 17021da177e4SLinus Torvalds */ 17031da177e4SLinus Torvalds SCR_FROM_REG (scntl2), 17041da177e4SLinus Torvalds 0, 17051da177e4SLinus Torvalds SCR_CALL ^ IFTRUE (MASK (WSR, WSR)), 17061da177e4SLinus Torvalds PADDR_B (pm_wsr_handle), 17071da177e4SLinus Torvalds /* 17081da177e4SLinus Torvalds * Save the remaining byte count, the updated 17091da177e4SLinus Torvalds * address and the return address. 17101da177e4SLinus Torvalds */ 17111da177e4SLinus Torvalds SCR_STORE_REL (rbc, 4), 17121da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm1.sg.size), 17131da177e4SLinus Torvalds SCR_STORE_REL (ua, 4), 17141da177e4SLinus Torvalds offsetof(struct sym_ccb, phys.pm1.sg.addr), 17151da177e4SLinus Torvalds /* 17161da177e4SLinus Torvalds * Set the current pointer at the PM1 DATA mini-script. 17171da177e4SLinus Torvalds */ 17181da177e4SLinus Torvalds SCR_LOAD_ABS (ia, 4), 17191da177e4SLinus Torvalds PADDR_B (pm1_data_addr), 17201da177e4SLinus Torvalds SCR_JUMP, 17211da177e4SLinus Torvalds PADDR_B (pm_save_end), 17221da177e4SLinus Torvalds }/*-------------------------< PM_WSR_HANDLE >--------------------*/,{ 17231da177e4SLinus Torvalds /* 17241da177e4SLinus Torvalds * Phase mismatch handling from SCRIPT with WSR set. 17251da177e4SLinus Torvalds * Such a condition can occur if the chip wants to 17261da177e4SLinus Torvalds * execute a CHMOV(size > 1) when the WSR bit is 17271da177e4SLinus Torvalds * set and the target changes PHASE. 17281da177e4SLinus Torvalds * 17291da177e4SLinus Torvalds * We must move the residual byte to memory. 17301da177e4SLinus Torvalds * 17311da177e4SLinus Torvalds * UA contains bit 0..31 of the address to 17321da177e4SLinus Torvalds * move the residual byte. 17331da177e4SLinus Torvalds * Move it to the table indirect. 17341da177e4SLinus Torvalds */ 17351da177e4SLinus Torvalds SCR_STORE_REL (ua, 4), 17361da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.wresid.addr), 17371da177e4SLinus Torvalds /* 17381da177e4SLinus Torvalds * Increment UA (move address to next position). 17391da177e4SLinus Torvalds */ 17401da177e4SLinus Torvalds SCR_REG_REG (ua, SCR_ADD, 1), 17411da177e4SLinus Torvalds 0, 17421da177e4SLinus Torvalds SCR_REG_REG (ua1, SCR_ADDC, 0), 17431da177e4SLinus Torvalds 0, 17441da177e4SLinus Torvalds SCR_REG_REG (ua2, SCR_ADDC, 0), 17451da177e4SLinus Torvalds 0, 17461da177e4SLinus Torvalds SCR_REG_REG (ua3, SCR_ADDC, 0), 17471da177e4SLinus Torvalds 0, 17481da177e4SLinus Torvalds /* 17491da177e4SLinus Torvalds * Compute SCRATCHA as: 17501da177e4SLinus Torvalds * - size to transfer = 1 byte. 17511da177e4SLinus Torvalds * - bit 24..31 = high address bit [32...39]. 17521da177e4SLinus Torvalds */ 17531da177e4SLinus Torvalds SCR_LOAD_ABS (scratcha, 4), 17541da177e4SLinus Torvalds PADDR_B (zero), 17551da177e4SLinus Torvalds SCR_REG_REG (scratcha, SCR_OR, 1), 17561da177e4SLinus Torvalds 0, 17571da177e4SLinus Torvalds SCR_FROM_REG (rbc3), 17581da177e4SLinus Torvalds 0, 17591da177e4SLinus Torvalds SCR_TO_REG (scratcha3), 17601da177e4SLinus Torvalds 0, 17611da177e4SLinus Torvalds /* 17621da177e4SLinus Torvalds * Move this value to the table indirect. 17631da177e4SLinus Torvalds */ 17641da177e4SLinus Torvalds SCR_STORE_REL (scratcha, 4), 17651da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.wresid.size), 17661da177e4SLinus Torvalds /* 17671da177e4SLinus Torvalds * Wait for a valid phase. 17681da177e4SLinus Torvalds * While testing with bogus QUANTUM drives, the C1010 17691da177e4SLinus Torvalds * sometimes raised a spurious phase mismatch with 17701da177e4SLinus Torvalds * WSR and the CHMOV(1) triggered another PM. 1771c03983acSJean Delvare * Waiting explicitly for the PHASE seemed to avoid 17721da177e4SLinus Torvalds * the nested phase mismatch. Btw, this didn't happen 17731da177e4SLinus Torvalds * using my IBM drives. 17741da177e4SLinus Torvalds */ 17751da177e4SLinus Torvalds SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)), 17761da177e4SLinus Torvalds 0, 17771da177e4SLinus Torvalds /* 17781da177e4SLinus Torvalds * Perform the move of the residual byte. 17791da177e4SLinus Torvalds */ 17801da177e4SLinus Torvalds SCR_CHMOV_TBL ^ SCR_DATA_IN, 17811da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.wresid), 17821da177e4SLinus Torvalds /* 17831da177e4SLinus Torvalds * We can now handle the phase mismatch with UA fixed. 17841da177e4SLinus Torvalds * RBC[0..23]=0 is a special case that does not require 17851da177e4SLinus Torvalds * a PM context. The C code also checks against this. 17861da177e4SLinus Torvalds */ 17871da177e4SLinus Torvalds SCR_FROM_REG (rbc), 17881da177e4SLinus Torvalds 0, 17891da177e4SLinus Torvalds SCR_RETURN ^ IFFALSE (DATA (0)), 17901da177e4SLinus Torvalds 0, 17911da177e4SLinus Torvalds SCR_FROM_REG (rbc1), 17921da177e4SLinus Torvalds 0, 17931da177e4SLinus Torvalds SCR_RETURN ^ IFFALSE (DATA (0)), 17941da177e4SLinus Torvalds 0, 17951da177e4SLinus Torvalds SCR_FROM_REG (rbc2), 17961da177e4SLinus Torvalds 0, 17971da177e4SLinus Torvalds SCR_RETURN ^ IFFALSE (DATA (0)), 17981da177e4SLinus Torvalds 0, 17991da177e4SLinus Torvalds /* 18001da177e4SLinus Torvalds * RBC[0..23]=0. 18011da177e4SLinus Torvalds * Not only we donnot need a PM context, but this would 18021da177e4SLinus Torvalds * lead to a bogus CHMOV(0). This condition means that 18031da177e4SLinus Torvalds * the residual was the last byte to move from this CHMOV. 18041da177e4SLinus Torvalds * So, we just have to move the current data script pointer 18051da177e4SLinus Torvalds * (i.e. TEMP) to the SCRIPTS address following the 18061da177e4SLinus Torvalds * interrupted CHMOV and jump to dispatcher. 18071da177e4SLinus Torvalds * IA contains the data pointer to save. 18081da177e4SLinus Torvalds */ 18091da177e4SLinus Torvalds SCR_JUMP, 18101da177e4SLinus Torvalds PADDR_B (pm_save_end), 18111da177e4SLinus Torvalds }/*-------------------------< WSR_MA_HELPER >--------------------*/,{ 18121da177e4SLinus Torvalds /* 18131da177e4SLinus Torvalds * Helper for the C code when WSR bit is set. 18141da177e4SLinus Torvalds * Perform the move of the residual byte. 18151da177e4SLinus Torvalds */ 18161da177e4SLinus Torvalds SCR_CHMOV_TBL ^ SCR_DATA_IN, 18171da177e4SLinus Torvalds offsetof (struct sym_ccb, phys.wresid), 18181da177e4SLinus Torvalds SCR_JUMP, 18191da177e4SLinus Torvalds PADDR_A (dispatch), 18201da177e4SLinus Torvalds 18211da177e4SLinus Torvalds }/*-------------------------< ZERO >-----------------------------*/,{ 18221da177e4SLinus Torvalds SCR_DATA_ZERO, 18231da177e4SLinus Torvalds }/*-------------------------< SCRATCH >--------------------------*/,{ 18241da177e4SLinus Torvalds SCR_DATA_ZERO, 18251da177e4SLinus Torvalds }/*-------------------------< PM0_DATA_ADDR >--------------------*/,{ 18261da177e4SLinus Torvalds SCR_DATA_ZERO, 18271da177e4SLinus Torvalds }/*-------------------------< PM1_DATA_ADDR >--------------------*/,{ 18281da177e4SLinus Torvalds SCR_DATA_ZERO, 18291da177e4SLinus Torvalds }/*-------------------------< DONE_POS >-------------------------*/,{ 18301da177e4SLinus Torvalds SCR_DATA_ZERO, 18311da177e4SLinus Torvalds }/*-------------------------< STARTPOS >-------------------------*/,{ 18321da177e4SLinus Torvalds SCR_DATA_ZERO, 18331da177e4SLinus Torvalds }/*-------------------------< TARGTBL >--------------------------*/,{ 18341da177e4SLinus Torvalds SCR_DATA_ZERO, 18351da177e4SLinus Torvalds }/*-------------------------<>-----------------------------------*/ 18361da177e4SLinus Torvalds }; 18371da177e4SLinus Torvalds 18381da177e4SLinus Torvalds static struct SYM_FWZ_SCR SYM_FWZ_SCR = { 18391da177e4SLinus Torvalds /*-------------------------< SNOOPTEST >------------------------*/{ 18401da177e4SLinus Torvalds /* 18411da177e4SLinus Torvalds * Read the variable from memory. 18421da177e4SLinus Torvalds */ 18431da177e4SLinus Torvalds SCR_LOAD_REL (scratcha, 4), 18441da177e4SLinus Torvalds offsetof(struct sym_hcb, scratch), 18451da177e4SLinus Torvalds /* 18461da177e4SLinus Torvalds * Write the variable to memory. 18471da177e4SLinus Torvalds */ 18481da177e4SLinus Torvalds SCR_STORE_REL (temp, 4), 18491da177e4SLinus Torvalds offsetof(struct sym_hcb, scratch), 18501da177e4SLinus Torvalds /* 18511da177e4SLinus Torvalds * Read back the variable from memory. 18521da177e4SLinus Torvalds */ 18531da177e4SLinus Torvalds SCR_LOAD_REL (temp, 4), 18541da177e4SLinus Torvalds offsetof(struct sym_hcb, scratch), 18551da177e4SLinus Torvalds }/*-------------------------< SNOOPEND >-------------------------*/,{ 18561da177e4SLinus Torvalds /* 18571da177e4SLinus Torvalds * And stop. 18581da177e4SLinus Torvalds */ 18591da177e4SLinus Torvalds SCR_INT, 18601da177e4SLinus Torvalds 99, 18611da177e4SLinus Torvalds }/*-------------------------<>-----------------------------------*/ 18621da177e4SLinus Torvalds }; 1863