1863 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 4 * of PCI-SCSI IO processors.5 *6 * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>7 *8 * This driver is derived from the Linux sym53c8xx driver.9 * Copyright (C) 1998-2000 Gerard Roudier10 *11 * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 12 * a port of the FreeBSD ncr driver to Linux-1.2.13.13 *14 * The original ncr driver has been written for 386bsd and FreeBSD by15 * Wolfgang Stanglmeier <wolf@cologne.de>16 * Stefan Esser <se@mi.Uni-Koeln.de>17 * Copyright (C) 1994 Wolfgang Stanglmeier18 *19 * Other major contributions:20 *21 * NVRAM detection and reading.22 * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>23 *24 *-----------------------------------------------------------------------------25 */26 27/*28 * Scripts for SYMBIOS-Processor29 *30 * We have to know the offsets of all labels before we reach 31 * them (for forward jumps). Therefore we declare a struct 32 * here. If you make changes inside the script,33 *34 * DONT FORGET TO CHANGE THE LENGTHS HERE!35 */36 37/*38 * Script fragments which are loaded into the on-chip RAM 39 * of 825A, 875, 876, 895, 895A, 896 and 1010 chips.40 * Must not exceed 4K bytes.41 */42struct SYM_FWA_SCR {43 u32 start [ 14];44 u32 getjob_begin [ 4];45 u32 getjob_end [ 4];46#ifdef SYM_CONF_TARGET_ROLE_SUPPORT47 u32 select [ 6];48#else49 u32 select [ 4];50#endif51#if SYM_CONF_DMA_ADDRESSING_MODE == 252 u32 is_dmap_dirty [ 4];53#endif54 u32 wf_sel_done [ 2];55 u32 sel_done [ 2];56 u32 send_ident [ 2];57#ifdef SYM_CONF_IARB_SUPPORT58 u32 select2 [ 8];59#else60 u32 select2 [ 2];61#endif62 u32 command [ 2];63 u32 dispatch [ 28];64 u32 sel_no_cmd [ 10];65 u32 init [ 6];66 u32 clrack [ 4];67 u32 datai_done [ 10];68 u32 datai_done_wsr [ 20];69 u32 datao_done [ 10];70 u32 datao_done_wss [ 6];71 u32 datai_phase [ 4];72 u32 datao_phase [ 6];73 u32 msg_in [ 2];74 u32 msg_in2 [ 10];75#ifdef SYM_CONF_IARB_SUPPORT76 u32 status [ 14];77#else78 u32 status [ 10];79#endif80 u32 complete [ 6];81 u32 complete2 [ 12];82 u32 done [ 14];83 u32 done_end [ 2];84 u32 complete_error [ 4];85 u32 save_dp [ 12];86 u32 restore_dp [ 8];87 u32 disconnect [ 12];88#ifdef SYM_CONF_IARB_SUPPORT89 u32 idle [ 4];90#else91 u32 idle [ 2];92#endif93#ifdef SYM_CONF_IARB_SUPPORT94 u32 ungetjob [ 6];95#else96 u32 ungetjob [ 4];97#endif98#ifdef SYM_CONF_TARGET_ROLE_SUPPORT99 u32 reselect [ 4];100#else101 u32 reselect [ 2];102#endif103 u32 reselected [ 22];104 u32 resel_scntl4 [ 20];105 u32 resel_lun0 [ 6];106#if SYM_CONF_MAX_TASK*4 > 512107 u32 resel_tag [ 26];108#elif SYM_CONF_MAX_TASK*4 > 256109 u32 resel_tag [ 20];110#else111 u32 resel_tag [ 16];112#endif113 u32 resel_dsa [ 2];114 u32 resel_dsa1 [ 4];115 u32 resel_no_tag [ 6];116 u32 data_in [SYM_CONF_MAX_SG * 2];117 u32 data_in2 [ 4];118 u32 data_out [SYM_CONF_MAX_SG * 2];119 u32 data_out2 [ 4];120 u32 pm0_data [ 12];121 u32 pm0_data_out [ 6];122 u32 pm0_data_end [ 6];123 u32 pm1_data [ 12];124 u32 pm1_data_out [ 6];125 u32 pm1_data_end [ 6];126};127 128/*129 * Script fragments which stay in main memory for all chips 130 * except for chips that support 8K on-chip RAM.131 */132struct SYM_FWB_SCR {133 u32 start64 [ 2];134 u32 no_data [ 2];135#ifdef SYM_CONF_TARGET_ROLE_SUPPORT136 u32 sel_for_abort [ 18];137#else138 u32 sel_for_abort [ 16];139#endif140 u32 sel_for_abort_1 [ 2];141 u32 msg_in_etc [ 12];142 u32 msg_received [ 4];143 u32 msg_weird_seen [ 4];144 u32 msg_extended [ 20];145 u32 msg_bad [ 6];146 u32 msg_weird [ 4];147 u32 msg_weird1 [ 8];148 149 u32 wdtr_resp [ 6];150 u32 send_wdtr [ 4];151 u32 sdtr_resp [ 6];152 u32 send_sdtr [ 4];153 u32 ppr_resp [ 6];154 u32 send_ppr [ 4];155 u32 nego_bad_phase [ 4];156 u32 msg_out [ 4];157 u32 msg_out_done [ 4];158 u32 data_ovrun [ 2];159 u32 data_ovrun1 [ 22];160 u32 data_ovrun2 [ 8];161 u32 abort_resel [ 16];162 u32 resend_ident [ 4];163 u32 ident_break [ 4];164 u32 ident_break_atn [ 4];165 u32 sdata_in [ 6];166 u32 resel_bad_lun [ 4];167 u32 bad_i_t_l [ 4];168 u32 bad_i_t_l_q [ 4];169 u32 bad_status [ 6];170 u32 pm_handle [ 20];171 u32 pm_handle1 [ 4];172 u32 pm_save [ 4];173 u32 pm0_save [ 12];174 u32 pm_save_end [ 4];175 u32 pm1_save [ 14];176 177 /* WSR handling */178 u32 pm_wsr_handle [ 38];179 u32 wsr_ma_helper [ 4];180 181 /* Data area */182 u32 zero [ 1];183 u32 scratch [ 1];184 u32 pm0_data_addr [ 1];185 u32 pm1_data_addr [ 1];186 u32 done_pos [ 1];187 u32 startpos [ 1];188 u32 targtbl [ 1];189};190 191/*192 * Script fragments used at initialisations.193 * Only runs out of main memory.194 */195struct SYM_FWZ_SCR {196 u32 snooptest [ 6];197 u32 snoopend [ 2];198};199 200static struct SYM_FWA_SCR SYM_FWA_SCR = {201/*--------------------------< START >----------------------------*/ {202 /*203 * Switch the LED on.204 * Will be patched with a NO_OP if LED205 * not needed or not desired.206 */207 SCR_REG_REG (gpreg, SCR_AND, 0xfe),208 0,209 /*210 * Clear SIGP.211 */212 SCR_FROM_REG (ctest2),213 0,214 /*215 * Stop here if the C code wants to perform 216 * some error recovery procedure manually.217 * (Indicate this by setting SEM in ISTAT)218 */219 SCR_FROM_REG (istat),220 0,221 /*222 * Report to the C code the next position in 223 * the start queue the SCRIPTS will schedule.224 * The C code must not change SCRATCHA.225 */226 SCR_LOAD_ABS (scratcha, 4),227 PADDR_B (startpos),228 SCR_INT ^ IFTRUE (MASK (SEM, SEM)),229 SIR_SCRIPT_STOPPED,230 /*231 * Start the next job.232 *233 * @DSA = start point for this job.234 * SCRATCHA = address of this job in the start queue.235 *236 * We will restore startpos with SCRATCHA if we fails the 237 * arbitration or if it is the idle job.238 *239 * The below GETJOB_BEGIN to GETJOB_END section of SCRIPTS 240 * is a critical path. If it is partially executed, it then 241 * may happen that the job address is not yet in the DSA 242 * and the next queue position points to the next JOB.243 */244 SCR_LOAD_ABS (dsa, 4),245 PADDR_B (startpos),246 SCR_LOAD_REL (temp, 4),247 4,248}/*-------------------------< GETJOB_BEGIN >---------------------*/,{249 SCR_STORE_ABS (temp, 4),250 PADDR_B (startpos),251 SCR_LOAD_REL (dsa, 4),252 0,253}/*-------------------------< GETJOB_END >-----------------------*/,{254 SCR_LOAD_REL (temp, 4),255 0,256 SCR_RETURN,257 0,258}/*-------------------------< SELECT >---------------------------*/,{259 /*260 * DSA contains the address of a scheduled261 * data structure.262 *263 * SCRATCHA contains the address of the start queue 264 * entry which points to the next job.265 *266 * Set Initiator mode.267 *268 * (Target mode is left as an exercise for the reader)269 */270#ifdef SYM_CONF_TARGET_ROLE_SUPPORT271 SCR_CLR (SCR_TRG),272 0,273#endif274 /*275 * And try to select this target.276 */277 SCR_SEL_TBL_ATN ^ offsetof (struct sym_dsb, select),278 PADDR_A (ungetjob),279 /*280 * Now there are 4 possibilities:281 *282 * (1) The chip loses arbitration.283 * This is ok, because it will try again,284 * when the bus becomes idle.285 * (But beware of the timeout function!)286 *287 * (2) The chip is reselected.288 * Then the script processor takes the jump289 * to the RESELECT label.290 *291 * (3) The chip wins arbitration.292 * Then it will execute SCRIPTS instruction until 293 * the next instruction that checks SCSI phase.294 * Then will stop and wait for selection to be 295 * complete or selection time-out to occur.296 *297 * After having won arbitration, the SCRIPTS 298 * processor is able to execute instructions while 299 * the SCSI core is performing SCSI selection.300 */301 /*302 * Initialize the status registers303 */304 SCR_LOAD_REL (scr0, 4),305 offsetof (struct sym_ccb, phys.head.status),306 /*307 * We may need help from CPU if the DMA segment 308 * registers aren't up-to-date for this IO.309 * Patched with NOOP for chips that donnot 310 * support DAC addressing.311 */312#if SYM_CONF_DMA_ADDRESSING_MODE == 2313}/*-------------------------< IS_DMAP_DIRTY >--------------------*/,{314 SCR_FROM_REG (HX_REG),315 0,316 SCR_INT ^ IFTRUE (MASK (HX_DMAP_DIRTY, HX_DMAP_DIRTY)),317 SIR_DMAP_DIRTY,318#endif319}/*-------------------------< WF_SEL_DONE >----------------------*/,{320 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),321 SIR_SEL_ATN_NO_MSG_OUT,322}/*-------------------------< SEL_DONE >-------------------------*/,{323 /*324 * C1010-33 errata work-around.325 * Due to a race, the SCSI core may not have 326 * loaded SCNTL3 on SEL_TBL instruction.327 * We reload it once phase is stable.328 * Patched with a NOOP for other chips.329 */330 SCR_LOAD_REL (scntl3, 1),331 offsetof(struct sym_dsb, select.sel_scntl3),332}/*-------------------------< SEND_IDENT >-----------------------*/,{333 /*334 * Selection complete.335 * Send the IDENTIFY and possibly the TAG message 336 * and negotiation message if present.337 */338 SCR_MOVE_TBL ^ SCR_MSG_OUT,339 offsetof (struct sym_dsb, smsg),340}/*-------------------------< SELECT2 >--------------------------*/,{341#ifdef SYM_CONF_IARB_SUPPORT342 /*343 * Set IMMEDIATE ARBITRATION if we have been given 344 * a hint to do so. (Some job to do after this one).345 */346 SCR_FROM_REG (HF_REG),347 0,348 SCR_JUMPR ^ IFFALSE (MASK (HF_HINT_IARB, HF_HINT_IARB)),349 8,350 SCR_REG_REG (scntl1, SCR_OR, IARB),351 0,352#endif353 /*354 * Anticipate the COMMAND phase.355 * This is the PHASE we expect at this point.356 */357 SCR_JUMP ^ IFFALSE (WHEN (SCR_COMMAND)),358 PADDR_A (sel_no_cmd),359}/*-------------------------< COMMAND >--------------------------*/,{360 /*361 * ... and send the command362 */363 SCR_MOVE_TBL ^ SCR_COMMAND,364 offsetof (struct sym_dsb, cmd),365}/*-------------------------< DISPATCH >-------------------------*/,{366 /*367 * MSG_IN is the only phase that shall be 368 * entered at least once for each (re)selection.369 * So we test it first.370 */371 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),372 PADDR_A (msg_in),373 SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)),374 PADDR_A (datao_phase),375 SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)),376 PADDR_A (datai_phase),377 SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)),378 PADDR_A (status),379 SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)),380 PADDR_A (command),381 SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),382 PADDR_B (msg_out),383 /*384 * Discard as many illegal phases as 385 * required and tell the C code about.386 */387 SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_OUT)),388 16,389 SCR_MOVE_ABS (1) ^ SCR_ILG_OUT,390 HADDR_1 (scratch),391 SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_OUT)),392 -16,393 SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_IN)),394 16,395 SCR_MOVE_ABS (1) ^ SCR_ILG_IN,396 HADDR_1 (scratch),397 SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_IN)),398 -16,399 SCR_INT,400 SIR_BAD_PHASE,401 SCR_JUMP,402 PADDR_A (dispatch),403}/*-------------------------< SEL_NO_CMD >-----------------------*/,{404 /*405 * The target does not switch to command 406 * phase after IDENTIFY has been sent.407 *408 * If it stays in MSG OUT phase send it 409 * the IDENTIFY again.410 */411 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),412 PADDR_B (resend_ident),413 /*414 * If target does not switch to MSG IN phase 415 * and we sent a negotiation, assert the 416 * failure immediately.417 */418 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),419 PADDR_A (dispatch),420 SCR_FROM_REG (HS_REG),421 0,422 SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),423 SIR_NEGO_FAILED,424 /*425 * Jump to dispatcher.426 */427 SCR_JUMP,428 PADDR_A (dispatch),429}/*-------------------------< INIT >-----------------------------*/,{430 /*431 * Wait for the SCSI RESET signal to be 432 * inactive before restarting operations, 433 * since the chip may hang on SEL_ATN 434 * if SCSI RESET is active.435 */436 SCR_FROM_REG (sstat0),437 0,438 SCR_JUMPR ^ IFTRUE (MASK (IRST, IRST)),439 -16,440 SCR_JUMP,441 PADDR_A (start),442}/*-------------------------< CLRACK >---------------------------*/,{443 /*444 * Terminate possible pending message phase.445 */446 SCR_CLR (SCR_ACK),447 0,448 SCR_JUMP,449 PADDR_A (dispatch),450}/*-------------------------< DATAI_DONE >-----------------------*/,{451 /*452 * Save current pointer to LASTP.453 */454 SCR_STORE_REL (temp, 4),455 offsetof (struct sym_ccb, phys.head.lastp),456 /*457 * If the SWIDE is not full, jump to dispatcher.458 * We anticipate a STATUS phase.459 */460 SCR_FROM_REG (scntl2),461 0,462 SCR_JUMP ^ IFTRUE (MASK (WSR, WSR)),463 PADDR_A (datai_done_wsr),464 SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)),465 PADDR_A (status),466 SCR_JUMP,467 PADDR_A (dispatch),468}/*-------------------------< DATAI_DONE_WSR >-------------------*/,{469 /*470 * The SWIDE is full.471 * Clear this condition.472 */473 SCR_REG_REG (scntl2, SCR_OR, WSR),474 0,475 /*476 * We are expecting an IGNORE RESIDUE message 477 * from the device, otherwise we are in data 478 * overrun condition. Check against MSG_IN phase.479 */480 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),481 SIR_SWIDE_OVERRUN,482 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),483 PADDR_A (dispatch),484 /*485 * We are in MSG_IN phase,486 * Read the first byte of the message.487 * If it is not an IGNORE RESIDUE message,488 * signal overrun and jump to message 489 * processing.490 */491 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,492 HADDR_1 (msgin[0]),493 SCR_INT ^ IFFALSE (DATA (M_IGN_RESIDUE)),494 SIR_SWIDE_OVERRUN,495 SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)),496 PADDR_A (msg_in2),497 /*498 * We got the message we expected.499 * Read the 2nd byte, and jump to dispatcher.500 */501 SCR_CLR (SCR_ACK),502 0,503 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,504 HADDR_1 (msgin[1]),505 SCR_CLR (SCR_ACK),506 0,507 SCR_JUMP,508 PADDR_A (dispatch),509}/*-------------------------< DATAO_DONE >-----------------------*/,{510 /*511 * Save current pointer to LASTP.512 */513 SCR_STORE_REL (temp, 4),514 offsetof (struct sym_ccb, phys.head.lastp),515 /*516 * If the SODL is not full jump to dispatcher.517 * We anticipate a STATUS phase.518 */519 SCR_FROM_REG (scntl2),520 0,521 SCR_JUMP ^ IFTRUE (MASK (WSS, WSS)),522 PADDR_A (datao_done_wss),523 SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)),524 PADDR_A (status),525 SCR_JUMP,526 PADDR_A (dispatch),527}/*-------------------------< DATAO_DONE_WSS >-------------------*/,{528 /*529 * The SODL is full, clear this condition.530 */531 SCR_REG_REG (scntl2, SCR_OR, WSS),532 0,533 /*534 * And signal a DATA UNDERRUN condition 535 * to the C code.536 */537 SCR_INT,538 SIR_SODL_UNDERRUN,539 SCR_JUMP,540 PADDR_A (dispatch),541}/*-------------------------< DATAI_PHASE >----------------------*/,{542 /*543 * Jump to current pointer.544 */545 SCR_LOAD_REL (temp, 4),546 offsetof (struct sym_ccb, phys.head.lastp),547 SCR_RETURN,548 0,549}/*-------------------------< DATAO_PHASE >----------------------*/,{550 /*551 * C1010-66 errata work-around.552 * Extra clocks of data hold must be inserted 553 * in DATA OUT phase on 33 MHz PCI BUS.554 * Patched with a NOOP for other chips.555 */556 SCR_REG_REG (scntl4, SCR_OR, (XCLKH_DT|XCLKH_ST)),557 0,558 /*559 * Jump to current pointer.560 */561 SCR_LOAD_REL (temp, 4),562 offsetof (struct sym_ccb, phys.head.lastp),563 SCR_RETURN,564 0,565}/*-------------------------< MSG_IN >---------------------------*/,{566 /*567 * Get the first byte of the message.568 *569 * The script processor doesn't negate the570 * ACK signal after this transfer.571 */572 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,573 HADDR_1 (msgin[0]),574}/*-------------------------< MSG_IN2 >--------------------------*/,{575 /*576 * Check first against 1 byte messages 577 * that we handle from SCRIPTS.578 */579 SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),580 PADDR_A (complete),581 SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),582 PADDR_A (disconnect),583 SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),584 PADDR_A (save_dp),585 SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),586 PADDR_A (restore_dp),587 /*588 * We handle all other messages from the 589 * C code, so no need to waste on-chip RAM 590 * for those ones.591 */592 SCR_JUMP,593 PADDR_B (msg_in_etc),594}/*-------------------------< STATUS >---------------------------*/,{595 /*596 * get the status597 */598 SCR_MOVE_ABS (1) ^ SCR_STATUS,599 HADDR_1 (scratch),600#ifdef SYM_CONF_IARB_SUPPORT601 /*602 * If STATUS is not GOOD, clear IMMEDIATE ARBITRATION, 603 * since we may have to tamper the start queue from 604 * the C code.605 */606 SCR_JUMPR ^ IFTRUE (DATA (S_GOOD)),607 8,608 SCR_REG_REG (scntl1, SCR_AND, ~IARB),609 0,610#endif611 /*612 * save status to scsi_status.613 * mark as complete.614 */615 SCR_TO_REG (SS_REG),616 0,617 SCR_LOAD_REG (HS_REG, HS_COMPLETE),618 0,619 /*620 * Anticipate the MESSAGE PHASE for 621 * the TASK COMPLETE message.622 */623 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),624 PADDR_A (msg_in),625 SCR_JUMP,626 PADDR_A (dispatch),627}/*-------------------------< COMPLETE >-------------------------*/,{628 /*629 * Complete message.630 *631 * When we terminate the cycle by clearing ACK,632 * the target may disconnect immediately.633 *634 * We don't want to be told of an "unexpected disconnect",635 * so we disable this feature.636 */637 SCR_REG_REG (scntl2, SCR_AND, 0x7f),638 0,639 /*640 * Terminate cycle ...641 */642 SCR_CLR (SCR_ACK|SCR_ATN),643 0,644 /*645 * ... and wait for the disconnect.646 */647 SCR_WAIT_DISC,648 0,649}/*-------------------------< COMPLETE2 >------------------------*/,{650 /*651 * Save host status.652 */653 SCR_STORE_REL (scr0, 4),654 offsetof (struct sym_ccb, phys.head.status),655 /*656 * Some bridges may reorder DMA writes to memory.657 * We donnot want the CPU to deal with completions 658 * without all the posted write having been flushed 659 * to memory. This DUMMY READ should flush posted 660 * buffers prior to the CPU having to deal with 661 * completions.662 */663 SCR_LOAD_REL (scr0, 4), /* DUMMY READ */664 offsetof (struct sym_ccb, phys.head.status),665 666 /*667 * If command resulted in not GOOD status,668 * call the C code if needed.669 */670 SCR_FROM_REG (SS_REG),671 0,672 SCR_CALL ^ IFFALSE (DATA (S_GOOD)),673 PADDR_B (bad_status),674 /*675 * If we performed an auto-sense, call 676 * the C code to synchronyze task aborts 677 * with UNIT ATTENTION conditions.678 */679 SCR_FROM_REG (HF_REG),680 0,681 SCR_JUMP ^ IFFALSE (MASK (0 ,(HF_SENSE|HF_EXT_ERR))),682 PADDR_A (complete_error),683}/*-------------------------< DONE >-----------------------------*/,{684 /*685 * Copy the DSA to the DONE QUEUE and 686 * signal completion to the host.687 * If we are interrupted between DONE 688 * and DONE_END, we must reset, otherwise 689 * the completed CCB may be lost.690 */691 SCR_STORE_ABS (dsa, 4),692 PADDR_B (scratch),693 SCR_LOAD_ABS (dsa, 4),694 PADDR_B (done_pos),695 SCR_LOAD_ABS (scratcha, 4),696 PADDR_B (scratch),697 SCR_STORE_REL (scratcha, 4),698 0,699 /*700 * The instruction below reads the DONE QUEUE next 701 * free position from memory.702 * In addition it ensures that all PCI posted writes 703 * are flushed and so the DSA value of the done 704 * CCB is visible by the CPU before INTFLY is raised.705 */706 SCR_LOAD_REL (scratcha, 4),707 4,708 SCR_INT_FLY,709 0,710 SCR_STORE_ABS (scratcha, 4),711 PADDR_B (done_pos),712}/*-------------------------< DONE_END >-------------------------*/,{713 SCR_JUMP,714 PADDR_A (start),715}/*-------------------------< COMPLETE_ERROR >-------------------*/,{716 SCR_LOAD_ABS (scratcha, 4),717 PADDR_B (startpos),718 SCR_INT,719 SIR_COMPLETE_ERROR,720}/*-------------------------< SAVE_DP >--------------------------*/,{721 /*722 * Clear ACK immediately.723 * No need to delay it.724 */725 SCR_CLR (SCR_ACK),726 0,727 /*728 * Keep track we received a SAVE DP, so 729 * we will switch to the other PM context 730 * on the next PM since the DP may point 731 * to the current PM context.732 */733 SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED),734 0,735 /*736 * SAVE_DP message:737 * Copy LASTP to SAVEP.738 */739 SCR_LOAD_REL (scratcha, 4),740 offsetof (struct sym_ccb, phys.head.lastp),741 SCR_STORE_REL (scratcha, 4),742 offsetof (struct sym_ccb, phys.head.savep),743 /*744 * Anticipate the MESSAGE PHASE for 745 * the DISCONNECT message.746 */747 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),748 PADDR_A (msg_in),749 SCR_JUMP,750 PADDR_A (dispatch),751}/*-------------------------< RESTORE_DP >-----------------------*/,{752 /*753 * Clear ACK immediately.754 * No need to delay it.755 */756 SCR_CLR (SCR_ACK),757 0,758 /*759 * Copy SAVEP to LASTP.760 */761 SCR_LOAD_REL (scratcha, 4),762 offsetof (struct sym_ccb, phys.head.savep),763 SCR_STORE_REL (scratcha, 4),764 offsetof (struct sym_ccb, phys.head.lastp),765 SCR_JUMP,766 PADDR_A (dispatch),767}/*-------------------------< DISCONNECT >-----------------------*/,{768 /*769 * DISCONNECTing ...770 *771 * disable the "unexpected disconnect" feature,772 * and remove the ACK signal.773 */774 SCR_REG_REG (scntl2, SCR_AND, 0x7f),775 0,776 SCR_CLR (SCR_ACK|SCR_ATN),777 0,778 /*779 * Wait for the disconnect.780 */781 SCR_WAIT_DISC,782 0,783 /*784 * Status is: DISCONNECTED.785 */786 SCR_LOAD_REG (HS_REG, HS_DISCONNECT),787 0,788 /*789 * Save host status.790 */791 SCR_STORE_REL (scr0, 4),792 offsetof (struct sym_ccb, phys.head.status),793 SCR_JUMP,794 PADDR_A (start),795}/*-------------------------< IDLE >-----------------------------*/,{796 /*797 * Nothing to do?798 * Switch the LED off and wait for reselect.799 * Will be patched with a NO_OP if LED800 * not needed or not desired.801 */802 SCR_REG_REG (gpreg, SCR_OR, 0x01),803 0,804#ifdef SYM_CONF_IARB_SUPPORT805 SCR_JUMPR,806 8,807#endif808}/*-------------------------< UNGETJOB >-------------------------*/,{809#ifdef SYM_CONF_IARB_SUPPORT810 /*811 * Set IMMEDIATE ARBITRATION, for the next time.812 * This will give us better chance to win arbitration 813 * for the job we just wanted to do.814 */815 SCR_REG_REG (scntl1, SCR_OR, IARB),816 0,817#endif818 /*819 * We are not able to restart the SCRIPTS if we are 820 * interrupted and these instruction haven't been 821 * all executed. BTW, this is very unlikely to 822 * happen, but we check that from the C code.823 */824 SCR_LOAD_REG (dsa, 0xff),825 0,826 SCR_STORE_ABS (scratcha, 4),827 PADDR_B (startpos),828}/*-------------------------< RESELECT >-------------------------*/,{829#ifdef SYM_CONF_TARGET_ROLE_SUPPORT830 /*831 * Make sure we are in initiator mode.832 */833 SCR_CLR (SCR_TRG),834 0,835#endif836 /*837 * Sleep waiting for a reselection.838 */839 SCR_WAIT_RESEL,840 PADDR_A(start),841}/*-------------------------< RESELECTED >-----------------------*/,{842 /*843 * Switch the LED on.844 * Will be patched with a NO_OP if LED845 * not needed or not desired.846 */847 SCR_REG_REG (gpreg, SCR_AND, 0xfe),848 0,849 /*850 * load the target id into the sdid851 */852 SCR_REG_SFBR (ssid, SCR_AND, 0x8F),853 0,854 SCR_TO_REG (sdid),855 0,856 /*857 * Load the target control block address858 */859 SCR_LOAD_ABS (dsa, 4),860 PADDR_B (targtbl),861 SCR_SFBR_REG (dsa, SCR_SHL, 0),862 0,863 SCR_REG_REG (dsa, SCR_SHL, 0),864 0,865 SCR_REG_REG (dsa, SCR_AND, 0x3c),866 0,867 SCR_LOAD_REL (dsa, 4),868 0,869 /*870 * We expect MESSAGE IN phase.871 * If not, get help from the C code.872 */873 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),874 SIR_RESEL_NO_MSG_IN,875 /*876 * Load the legacy synchronous transfer registers.877 */878 SCR_LOAD_REL (scntl3, 1),879 offsetof(struct sym_tcb, head.wval),880 SCR_LOAD_REL (sxfer, 1),881 offsetof(struct sym_tcb, head.sval),882}/*-------------------------< RESEL_SCNTL4 >---------------------*/,{883 /*884 * The C1010 uses a new synchronous timing scheme.885 * Will be patched with a NO_OP if not a C1010.886 */887 SCR_LOAD_REL (scntl4, 1),888 offsetof(struct sym_tcb, head.uval),889 /*890 * Get the IDENTIFY message.891 */892 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,893 HADDR_1 (msgin),894 /*895 * If IDENTIFY LUN #0, use a faster path 896 * to find the LCB structure.897 */898 SCR_JUMP ^ IFTRUE (MASK (0x80, 0xbf)),899 PADDR_A (resel_lun0),900 /*901 * If message isn't an IDENTIFY, 902 * tell the C code about.903 */904 SCR_INT ^ IFFALSE (MASK (0x80, 0x80)),905 SIR_RESEL_NO_IDENTIFY,906 /*907 * It is an IDENTIFY message,908 * Load the LUN control block address.909 */910 SCR_LOAD_REL (dsa, 4),911 offsetof(struct sym_tcb, head.luntbl_sa),912 SCR_SFBR_REG (dsa, SCR_SHL, 0),913 0,914 SCR_REG_REG (dsa, SCR_SHL, 0),915 0,916 SCR_REG_REG (dsa, SCR_AND, 0xfc),917 0,918 SCR_LOAD_REL (dsa, 4),919 0,920 SCR_JUMPR,921 8,922}/*-------------------------< RESEL_LUN0 >-----------------------*/,{923 /*924 * LUN 0 special case (but usual one :))925 */926 SCR_LOAD_REL (dsa, 4),927 offsetof(struct sym_tcb, head.lun0_sa),928 /*929 * Jump indirectly to the reselect action for this LUN.930 */931 SCR_LOAD_REL (temp, 4),932 offsetof(struct sym_lcb, head.resel_sa),933 SCR_RETURN,934 0,935 /* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */936}/*-------------------------< RESEL_TAG >------------------------*/,{937 /*938 * ACK the IDENTIFY previously received.939 */940 SCR_CLR (SCR_ACK),941 0,942 /*943 * It shall be a tagged command.944 * Read SIMPLE+TAG.945 * The C code will deal with errors.946 * Aggressive optimization, isn't it? :)947 */948 SCR_MOVE_ABS (2) ^ SCR_MSG_IN,949 HADDR_1 (msgin),950 /*951 * Load the pointer to the tagged task 952 * table for this LUN.953 */954 SCR_LOAD_REL (dsa, 4),955 offsetof(struct sym_lcb, head.itlq_tbl_sa),956 /*957 * The SIDL still contains the TAG value.958 * Aggressive optimization, isn't it? :):)959 */960 SCR_REG_SFBR (sidl, SCR_SHL, 0),961 0,962#if SYM_CONF_MAX_TASK*4 > 512963 SCR_JUMPR ^ IFFALSE (CARRYSET),964 8,965 SCR_REG_REG (dsa1, SCR_OR, 2),966 0,967 SCR_REG_REG (sfbr, SCR_SHL, 0),968 0,969 SCR_JUMPR ^ IFFALSE (CARRYSET),970 8,971 SCR_REG_REG (dsa1, SCR_OR, 1),972 0,973#elif SYM_CONF_MAX_TASK*4 > 256974 SCR_JUMPR ^ IFFALSE (CARRYSET),975 8,976 SCR_REG_REG (dsa1, SCR_OR, 1),977 0,978#endif979 /*980 * Retrieve the DSA of this task.981 * JUMP indirectly to the restart point of the CCB.982 */983 SCR_SFBR_REG (dsa, SCR_AND, 0xfc),984 0,985 SCR_LOAD_REL (dsa, 4),986 0,987 SCR_LOAD_REL (temp, 4),988 offsetof(struct sym_ccb, phys.head.go.restart),989 SCR_RETURN,990 0,991 /* In normal situations we branch to RESEL_DSA */992}/*-------------------------< RESEL_DSA >------------------------*/,{993 /*994 * ACK the IDENTIFY or TAG previously received.995 */996 SCR_CLR (SCR_ACK),997 0,998}/*-------------------------< RESEL_DSA1 >-----------------------*/,{999 /*1000 * Initialize the status registers1001 */1002 SCR_LOAD_REL (scr0, 4),1003 offsetof (struct sym_ccb, phys.head.status),1004 /*1005 * Jump to dispatcher.1006 */1007 SCR_JUMP,1008 PADDR_A (dispatch),1009}/*-------------------------< RESEL_NO_TAG >---------------------*/,{1010 /*1011 * Load the DSA with the unique ITL task.1012 */1013 SCR_LOAD_REL (dsa, 4),1014 offsetof(struct sym_lcb, head.itl_task_sa),1015 /*1016 * JUMP indirectly to the restart point of the CCB.1017 */1018 SCR_LOAD_REL (temp, 4),1019 offsetof(struct sym_ccb, phys.head.go.restart),1020 SCR_RETURN,1021 0,1022 /* In normal situations we branch to RESEL_DSA */1023}/*-------------------------< DATA_IN >--------------------------*/,{1024/*1025 * Because the size depends on the1026 * #define SYM_CONF_MAX_SG parameter,1027 * it is filled in at runtime.1028 *1029 * ##===========< i=0; i<SYM_CONF_MAX_SG >=========1030 * || SCR_CHMOV_TBL ^ SCR_DATA_IN,1031 * || offsetof (struct sym_dsb, data[ i]),1032 * ##==========================================1033 */103401035}/*-------------------------< DATA_IN2 >-------------------------*/,{1036 SCR_CALL,1037 PADDR_A (datai_done),1038 SCR_JUMP,1039 PADDR_B (data_ovrun),1040}/*-------------------------< DATA_OUT >-------------------------*/,{1041/*1042 * Because the size depends on the1043 * #define SYM_CONF_MAX_SG parameter,1044 * it is filled in at runtime.1045 *1046 * ##===========< i=0; i<SYM_CONF_MAX_SG >=========1047 * || SCR_CHMOV_TBL ^ SCR_DATA_OUT,1048 * || offsetof (struct sym_dsb, data[ i]),1049 * ##==========================================1050 */105101052}/*-------------------------< DATA_OUT2 >------------------------*/,{1053 SCR_CALL,1054 PADDR_A (datao_done),1055 SCR_JUMP,1056 PADDR_B (data_ovrun),1057}/*-------------------------< PM0_DATA >-------------------------*/,{1058 /*1059 * Read our host flags to SFBR, so we will be able 1060 * to check against the data direction we expect.1061 */1062 SCR_FROM_REG (HF_REG),1063 0,1064 /*1065 * Check against actual DATA PHASE.1066 */1067 SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),1068 PADDR_A (pm0_data_out),1069 /*1070 * Actual phase is DATA IN.1071 * Check against expected direction.1072 */1073 SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),1074 PADDR_B (data_ovrun),1075 /*1076 * Keep track we are moving data from the 1077 * PM0 DATA mini-script.1078 */1079 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),1080 0,1081 /*1082 * Move the data to memory.1083 */1084 SCR_CHMOV_TBL ^ SCR_DATA_IN,1085 offsetof (struct sym_ccb, phys.pm0.sg),1086 SCR_JUMP,1087 PADDR_A (pm0_data_end),1088}/*-------------------------< PM0_DATA_OUT >---------------------*/,{1089 /*1090 * Actual phase is DATA OUT.1091 * Check against expected direction.1092 */1093 SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),1094 PADDR_B (data_ovrun),1095 /*1096 * Keep track we are moving data from the 1097 * PM0 DATA mini-script.1098 */1099 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),1100 0,1101 /*1102 * Move the data from memory.1103 */1104 SCR_CHMOV_TBL ^ SCR_DATA_OUT,1105 offsetof (struct sym_ccb, phys.pm0.sg),1106}/*-------------------------< PM0_DATA_END >---------------------*/,{1107 /*1108 * Clear the flag that told we were moving 1109 * data from the PM0 DATA mini-script.1110 */1111 SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)),1112 0,1113 /*1114 * Return to the previous DATA script which 1115 * is guaranteed by design (if no bug) to be 1116 * the main DATA script for this transfer.1117 */1118 SCR_LOAD_REL (temp, 4),1119 offsetof (struct sym_ccb, phys.pm0.ret),1120 SCR_RETURN,1121 0,1122}/*-------------------------< PM1_DATA >-------------------------*/,{1123 /*1124 * Read our host flags to SFBR, so we will be able 1125 * to check against the data direction we expect.1126 */1127 SCR_FROM_REG (HF_REG),1128 0,1129 /*1130 * Check against actual DATA PHASE.1131 */1132 SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),1133 PADDR_A (pm1_data_out),1134 /*1135 * Actual phase is DATA IN.1136 * Check against expected direction.1137 */1138 SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),1139 PADDR_B (data_ovrun),1140 /*1141 * Keep track we are moving data from the 1142 * PM1 DATA mini-script.1143 */1144 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),1145 0,1146 /*1147 * Move the data to memory.1148 */1149 SCR_CHMOV_TBL ^ SCR_DATA_IN,1150 offsetof (struct sym_ccb, phys.pm1.sg),1151 SCR_JUMP,1152 PADDR_A (pm1_data_end),1153}/*-------------------------< PM1_DATA_OUT >---------------------*/,{1154 /*1155 * Actual phase is DATA OUT.1156 * Check against expected direction.1157 */1158 SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),1159 PADDR_B (data_ovrun),1160 /*1161 * Keep track we are moving data from the 1162 * PM1 DATA mini-script.1163 */1164 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),1165 0,1166 /*1167 * Move the data from memory.1168 */1169 SCR_CHMOV_TBL ^ SCR_DATA_OUT,1170 offsetof (struct sym_ccb, phys.pm1.sg),1171}/*-------------------------< PM1_DATA_END >---------------------*/,{1172 /*1173 * Clear the flag that told we were moving 1174 * data from the PM1 DATA mini-script.1175 */1176 SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)),1177 0,1178 /*1179 * Return to the previous DATA script which 1180 * is guaranteed by design (if no bug) to be 1181 * the main DATA script for this transfer.1182 */1183 SCR_LOAD_REL (temp, 4),1184 offsetof (struct sym_ccb, phys.pm1.ret),1185 SCR_RETURN,1186 0,1187}/*-------------------------<>-----------------------------------*/1188};1189 1190static struct SYM_FWB_SCR SYM_FWB_SCR = {1191/*--------------------------< START64 >--------------------------*/ {1192 /*1193 * SCRIPT entry point for the 895A, 896 and 1010.1194 * For now, there is no specific stuff for those 1195 * chips at this point, but this may come.1196 */1197 SCR_JUMP,1198 PADDR_A (init),1199}/*-------------------------< NO_DATA >--------------------------*/,{1200 SCR_JUMP,1201 PADDR_B (data_ovrun),1202}/*-------------------------< SEL_FOR_ABORT >--------------------*/,{1203 /*1204 * We are jumped here by the C code, if we have 1205 * some target to reset or some disconnected 1206 * job to abort. Since error recovery is a serious 1207 * busyness, we will really reset the SCSI BUS, if 1208 * case of a SCSI interrupt occurring in this path.1209 */1210#ifdef SYM_CONF_TARGET_ROLE_SUPPORT1211 /*1212 * Set initiator mode.1213 */1214 SCR_CLR (SCR_TRG),1215 0,1216#endif1217 /*1218 * And try to select this target.1219 */1220 SCR_SEL_TBL_ATN ^ offsetof (struct sym_hcb, abrt_sel),1221 PADDR_A (reselect),1222 /*1223 * Wait for the selection to complete or 1224 * the selection to time out.1225 */1226 SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)),1227 -8,1228 /*1229 * Call the C code.1230 */1231 SCR_INT,1232 SIR_TARGET_SELECTED,1233 /*1234 * The C code should let us continue here. 1235 * Send the 'kiss of death' message.1236 * We expect an immediate disconnect once 1237 * the target has eaten the message.1238 */1239 SCR_REG_REG (scntl2, SCR_AND, 0x7f),1240 0,1241 SCR_MOVE_TBL ^ SCR_MSG_OUT,1242 offsetof (struct sym_hcb, abrt_tbl),1243 SCR_CLR (SCR_ACK|SCR_ATN),1244 0,1245 SCR_WAIT_DISC,1246 0,1247 /*1248 * Tell the C code that we are done.1249 */1250 SCR_INT,1251 SIR_ABORT_SENT,1252}/*-------------------------< SEL_FOR_ABORT_1 >------------------*/,{1253 /*1254 * Jump at scheduler.1255 */1256 SCR_JUMP,1257 PADDR_A (start),1258}/*-------------------------< MSG_IN_ETC >-----------------------*/,{1259 /*1260 * If it is an EXTENDED (variable size message)1261 * Handle it.1262 */1263 SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),1264 PADDR_B (msg_extended),1265 /*1266 * Let the C code handle any other 1267 * 1 byte message.1268 */1269 SCR_JUMP ^ IFTRUE (MASK (0x00, 0xf0)),1270 PADDR_B (msg_received),1271 SCR_JUMP ^ IFTRUE (MASK (0x10, 0xf0)),1272 PADDR_B (msg_received),1273 /*1274 * We donnot handle 2 bytes messages from SCRIPTS.1275 * So, let the C code deal with these ones too.1276 */1277 SCR_JUMP ^ IFFALSE (MASK (0x20, 0xf0)),1278 PADDR_B (msg_weird_seen),1279 SCR_CLR (SCR_ACK),1280 0,1281 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,1282 HADDR_1 (msgin[1]),1283}/*-------------------------< MSG_RECEIVED >---------------------*/,{1284 SCR_LOAD_REL (scratcha, 4), /* DUMMY READ */1285 0,1286 SCR_INT,1287 SIR_MSG_RECEIVED,1288}/*-------------------------< MSG_WEIRD_SEEN >-------------------*/,{1289 SCR_LOAD_REL (scratcha, 4), /* DUMMY READ */1290 0,1291 SCR_INT,1292 SIR_MSG_WEIRD,1293}/*-------------------------< MSG_EXTENDED >---------------------*/,{1294 /*1295 * Clear ACK and get the next byte 1296 * assumed to be the message length.1297 */1298 SCR_CLR (SCR_ACK),1299 0,1300 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,1301 HADDR_1 (msgin[1]),1302 /*1303 * Try to catch some unlikely situations as 0 length 1304 * or too large the length.1305 */1306 SCR_JUMP ^ IFTRUE (DATA (0)),1307 PADDR_B (msg_weird_seen),1308 SCR_TO_REG (scratcha),1309 0,1310 SCR_REG_REG (sfbr, SCR_ADD, (256-8)),1311 0,1312 SCR_JUMP ^ IFTRUE (CARRYSET),1313 PADDR_B (msg_weird_seen),1314 /*1315 * We donnot handle extended messages from SCRIPTS.1316 * Read the amount of data corresponding to the 1317 * message length and call the C code.1318 */1319 SCR_STORE_REL (scratcha, 1),1320 offsetof (struct sym_dsb, smsg_ext.size),1321 SCR_CLR (SCR_ACK),1322 0,1323 SCR_MOVE_TBL ^ SCR_MSG_IN,1324 offsetof (struct sym_dsb, smsg_ext),1325 SCR_JUMP,1326 PADDR_B (msg_received),1327}/*-------------------------< MSG_BAD >--------------------------*/,{1328 /*1329 * unimplemented message - reject it.1330 */1331 SCR_INT,1332 SIR_REJECT_TO_SEND,1333 SCR_SET (SCR_ATN),1334 0,1335 SCR_JUMP,1336 PADDR_A (clrack),1337}/*-------------------------< MSG_WEIRD >------------------------*/,{1338 /*1339 * weird message received1340 * ignore all MSG IN phases and reject it.1341 */1342 SCR_INT,1343 SIR_REJECT_TO_SEND,1344 SCR_SET (SCR_ATN),1345 0,1346}/*-------------------------< MSG_WEIRD1 >-----------------------*/,{1347 SCR_CLR (SCR_ACK),1348 0,1349 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),1350 PADDR_A (dispatch),1351 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,1352 HADDR_1 (scratch),1353 SCR_JUMP,1354 PADDR_B (msg_weird1),1355}/*-------------------------< WDTR_RESP >------------------------*/,{1356 /*1357 * let the target fetch our answer.1358 */1359 SCR_SET (SCR_ATN),1360 0,1361 SCR_CLR (SCR_ACK),1362 0,1363 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),1364 PADDR_B (nego_bad_phase),1365}/*-------------------------< SEND_WDTR >------------------------*/,{1366 /*1367 * Send the M_X_WIDE_REQ1368 */1369 SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,1370 HADDR_1 (msgout),1371 SCR_JUMP,1372 PADDR_B (msg_out_done),1373}/*-------------------------< SDTR_RESP >------------------------*/,{1374 /*1375 * let the target fetch our answer.1376 */1377 SCR_SET (SCR_ATN),1378 0,1379 SCR_CLR (SCR_ACK),1380 0,1381 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),1382 PADDR_B (nego_bad_phase),1383}/*-------------------------< SEND_SDTR >------------------------*/,{1384 /*1385 * Send the M_X_SYNC_REQ1386 */1387 SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,1388 HADDR_1 (msgout),1389 SCR_JUMP,1390 PADDR_B (msg_out_done),1391}/*-------------------------< PPR_RESP >-------------------------*/,{1392 /*1393 * let the target fetch our answer.1394 */1395 SCR_SET (SCR_ATN),1396 0,1397 SCR_CLR (SCR_ACK),1398 0,1399 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),1400 PADDR_B (nego_bad_phase),1401}/*-------------------------< SEND_PPR >-------------------------*/,{1402 /*1403 * Send the M_X_PPR_REQ1404 */1405 SCR_MOVE_ABS (8) ^ SCR_MSG_OUT,1406 HADDR_1 (msgout),1407 SCR_JUMP,1408 PADDR_B (msg_out_done),1409}/*-------------------------< NEGO_BAD_PHASE >-------------------*/,{1410 SCR_INT,1411 SIR_NEGO_PROTO,1412 SCR_JUMP,1413 PADDR_A (dispatch),1414}/*-------------------------< MSG_OUT >--------------------------*/,{1415 /*1416 * The target requests a message.1417 * We donnot send messages that may 1418 * require the device to go to bus free.1419 */1420 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,1421 HADDR_1 (msgout),1422 /*1423 * ... wait for the next phase1424 * if it's a message out, send it again, ...1425 */1426 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),1427 PADDR_B (msg_out),1428}/*-------------------------< MSG_OUT_DONE >---------------------*/,{1429 /*1430 * Let the C code be aware of the 1431 * sent message and clear the message.1432 */1433 SCR_INT,1434 SIR_MSG_OUT_DONE,1435 /*1436 * ... and process the next phase1437 */1438 SCR_JUMP,1439 PADDR_A (dispatch),1440}/*-------------------------< DATA_OVRUN >-----------------------*/,{1441 /*1442 * Use scratcha to count the extra bytes.1443 */1444 SCR_LOAD_ABS (scratcha, 4),1445 PADDR_B (zero),1446}/*-------------------------< DATA_OVRUN1 >----------------------*/,{1447 /*1448 * The target may want to transfer too much data.1449 *1450 * If phase is DATA OUT write 1 byte and count it.1451 */1452 SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),1453 16,1454 SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT,1455 HADDR_1 (scratch),1456 SCR_JUMP,1457 PADDR_B (data_ovrun2),1458 /*1459 * If WSR is set, clear this condition, and 1460 * count this byte.1461 */1462 SCR_FROM_REG (scntl2),1463 0,1464 SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),1465 16,1466 SCR_REG_REG (scntl2, SCR_OR, WSR),1467 0,1468 SCR_JUMP,1469 PADDR_B (data_ovrun2),1470 /*1471 * Finally check against DATA IN phase.1472 * Signal data overrun to the C code 1473 * and jump to dispatcher if not so.1474 * Read 1 byte otherwise and count it.1475 */1476 SCR_JUMPR ^ IFTRUE (WHEN (SCR_DATA_IN)),1477 16,1478 SCR_INT,1479 SIR_DATA_OVERRUN,1480 SCR_JUMP,1481 PADDR_A (dispatch),1482 SCR_CHMOV_ABS (1) ^ SCR_DATA_IN,1483 HADDR_1 (scratch),1484}/*-------------------------< DATA_OVRUN2 >----------------------*/,{1485 /*1486 * Count this byte.1487 * This will allow to return a negative 1488 * residual to user.1489 */1490 SCR_REG_REG (scratcha, SCR_ADD, 0x01),1491 0,1492 SCR_REG_REG (scratcha1, SCR_ADDC, 0),1493 0,1494 SCR_REG_REG (scratcha2, SCR_ADDC, 0),1495 0,1496 /*1497 * .. and repeat as required.1498 */1499 SCR_JUMP,1500 PADDR_B (data_ovrun1),1501}/*-------------------------< ABORT_RESEL >----------------------*/,{1502 SCR_SET (SCR_ATN),1503 0,1504 SCR_CLR (SCR_ACK),1505 0,1506 /*1507 * send the abort/abortag/reset message1508 * we expect an immediate disconnect1509 */1510 SCR_REG_REG (scntl2, SCR_AND, 0x7f),1511 0,1512 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,1513 HADDR_1 (msgout),1514 SCR_CLR (SCR_ACK|SCR_ATN),1515 0,1516 SCR_WAIT_DISC,1517 0,1518 SCR_INT,1519 SIR_RESEL_ABORTED,1520 SCR_JUMP,1521 PADDR_A (start),1522}/*-------------------------< RESEND_IDENT >---------------------*/,{1523 /*1524 * The target stays in MSG OUT phase after having acked 1525 * Identify [+ Tag [+ Extended message ]]. Targets shall1526 * behave this way on parity error.1527 * We must send it again all the messages.1528 */1529 SCR_SET (SCR_ATN), /* Shall be asserted 2 deskew delays before the */1530 0, /* 1rst ACK = 90 ns. Hope the chip isn't too fast */1531 SCR_JUMP,1532 PADDR_A (send_ident),1533}/*-------------------------< IDENT_BREAK >----------------------*/,{1534 SCR_CLR (SCR_ATN),1535 0,1536 SCR_JUMP,1537 PADDR_A (select2),1538}/*-------------------------< IDENT_BREAK_ATN >------------------*/,{1539 SCR_SET (SCR_ATN),1540 0,1541 SCR_JUMP,1542 PADDR_A (select2),1543}/*-------------------------< SDATA_IN >-------------------------*/,{1544 SCR_CHMOV_TBL ^ SCR_DATA_IN,1545 offsetof (struct sym_dsb, sense),1546 SCR_CALL,1547 PADDR_A (datai_done),1548 SCR_JUMP,1549 PADDR_B (data_ovrun),1550}/*-------------------------< RESEL_BAD_LUN >--------------------*/,{1551 /*1552 * Message is an IDENTIFY, but lun is unknown.1553 * Signal problem to C code for logging the event.1554 * Send a M_ABORT to clear all pending tasks.1555 */1556 SCR_INT,1557 SIR_RESEL_BAD_LUN,1558 SCR_JUMP,1559 PADDR_B (abort_resel),1560}/*-------------------------< BAD_I_T_L >------------------------*/,{1561 /*1562 * We donnot have a task for that I_T_L.1563 * Signal problem to C code for logging the event.1564 * Send a M_ABORT message.1565 */1566 SCR_INT,1567 SIR_RESEL_BAD_I_T_L,1568 SCR_JUMP,1569 PADDR_B (abort_resel),1570}/*-------------------------< BAD_I_T_L_Q >----------------------*/,{1571 /*1572 * We donnot have a task that matches the tag.1573 * Signal problem to C code for logging the event.1574 * Send a M_ABORTTAG message.1575 */1576 SCR_INT,1577 SIR_RESEL_BAD_I_T_L_Q,1578 SCR_JUMP,1579 PADDR_B (abort_resel),1580}/*-------------------------< BAD_STATUS >-----------------------*/,{1581 /*1582 * Anything different from INTERMEDIATE 1583 * CONDITION MET should be a bad SCSI status, 1584 * given that GOOD status has already been tested.1585 * Call the C code.1586 */1587 SCR_LOAD_ABS (scratcha, 4),1588 PADDR_B (startpos),1589 SCR_INT ^ IFFALSE (DATA (S_COND_MET)),1590 SIR_BAD_SCSI_STATUS,1591 SCR_RETURN,1592 0,1593}/*-------------------------< PM_HANDLE >------------------------*/,{1594 /*1595 * Phase mismatch handling.1596 *1597 * Since we have to deal with 2 SCSI data pointers 1598 * (current and saved), we need at least 2 contexts.1599 * Each context (pm0 and pm1) has a saved area, a 1600 * SAVE mini-script and a DATA phase mini-script.1601 */1602 /*1603 * Get the PM handling flags.1604 */1605 SCR_FROM_REG (HF_REG),1606 0,1607 /*1608 * If no flags (1rst PM for example), avoid 1609 * all the below heavy flags testing.1610 * This makes the normal case a bit faster.1611 */1612 SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED))),1613 PADDR_B (pm_handle1),1614 /*1615 * If we received a SAVE DP, switch to the 1616 * other PM context since the savep may point 1617 * to the current PM context.1618 */1619 SCR_JUMPR ^ IFFALSE (MASK (HF_DP_SAVED, HF_DP_SAVED)),1620 8,1621 SCR_REG_REG (sfbr, SCR_XOR, HF_ACT_PM),1622 0,1623 /*1624 * If we have been interrupt in a PM DATA mini-script,1625 * we take the return address from the corresponding 1626 * saved area.1627 * This ensure the return address always points to the 1628 * main DATA script for this transfer.1629 */1630 SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1))),1631 PADDR_B (pm_handle1),1632 SCR_JUMPR ^ IFFALSE (MASK (HF_IN_PM0, HF_IN_PM0)),1633 16,1634 SCR_LOAD_REL (ia, 4),1635 offsetof(struct sym_ccb, phys.pm0.ret),1636 SCR_JUMP,1637 PADDR_B (pm_save),1638 SCR_LOAD_REL (ia, 4),1639 offsetof(struct sym_ccb, phys.pm1.ret),1640 SCR_JUMP,1641 PADDR_B (pm_save),1642}/*-------------------------< PM_HANDLE1 >-----------------------*/,{1643 /*1644 * Normal case.1645 * Update the return address so that it 1646 * will point after the interrupted MOVE.1647 */1648 SCR_REG_REG (ia, SCR_ADD, 8),1649 0,1650 SCR_REG_REG (ia1, SCR_ADDC, 0),1651 0,1652}/*-------------------------< PM_SAVE >--------------------------*/,{1653 /*1654 * Clear all the flags that told us if we were 1655 * interrupted in a PM DATA mini-script and/or 1656 * we received a SAVE DP.1657 */1658 SCR_SFBR_REG (HF_REG, SCR_AND, (~(HF_IN_PM0|HF_IN_PM1|HF_DP_SAVED))),1659 0,1660 /*1661 * Choose the current PM context.1662 */1663 SCR_JUMP ^ IFTRUE (MASK (HF_ACT_PM, HF_ACT_PM)),1664 PADDR_B (pm1_save),1665}/*-------------------------< PM0_SAVE >-------------------------*/,{1666 SCR_STORE_REL (ia, 4),1667 offsetof(struct sym_ccb, phys.pm0.ret),1668 /*1669 * If WSR bit is set, either UA and RBC may 1670 * have to be changed whether the device wants 1671 * to ignore this residue or not.1672 */1673 SCR_FROM_REG (scntl2),1674 0,1675 SCR_CALL ^ IFTRUE (MASK (WSR, WSR)),1676 PADDR_B (pm_wsr_handle),1677 /*1678 * Save the remaining byte count, the updated 1679 * address and the return address.1680 */1681 SCR_STORE_REL (rbc, 4),1682 offsetof(struct sym_ccb, phys.pm0.sg.size),1683 SCR_STORE_REL (ua, 4),1684 offsetof(struct sym_ccb, phys.pm0.sg.addr),1685 /*1686 * Set the current pointer at the PM0 DATA mini-script.1687 */1688 SCR_LOAD_ABS (ia, 4),1689 PADDR_B (pm0_data_addr),1690}/*-------------------------< PM_SAVE_END >----------------------*/,{1691 SCR_STORE_REL (ia, 4),1692 offsetof(struct sym_ccb, phys.head.lastp),1693 SCR_JUMP,1694 PADDR_A (dispatch),1695}/*-------------------------< PM1_SAVE >-------------------------*/,{1696 SCR_STORE_REL (ia, 4),1697 offsetof(struct sym_ccb, phys.pm1.ret),1698 /*1699 * If WSR bit is set, either UA and RBC may 1700 * have to be changed whether the device wants 1701 * to ignore this residue or not.1702 */1703 SCR_FROM_REG (scntl2),1704 0,1705 SCR_CALL ^ IFTRUE (MASK (WSR, WSR)),1706 PADDR_B (pm_wsr_handle),1707 /*1708 * Save the remaining byte count, the updated 1709 * address and the return address.1710 */1711 SCR_STORE_REL (rbc, 4),1712 offsetof(struct sym_ccb, phys.pm1.sg.size),1713 SCR_STORE_REL (ua, 4),1714 offsetof(struct sym_ccb, phys.pm1.sg.addr),1715 /*1716 * Set the current pointer at the PM1 DATA mini-script.1717 */1718 SCR_LOAD_ABS (ia, 4),1719 PADDR_B (pm1_data_addr),1720 SCR_JUMP,1721 PADDR_B (pm_save_end),1722}/*-------------------------< PM_WSR_HANDLE >--------------------*/,{1723 /*1724 * Phase mismatch handling from SCRIPT with WSR set.1725 * Such a condition can occur if the chip wants to 1726 * execute a CHMOV(size > 1) when the WSR bit is 1727 * set and the target changes PHASE.1728 *1729 * We must move the residual byte to memory.1730 *1731 * UA contains bit 0..31 of the address to 1732 * move the residual byte.1733 * Move it to the table indirect.1734 */1735 SCR_STORE_REL (ua, 4),1736 offsetof (struct sym_ccb, phys.wresid.addr),1737 /*1738 * Increment UA (move address to next position).1739 */1740 SCR_REG_REG (ua, SCR_ADD, 1),1741 0,1742 SCR_REG_REG (ua1, SCR_ADDC, 0),1743 0,1744 SCR_REG_REG (ua2, SCR_ADDC, 0),1745 0,1746 SCR_REG_REG (ua3, SCR_ADDC, 0),1747 0,1748 /*1749 * Compute SCRATCHA as:1750 * - size to transfer = 1 byte.1751 * - bit 24..31 = high address bit [32...39].1752 */1753 SCR_LOAD_ABS (scratcha, 4),1754 PADDR_B (zero),1755 SCR_REG_REG (scratcha, SCR_OR, 1),1756 0,1757 SCR_FROM_REG (rbc3),1758 0,1759 SCR_TO_REG (scratcha3),1760 0,1761 /*1762 * Move this value to the table indirect.1763 */1764 SCR_STORE_REL (scratcha, 4),1765 offsetof (struct sym_ccb, phys.wresid.size),1766 /*1767 * Wait for a valid phase.1768 * While testing with bogus QUANTUM drives, the C1010 1769 * sometimes raised a spurious phase mismatch with 1770 * WSR and the CHMOV(1) triggered another PM.1771 * Waiting explicitly for the PHASE seemed to avoid1772 * the nested phase mismatch. Btw, this didn't happen 1773 * using my IBM drives.1774 */1775 SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)),1776 0,1777 /*1778 * Perform the move of the residual byte.1779 */1780 SCR_CHMOV_TBL ^ SCR_DATA_IN,1781 offsetof (struct sym_ccb, phys.wresid),1782 /*1783 * We can now handle the phase mismatch with UA fixed.1784 * RBC[0..23]=0 is a special case that does not require 1785 * a PM context. The C code also checks against this.1786 */1787 SCR_FROM_REG (rbc),1788 0,1789 SCR_RETURN ^ IFFALSE (DATA (0)),1790 0,1791 SCR_FROM_REG (rbc1),1792 0,1793 SCR_RETURN ^ IFFALSE (DATA (0)),1794 0,1795 SCR_FROM_REG (rbc2),1796 0,1797 SCR_RETURN ^ IFFALSE (DATA (0)),1798 0,1799 /*1800 * RBC[0..23]=0.1801 * Not only we donnot need a PM context, but this would 1802 * lead to a bogus CHMOV(0). This condition means that 1803 * the residual was the last byte to move from this CHMOV.1804 * So, we just have to move the current data script pointer 1805 * (i.e. TEMP) to the SCRIPTS address following the 1806 * interrupted CHMOV and jump to dispatcher.1807 * IA contains the data pointer to save.1808 */1809 SCR_JUMP,1810 PADDR_B (pm_save_end),1811}/*-------------------------< WSR_MA_HELPER >--------------------*/,{1812 /*1813 * Helper for the C code when WSR bit is set.1814 * Perform the move of the residual byte.1815 */1816 SCR_CHMOV_TBL ^ SCR_DATA_IN,1817 offsetof (struct sym_ccb, phys.wresid),1818 SCR_JUMP,1819 PADDR_A (dispatch),1820 1821}/*-------------------------< ZERO >-----------------------------*/,{1822 SCR_DATA_ZERO,1823}/*-------------------------< SCRATCH >--------------------------*/,{1824 SCR_DATA_ZERO,1825}/*-------------------------< PM0_DATA_ADDR >--------------------*/,{1826 SCR_DATA_ZERO,1827}/*-------------------------< PM1_DATA_ADDR >--------------------*/,{1828 SCR_DATA_ZERO,1829}/*-------------------------< DONE_POS >-------------------------*/,{1830 SCR_DATA_ZERO,1831}/*-------------------------< STARTPOS >-------------------------*/,{1832 SCR_DATA_ZERO,1833}/*-------------------------< TARGTBL >--------------------------*/,{1834 SCR_DATA_ZERO,1835}/*-------------------------<>-----------------------------------*/1836};1837 1838static struct SYM_FWZ_SCR SYM_FWZ_SCR = {1839 /*-------------------------< SNOOPTEST >------------------------*/{1840 /*1841 * Read the variable from memory.1842 */1843 SCR_LOAD_REL (scratcha, 4),1844 offsetof(struct sym_hcb, scratch),1845 /*1846 * Write the variable to memory.1847 */1848 SCR_STORE_REL (temp, 4),1849 offsetof(struct sym_hcb, scratch),1850 /*1851 * Read back the variable from memory.1852 */1853 SCR_LOAD_REL (temp, 4),1854 offsetof(struct sym_hcb, scratch),1855}/*-------------------------< SNOOPEND >-------------------------*/,{1856 /*1857 * And stop.1858 */1859 SCR_INT,1860 99,1861}/*-------------------------<>-----------------------------------*/1862};1863