xref: /openbmc/linux/drivers/scsi/sym53c8xx_2/sym_fw2.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
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