1778 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 [ 11];44 u32 getjob_begin [ 4];45 u32 _sms_a10 [ 5];46 u32 getjob_end [ 4];47 u32 _sms_a20 [ 4];48#ifdef SYM_CONF_TARGET_ROLE_SUPPORT49 u32 select [ 8];50#else51 u32 select [ 6];52#endif53 u32 _sms_a30 [ 5];54 u32 wf_sel_done [ 2];55 u32 send_ident [ 2];56#ifdef SYM_CONF_IARB_SUPPORT57 u32 select2 [ 8];58#else59 u32 select2 [ 2];60#endif61 u32 command [ 2];62 u32 dispatch [ 28];63 u32 sel_no_cmd [ 10];64 u32 init [ 6];65 u32 clrack [ 4];66 u32 datai_done [ 11];67 u32 datai_done_wsr [ 20];68 u32 datao_done [ 11];69 u32 datao_done_wss [ 6];70 u32 datai_phase [ 5];71 u32 datao_phase [ 5];72 u32 msg_in [ 2];73 u32 msg_in2 [ 10];74#ifdef SYM_CONF_IARB_SUPPORT75 u32 status [ 14];76#else77 u32 status [ 10];78#endif79 u32 complete [ 6];80 u32 complete2 [ 8];81 u32 _sms_a40 [ 12];82 u32 done [ 5];83 u32 _sms_a50 [ 5];84 u32 _sms_a60 [ 2];85 u32 done_end [ 4];86 u32 complete_error [ 5];87 u32 save_dp [ 11];88 u32 restore_dp [ 7];89 u32 disconnect [ 11];90 u32 disconnect2 [ 5];91 u32 _sms_a65 [ 3];92#ifdef SYM_CONF_IARB_SUPPORT93 u32 idle [ 4];94#else95 u32 idle [ 2];96#endif97#ifdef SYM_CONF_IARB_SUPPORT98 u32 ungetjob [ 7];99#else100 u32 ungetjob [ 5];101#endif102#ifdef SYM_CONF_TARGET_ROLE_SUPPORT103 u32 reselect [ 4];104#else105 u32 reselect [ 2];106#endif107 u32 reselected [ 19];108 u32 _sms_a70 [ 6];109 u32 _sms_a80 [ 4];110 u32 reselected1 [ 25];111 u32 _sms_a90 [ 4];112 u32 resel_lun0 [ 7];113 u32 _sms_a100 [ 4];114 u32 resel_tag [ 8];115#if SYM_CONF_MAX_TASK*4 > 512116 u32 _sms_a110 [ 23];117#elif SYM_CONF_MAX_TASK*4 > 256118 u32 _sms_a110 [ 17];119#else120 u32 _sms_a110 [ 13];121#endif122 u32 _sms_a120 [ 2];123 u32 resel_go [ 4];124 u32 _sms_a130 [ 7];125 u32 resel_dsa [ 2];126 u32 resel_dsa1 [ 4];127 u32 _sms_a140 [ 7];128 u32 resel_no_tag [ 4];129 u32 _sms_a145 [ 7];130 u32 data_in [SYM_CONF_MAX_SG * 2];131 u32 data_in2 [ 4];132 u32 data_out [SYM_CONF_MAX_SG * 2];133 u32 data_out2 [ 4];134 u32 pm0_data [ 12];135 u32 pm0_data_out [ 6];136 u32 pm0_data_end [ 7];137 u32 pm_data_end [ 4];138 u32 _sms_a150 [ 4];139 u32 pm1_data [ 12];140 u32 pm1_data_out [ 6];141 u32 pm1_data_end [ 9];142};143 144/*145 * Script fragments which stay in main memory for all chips 146 * except for chips that support 8K on-chip RAM.147 */148struct SYM_FWB_SCR {149 u32 no_data [ 2];150#ifdef SYM_CONF_TARGET_ROLE_SUPPORT151 u32 sel_for_abort [ 18];152#else153 u32 sel_for_abort [ 16];154#endif155 u32 sel_for_abort_1 [ 2];156 u32 msg_in_etc [ 12];157 u32 msg_received [ 5];158 u32 msg_weird_seen [ 5];159 u32 msg_extended [ 17];160 u32 _sms_b10 [ 4];161 u32 msg_bad [ 6];162 u32 msg_weird [ 4];163 u32 msg_weird1 [ 8];164 u32 wdtr_resp [ 6];165 u32 send_wdtr [ 4];166 u32 sdtr_resp [ 6];167 u32 send_sdtr [ 4];168 u32 ppr_resp [ 6];169 u32 send_ppr [ 4];170 u32 nego_bad_phase [ 4];171 u32 msg_out [ 4];172 u32 msg_out_done [ 4];173 u32 data_ovrun [ 3];174 u32 data_ovrun1 [ 22];175 u32 data_ovrun2 [ 8];176 u32 abort_resel [ 16];177 u32 resend_ident [ 4];178 u32 ident_break [ 4];179 u32 ident_break_atn [ 4];180 u32 sdata_in [ 6];181 u32 resel_bad_lun [ 4];182 u32 bad_i_t_l [ 4];183 u32 bad_i_t_l_q [ 4];184 u32 bad_status [ 7];185 u32 wsr_ma_helper [ 4];186 187 /* Data area */188 u32 zero [ 1];189 u32 scratch [ 1];190 u32 scratch1 [ 1];191 u32 prev_done [ 1];192 u32 done_pos [ 1];193 u32 nextjob [ 1];194 u32 startpos [ 1];195 u32 targtbl [ 1];196};197 198/*199 * Script fragments used at initialisations.200 * Only runs out of main memory.201 */202struct SYM_FWZ_SCR {203 u32 snooptest [ 9];204 u32 snoopend [ 2];205};206 207static struct SYM_FWA_SCR SYM_FWA_SCR = {208/*--------------------------< START >----------------------------*/ {209 /*210 * Switch the LED on.211 * Will be patched with a NO_OP if LED212 * not needed or not desired.213 */214 SCR_REG_REG (gpreg, SCR_AND, 0xfe),215 0,216 /*217 * Clear SIGP.218 */219 SCR_FROM_REG (ctest2),220 0,221 /*222 * Stop here if the C code wants to perform 223 * some error recovery procedure manually.224 * (Indicate this by setting SEM in ISTAT)225 */226 SCR_FROM_REG (istat),227 0,228 /*229 * Report to the C code the next position in 230 * the start queue the SCRIPTS will schedule.231 * The C code must not change SCRATCHA.232 */233 SCR_COPY (4),234 PADDR_B (startpos),235 RADDR_1 (scratcha),236 SCR_INT ^ IFTRUE (MASK (SEM, SEM)),237 SIR_SCRIPT_STOPPED,238 /*239 * Start the next job.240 *241 * @DSA = start point for this job.242 * SCRATCHA = address of this job in the start queue.243 *244 * We will restore startpos with SCRATCHA if we fails the 245 * arbitration or if it is the idle job.246 *247 * The below GETJOB_BEGIN to GETJOB_END section of SCRIPTS 248 * is a critical path. If it is partially executed, it then 249 * may happen that the job address is not yet in the DSA 250 * and the next queue position points to the next JOB.251 */252}/*-------------------------< GETJOB_BEGIN >---------------------*/,{253 /*254 * Copy to a fixed location both the next STARTPOS 255 * and the current JOB address, using self modifying 256 * SCRIPTS.257 */258 SCR_COPY (4),259 RADDR_1 (scratcha),260 PADDR_A (_sms_a10),261 SCR_COPY (8),262}/*-------------------------< _SMS_A10 >-------------------------*/,{263 0,264 PADDR_B (nextjob),265 /*266 * Move the start address to TEMP using self-267 * modifying SCRIPTS and jump indirectly to 268 * that address.269 */270 SCR_COPY (4),271 PADDR_B (nextjob),272 RADDR_1 (dsa),273}/*-------------------------< GETJOB_END >-----------------------*/,{274 SCR_COPY (4),275 RADDR_1 (dsa),276 PADDR_A (_sms_a20),277 SCR_COPY (4),278}/*-------------------------< _SMS_A20 >-------------------------*/,{279 0,280 RADDR_1 (temp),281 SCR_RETURN,282 0,283}/*-------------------------< SELECT >---------------------------*/,{284 /*285 * DSA contains the address of a scheduled286 * data structure.287 *288 * SCRATCHA contains the address of the start queue 289 * entry which points to the next job.290 *291 * Set Initiator mode.292 *293 * (Target mode is left as an exercise for the reader)294 */295#ifdef SYM_CONF_TARGET_ROLE_SUPPORT296 SCR_CLR (SCR_TRG),297 0,298#endif299 /*300 * And try to select this target.301 */302 SCR_SEL_TBL_ATN ^ offsetof (struct sym_dsb, select),303 PADDR_A (ungetjob),304 /*305 * Now there are 4 possibilities:306 *307 * (1) The chip loses arbitration.308 * This is ok, because it will try again,309 * when the bus becomes idle.310 * (But beware of the timeout function!)311 *312 * (2) The chip is reselected.313 * Then the script processor takes the jump314 * to the RESELECT label.315 *316 * (3) The chip wins arbitration.317 * Then it will execute SCRIPTS instruction until 318 * the next instruction that checks SCSI phase.319 * Then will stop and wait for selection to be 320 * complete or selection time-out to occur.321 *322 * After having won arbitration, the SCRIPTS 323 * processor is able to execute instructions while 324 * the SCSI core is performing SCSI selection.325 */326 327 /*328 * Copy the CCB header to a fixed location 329 * in the HCB using self-modifying SCRIPTS.330 */331 SCR_COPY (4),332 RADDR_1 (dsa),333 PADDR_A (_sms_a30),334 SCR_COPY (sizeof(struct sym_ccbh)),335}/*-------------------------< _SMS_A30 >-------------------------*/,{336 0,337 HADDR_1 (ccb_head),338 /*339 * Initialize the status register340 */341 SCR_COPY (4),342 HADDR_1 (ccb_head.status),343 RADDR_1 (scr0),344}/*-------------------------< WF_SEL_DONE >----------------------*/,{345 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),346 SIR_SEL_ATN_NO_MSG_OUT,347}/*-------------------------< SEND_IDENT >-----------------------*/,{348 /*349 * Selection complete.350 * Send the IDENTIFY and possibly the TAG message 351 * and negotiation message if present.352 */353 SCR_MOVE_TBL ^ SCR_MSG_OUT,354 offsetof (struct sym_dsb, smsg),355}/*-------------------------< SELECT2 >--------------------------*/,{356#ifdef SYM_CONF_IARB_SUPPORT357 /*358 * Set IMMEDIATE ARBITRATION if we have been given 359 * a hint to do so. (Some job to do after this one).360 */361 SCR_FROM_REG (HF_REG),362 0,363 SCR_JUMPR ^ IFFALSE (MASK (HF_HINT_IARB, HF_HINT_IARB)),364 8,365 SCR_REG_REG (scntl1, SCR_OR, IARB),366 0,367#endif368 /*369 * Anticipate the COMMAND phase.370 * This is the PHASE we expect at this point.371 */372 SCR_JUMP ^ IFFALSE (WHEN (SCR_COMMAND)),373 PADDR_A (sel_no_cmd),374}/*-------------------------< COMMAND >--------------------------*/,{375 /*376 * ... and send the command377 */378 SCR_MOVE_TBL ^ SCR_COMMAND,379 offsetof (struct sym_dsb, cmd),380}/*-------------------------< DISPATCH >-------------------------*/,{381 /*382 * MSG_IN is the only phase that shall be 383 * entered at least once for each (re)selection.384 * So we test it first.385 */386 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),387 PADDR_A (msg_in),388 SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)),389 PADDR_A (datao_phase),390 SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)),391 PADDR_A (datai_phase),392 SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)),393 PADDR_A (status),394 SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)),395 PADDR_A (command),396 SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),397 PADDR_B (msg_out),398 /*399 * Discard as many illegal phases as 400 * required and tell the C code about.401 */402 SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_OUT)),403 16,404 SCR_MOVE_ABS (1) ^ SCR_ILG_OUT,405 HADDR_1 (scratch),406 SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_OUT)),407 -16,408 SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_IN)),409 16,410 SCR_MOVE_ABS (1) ^ SCR_ILG_IN,411 HADDR_1 (scratch),412 SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_IN)),413 -16,414 SCR_INT,415 SIR_BAD_PHASE,416 SCR_JUMP,417 PADDR_A (dispatch),418}/*-------------------------< SEL_NO_CMD >-----------------------*/,{419 /*420 * The target does not switch to command 421 * phase after IDENTIFY has been sent.422 *423 * If it stays in MSG OUT phase send it 424 * the IDENTIFY again.425 */426 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),427 PADDR_B (resend_ident),428 /*429 * If target does not switch to MSG IN phase 430 * and we sent a negotiation, assert the 431 * failure immediately.432 */433 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),434 PADDR_A (dispatch),435 SCR_FROM_REG (HS_REG),436 0,437 SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),438 SIR_NEGO_FAILED,439 /*440 * Jump to dispatcher.441 */442 SCR_JUMP,443 PADDR_A (dispatch),444}/*-------------------------< INIT >-----------------------------*/,{445 /*446 * Wait for the SCSI RESET signal to be 447 * inactive before restarting operations, 448 * since the chip may hang on SEL_ATN 449 * if SCSI RESET is active.450 */451 SCR_FROM_REG (sstat0),452 0,453 SCR_JUMPR ^ IFTRUE (MASK (IRST, IRST)),454 -16,455 SCR_JUMP,456 PADDR_A (start),457}/*-------------------------< CLRACK >---------------------------*/,{458 /*459 * Terminate possible pending message phase.460 */461 SCR_CLR (SCR_ACK),462 0,463 SCR_JUMP,464 PADDR_A (dispatch),465}/*-------------------------< DATAI_DONE >-----------------------*/,{466 /*467 * Save current pointer to LASTP.468 */469 SCR_COPY (4),470 RADDR_1 (temp),471 HADDR_1 (ccb_head.lastp),472 /*473 * If the SWIDE is not full, jump to dispatcher.474 * We anticipate a STATUS phase.475 */476 SCR_FROM_REG (scntl2),477 0,478 SCR_JUMP ^ IFTRUE (MASK (WSR, WSR)),479 PADDR_A (datai_done_wsr),480 SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)),481 PADDR_A (status),482 SCR_JUMP,483 PADDR_A (dispatch),484}/*-------------------------< DATAI_DONE_WSR >-------------------*/,{485 /*486 * The SWIDE is full.487 * Clear this condition.488 */489 SCR_REG_REG (scntl2, SCR_OR, WSR),490 0,491 /*492 * We are expecting an IGNORE RESIDUE message 493 * from the device, otherwise we are in data 494 * overrun condition. Check against MSG_IN phase.495 */496 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),497 SIR_SWIDE_OVERRUN,498 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),499 PADDR_A (dispatch),500 /*501 * We are in MSG_IN phase,502 * Read the first byte of the message.503 * If it is not an IGNORE RESIDUE message,504 * signal overrun and jump to message 505 * processing.506 */507 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,508 HADDR_1 (msgin[0]),509 SCR_INT ^ IFFALSE (DATA (M_IGN_RESIDUE)),510 SIR_SWIDE_OVERRUN,511 SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)),512 PADDR_A (msg_in2),513 /*514 * We got the message we expected.515 * Read the 2nd byte, and jump to dispatcher.516 */517 SCR_CLR (SCR_ACK),518 0,519 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,520 HADDR_1 (msgin[1]),521 SCR_CLR (SCR_ACK),522 0,523 SCR_JUMP,524 PADDR_A (dispatch),525}/*-------------------------< DATAO_DONE >-----------------------*/,{526 /*527 * Save current pointer to LASTP.528 */529 SCR_COPY (4),530 RADDR_1 (temp),531 HADDR_1 (ccb_head.lastp),532 /*533 * If the SODL is not full jump to dispatcher.534 * We anticipate a STATUS phase.535 */536 SCR_FROM_REG (scntl2),537 0,538 SCR_JUMP ^ IFTRUE (MASK (WSS, WSS)),539 PADDR_A (datao_done_wss),540 SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)),541 PADDR_A (status),542 SCR_JUMP,543 PADDR_A (dispatch),544}/*-------------------------< DATAO_DONE_WSS >-------------------*/,{545 /*546 * The SODL is full, clear this condition.547 */548 SCR_REG_REG (scntl2, SCR_OR, WSS),549 0,550 /*551 * And signal a DATA UNDERRUN condition 552 * to the C code.553 */554 SCR_INT,555 SIR_SODL_UNDERRUN,556 SCR_JUMP,557 PADDR_A (dispatch),558}/*-------------------------< DATAI_PHASE >----------------------*/,{559 /*560 * Jump to current pointer.561 */562 SCR_COPY (4),563 HADDR_1 (ccb_head.lastp),564 RADDR_1 (temp),565 SCR_RETURN,566 0,567}/*-------------------------< DATAO_PHASE >----------------------*/,{568 /*569 * Jump to current pointer.570 */571 SCR_COPY (4),572 HADDR_1 (ccb_head.lastp),573 RADDR_1 (temp),574 SCR_RETURN,575 0,576}/*-------------------------< MSG_IN >---------------------------*/,{577 /*578 * Get the first byte of the message.579 *580 * The script processor doesn't negate the581 * ACK signal after this transfer.582 */583 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,584 HADDR_1 (msgin[0]),585}/*-------------------------< MSG_IN2 >--------------------------*/,{586 /*587 * Check first against 1 byte messages 588 * that we handle from SCRIPTS.589 */590 SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),591 PADDR_A (complete),592 SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),593 PADDR_A (disconnect),594 SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),595 PADDR_A (save_dp),596 SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),597 PADDR_A (restore_dp),598 /*599 * We handle all other messages from the 600 * C code, so no need to waste on-chip RAM 601 * for those ones.602 */603 SCR_JUMP,604 PADDR_B (msg_in_etc),605}/*-------------------------< STATUS >---------------------------*/,{606 /*607 * get the status608 */609 SCR_MOVE_ABS (1) ^ SCR_STATUS,610 HADDR_1 (scratch),611#ifdef SYM_CONF_IARB_SUPPORT612 /*613 * If STATUS is not GOOD, clear IMMEDIATE ARBITRATION, 614 * since we may have to tamper the start queue from 615 * the C code.616 */617 SCR_JUMPR ^ IFTRUE (DATA (S_GOOD)),618 8,619 SCR_REG_REG (scntl1, SCR_AND, ~IARB),620 0,621#endif622 /*623 * save status to scsi_status.624 * mark as complete.625 */626 SCR_TO_REG (SS_REG),627 0,628 SCR_LOAD_REG (HS_REG, HS_COMPLETE),629 0,630 /*631 * Anticipate the MESSAGE PHASE for 632 * the TASK COMPLETE message.633 */634 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),635 PADDR_A (msg_in),636 SCR_JUMP,637 PADDR_A (dispatch),638}/*-------------------------< COMPLETE >-------------------------*/,{639 /*640 * Complete message.641 *642 * When we terminate the cycle by clearing ACK,643 * the target may disconnect immediately.644 *645 * We don't want to be told of an "unexpected disconnect",646 * so we disable this feature.647 */648 SCR_REG_REG (scntl2, SCR_AND, 0x7f),649 0,650 /*651 * Terminate cycle ...652 */653 SCR_CLR (SCR_ACK|SCR_ATN),654 0,655 /*656 * ... and wait for the disconnect.657 */658 SCR_WAIT_DISC,659 0,660}/*-------------------------< COMPLETE2 >------------------------*/,{661 /*662 * Save host status.663 */664 SCR_COPY (4),665 RADDR_1 (scr0),666 HADDR_1 (ccb_head.status),667 /*668 * Move back the CCB header using self-modifying 669 * SCRIPTS.670 */671 SCR_COPY (4),672 RADDR_1 (dsa),673 PADDR_A (_sms_a40),674 SCR_COPY (sizeof(struct sym_ccbh)),675 HADDR_1 (ccb_head),676}/*-------------------------< _SMS_A40 >-------------------------*/,{677 0,678 /*679 * Some bridges may reorder DMA writes to memory.680 * We donnot want the CPU to deal with completions 681 * without all the posted write having been flushed 682 * to memory. This DUMMY READ should flush posted 683 * buffers prior to the CPU having to deal with 684 * completions.685 */686 SCR_COPY (4), /* DUMMY READ */687 HADDR_1 (ccb_head.status),688 RADDR_1 (scr0),689 /*690 * If command resulted in not GOOD status,691 * call the C code if needed.692 */693 SCR_FROM_REG (SS_REG),694 0,695 SCR_CALL ^ IFFALSE (DATA (S_GOOD)),696 PADDR_B (bad_status),697 /*698 * If we performed an auto-sense, call 699 * the C code to synchronyze task aborts 700 * with UNIT ATTENTION conditions.701 */702 SCR_FROM_REG (HF_REG),703 0,704 SCR_JUMP ^ IFFALSE (MASK (0 ,(HF_SENSE|HF_EXT_ERR))),705 PADDR_A (complete_error),706}/*-------------------------< DONE >-----------------------------*/,{707 /*708 * Copy the DSA to the DONE QUEUE and 709 * signal completion to the host.710 * If we are interrupted between DONE 711 * and DONE_END, we must reset, otherwise 712 * the completed CCB may be lost.713 */714 SCR_COPY (4),715 PADDR_B (done_pos),716 PADDR_A (_sms_a50),717 SCR_COPY (4),718 RADDR_1 (dsa),719}/*-------------------------< _SMS_A50 >-------------------------*/,{720 0,721 SCR_COPY (4),722 PADDR_B (done_pos),723 PADDR_A (_sms_a60),724 /*725 * The instruction below reads the DONE QUEUE next 726 * free position from memory.727 * In addition it ensures that all PCI posted writes 728 * are flushed and so the DSA value of the done 729 * CCB is visible by the CPU before INTFLY is raised.730 */731 SCR_COPY (8),732}/*-------------------------< _SMS_A60 >-------------------------*/,{733 0,734 PADDR_B (prev_done),735}/*-------------------------< DONE_END >-------------------------*/,{736 SCR_INT_FLY,737 0,738 SCR_JUMP,739 PADDR_A (start),740}/*-------------------------< COMPLETE_ERROR >-------------------*/,{741 SCR_COPY (4),742 PADDR_B (startpos),743 RADDR_1 (scratcha),744 SCR_INT,745 SIR_COMPLETE_ERROR,746}/*-------------------------< SAVE_DP >--------------------------*/,{747 /*748 * Clear ACK immediately.749 * No need to delay it.750 */751 SCR_CLR (SCR_ACK),752 0,753 /*754 * Keep track we received a SAVE DP, so 755 * we will switch to the other PM context 756 * on the next PM since the DP may point 757 * to the current PM context.758 */759 SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED),760 0,761 /*762 * SAVE_DP message:763 * Copy LASTP to SAVEP.764 */765 SCR_COPY (4),766 HADDR_1 (ccb_head.lastp),767 HADDR_1 (ccb_head.savep),768 /*769 * Anticipate the MESSAGE PHASE for 770 * the DISCONNECT message.771 */772 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),773 PADDR_A (msg_in),774 SCR_JUMP,775 PADDR_A (dispatch),776}/*-------------------------< RESTORE_DP >-----------------------*/,{777 /*778 * Clear ACK immediately.779 * No need to delay it.780 */781 SCR_CLR (SCR_ACK),782 0,783 /*784 * Copy SAVEP to LASTP.785 */786 SCR_COPY (4),787 HADDR_1 (ccb_head.savep),788 HADDR_1 (ccb_head.lastp),789 SCR_JUMP,790 PADDR_A (dispatch),791}/*-------------------------< DISCONNECT >-----------------------*/,{792 /*793 * DISCONNECTing ...794 *795 * disable the "unexpected disconnect" feature,796 * and remove the ACK signal.797 */798 SCR_REG_REG (scntl2, SCR_AND, 0x7f),799 0,800 SCR_CLR (SCR_ACK|SCR_ATN),801 0,802 /*803 * Wait for the disconnect.804 */805 SCR_WAIT_DISC,806 0,807 /*808 * Status is: DISCONNECTED.809 */810 SCR_LOAD_REG (HS_REG, HS_DISCONNECT),811 0,812 /*813 * Save host status.814 */815 SCR_COPY (4),816 RADDR_1 (scr0),817 HADDR_1 (ccb_head.status),818}/*-------------------------< DISCONNECT2 >----------------------*/,{819 /*820 * Move back the CCB header using self-modifying 821 * SCRIPTS.822 */823 SCR_COPY (4),824 RADDR_1 (dsa),825 PADDR_A (_sms_a65),826 SCR_COPY (sizeof(struct sym_ccbh)),827 HADDR_1 (ccb_head),828}/*-------------------------< _SMS_A65 >-------------------------*/,{829 0,830 SCR_JUMP,831 PADDR_A (start),832}/*-------------------------< IDLE >-----------------------------*/,{833 /*834 * Nothing to do?835 * Switch the LED off and wait for reselect.836 * Will be patched with a NO_OP if LED837 * not needed or not desired.838 */839 SCR_REG_REG (gpreg, SCR_OR, 0x01),840 0,841#ifdef SYM_CONF_IARB_SUPPORT842 SCR_JUMPR,843 8,844#endif845}/*-------------------------< UNGETJOB >-------------------------*/,{846#ifdef SYM_CONF_IARB_SUPPORT847 /*848 * Set IMMEDIATE ARBITRATION, for the next time.849 * This will give us better chance to win arbitration 850 * for the job we just wanted to do.851 */852 SCR_REG_REG (scntl1, SCR_OR, IARB),853 0,854#endif855 /*856 * We are not able to restart the SCRIPTS if we are 857 * interrupted and these instruction haven't been 858 * all executed. BTW, this is very unlikely to 859 * happen, but we check that from the C code.860 */861 SCR_LOAD_REG (dsa, 0xff),862 0,863 SCR_COPY (4),864 RADDR_1 (scratcha),865 PADDR_B (startpos),866}/*-------------------------< RESELECT >-------------------------*/,{867#ifdef SYM_CONF_TARGET_ROLE_SUPPORT868 /*869 * Make sure we are in initiator mode.870 */871 SCR_CLR (SCR_TRG),872 0,873#endif874 /*875 * Sleep waiting for a reselection.876 */877 SCR_WAIT_RESEL,878 PADDR_A(start),879}/*-------------------------< RESELECTED >-----------------------*/,{880 /*881 * Switch the LED on.882 * Will be patched with a NO_OP if LED883 * not needed or not desired.884 */885 SCR_REG_REG (gpreg, SCR_AND, 0xfe),886 0,887 /*888 * load the target id into the sdid889 */890 SCR_REG_SFBR (ssid, SCR_AND, 0x8F),891 0,892 SCR_TO_REG (sdid),893 0,894 /*895 * Load the target control block address896 */897 SCR_COPY (4),898 PADDR_B (targtbl),899 RADDR_1 (dsa),900 SCR_SFBR_REG (dsa, SCR_SHL, 0),901 0,902 SCR_REG_REG (dsa, SCR_SHL, 0),903 0,904 SCR_REG_REG (dsa, SCR_AND, 0x3c),905 0,906 SCR_COPY (4),907 RADDR_1 (dsa),908 PADDR_A (_sms_a70),909 SCR_COPY (4),910}/*-------------------------< _SMS_A70 >-------------------------*/,{911 0,912 RADDR_1 (dsa),913 /*914 * Copy the TCB header to a fixed place in 915 * the HCB.916 */917 SCR_COPY (4),918 RADDR_1 (dsa),919 PADDR_A (_sms_a80),920 SCR_COPY (sizeof(struct sym_tcbh)),921}/*-------------------------< _SMS_A80 >-------------------------*/,{922 0,923 HADDR_1 (tcb_head),924 /*925 * We expect MESSAGE IN phase.926 * If not, get help from the C code.927 */928 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),929 SIR_RESEL_NO_MSG_IN,930}/*-------------------------< RESELECTED1 >----------------------*/,{931 /*932 * Load the synchronous transfer registers.933 */934 SCR_COPY (1),935 HADDR_1 (tcb_head.wval),936 RADDR_1 (scntl3),937 SCR_COPY (1),938 HADDR_1 (tcb_head.sval),939 RADDR_1 (sxfer),940 /*941 * Get the IDENTIFY message.942 */943 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,944 HADDR_1 (msgin),945 /*946 * If IDENTIFY LUN #0, use a faster path 947 * to find the LCB structure.948 */949 SCR_JUMP ^ IFTRUE (MASK (0x80, 0xbf)),950 PADDR_A (resel_lun0),951 /*952 * If message isn't an IDENTIFY, 953 * tell the C code about.954 */955 SCR_INT ^ IFFALSE (MASK (0x80, 0x80)),956 SIR_RESEL_NO_IDENTIFY,957 /*958 * It is an IDENTIFY message,959 * Load the LUN control block address.960 */961 SCR_COPY (4),962 HADDR_1 (tcb_head.luntbl_sa),963 RADDR_1 (dsa),964 SCR_SFBR_REG (dsa, SCR_SHL, 0),965 0,966 SCR_REG_REG (dsa, SCR_SHL, 0),967 0,968 SCR_REG_REG (dsa, SCR_AND, 0xfc),969 0,970 SCR_COPY (4),971 RADDR_1 (dsa),972 PADDR_A (_sms_a90),973 SCR_COPY (4),974}/*-------------------------< _SMS_A90 >-------------------------*/,{975 0,976 RADDR_1 (dsa),977 SCR_JUMPR,978 12,979}/*-------------------------< RESEL_LUN0 >-----------------------*/,{980 /*981 * LUN 0 special case (but usual one :))982 */983 SCR_COPY (4),984 HADDR_1 (tcb_head.lun0_sa),985 RADDR_1 (dsa),986 /*987 * Jump indirectly to the reselect action for this LUN.988 * (lcb.head.resel_sa assumed at offset zero of lcb).989 */990 SCR_COPY (4),991 RADDR_1 (dsa),992 PADDR_A (_sms_a100),993 SCR_COPY (4),994}/*-------------------------< _SMS_A100 >------------------------*/,{995 0,996 RADDR_1 (temp),997 SCR_RETURN,998 0,999 /* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */1000}/*-------------------------< RESEL_TAG >------------------------*/,{1001 /*1002 * ACK the IDENTIFY previously received.1003 */1004 SCR_CLR (SCR_ACK),1005 0,1006 /*1007 * It shall be a tagged command.1008 * Read SIMPLE+TAG.1009 * The C code will deal with errors.1010 * Aggressive optimization, isn't it? :)1011 */1012 SCR_MOVE_ABS (2) ^ SCR_MSG_IN,1013 HADDR_1 (msgin),1014 /*1015 * Copy the LCB header to a fixed place in 1016 * the HCB using self-modifying SCRIPTS.1017 */1018 SCR_COPY (4),1019 RADDR_1 (dsa),1020 PADDR_A (_sms_a110),1021 SCR_COPY (sizeof(struct sym_lcbh)),1022}/*-------------------------< _SMS_A110 >------------------------*/,{1023 0,1024 HADDR_1 (lcb_head),1025 /*1026 * Load the pointer to the tagged task 1027 * table for this LUN.1028 */1029 SCR_COPY (4),1030 HADDR_1 (lcb_head.itlq_tbl_sa),1031 RADDR_1 (dsa),1032 /*1033 * The SIDL still contains the TAG value.1034 * Aggressive optimization, isn't it? :):)1035 */1036 SCR_REG_SFBR (sidl, SCR_SHL, 0),1037 0,1038#if SYM_CONF_MAX_TASK*4 > 5121039 SCR_JUMPR ^ IFFALSE (CARRYSET),1040 8,1041 SCR_REG_REG (dsa1, SCR_OR, 2),1042 0,1043 SCR_REG_REG (sfbr, SCR_SHL, 0),1044 0,1045 SCR_JUMPR ^ IFFALSE (CARRYSET),1046 8,1047 SCR_REG_REG (dsa1, SCR_OR, 1),1048 0,1049#elif SYM_CONF_MAX_TASK*4 > 2561050 SCR_JUMPR ^ IFFALSE (CARRYSET),1051 8,1052 SCR_REG_REG (dsa1, SCR_OR, 1),1053 0,1054#endif1055 /*1056 * Retrieve the DSA of this task.1057 * JUMP indirectly to the restart point of the CCB.1058 */1059 SCR_SFBR_REG (dsa, SCR_AND, 0xfc),1060 0,1061 SCR_COPY (4),1062 RADDR_1 (dsa),1063 PADDR_A (_sms_a120),1064 SCR_COPY (4),1065}/*-------------------------< _SMS_A120 >------------------------*/,{1066 0,1067 RADDR_1 (dsa),1068}/*-------------------------< RESEL_GO >-------------------------*/,{1069 SCR_COPY (4),1070 RADDR_1 (dsa),1071 PADDR_A (_sms_a130),1072 /*1073 * Move 'ccb.phys.head.go' action to 1074 * scratch/scratch1. So scratch1 will 1075 * contain the 'restart' field of the 1076 * 'go' structure.1077 */1078 SCR_COPY (8),1079}/*-------------------------< _SMS_A130 >------------------------*/,{1080 0,1081 PADDR_B (scratch),1082 SCR_COPY (4),1083 PADDR_B (scratch1), /* phys.head.go.restart */1084 RADDR_1 (temp),1085 SCR_RETURN,1086 0,1087 /* In normal situations we branch to RESEL_DSA */1088}/*-------------------------< RESEL_DSA >------------------------*/,{1089 /*1090 * ACK the IDENTIFY or TAG previously received.1091 */1092 SCR_CLR (SCR_ACK),1093 0,1094}/*-------------------------< RESEL_DSA1 >-----------------------*/,{1095 /*1096 * Copy the CCB header to a fixed location 1097 * in the HCB using self-modifying SCRIPTS.1098 */1099 SCR_COPY (4),1100 RADDR_1 (dsa),1101 PADDR_A (_sms_a140),1102 SCR_COPY (sizeof(struct sym_ccbh)),1103}/*-------------------------< _SMS_A140 >------------------------*/,{1104 0,1105 HADDR_1 (ccb_head),1106 /*1107 * Initialize the status register1108 */1109 SCR_COPY (4),1110 HADDR_1 (ccb_head.status),1111 RADDR_1 (scr0),1112 /*1113 * Jump to dispatcher.1114 */1115 SCR_JUMP,1116 PADDR_A (dispatch),1117}/*-------------------------< RESEL_NO_TAG >---------------------*/,{1118 /*1119 * Copy the LCB header to a fixed place in 1120 * the HCB using self-modifying SCRIPTS.1121 */1122 SCR_COPY (4),1123 RADDR_1 (dsa),1124 PADDR_A (_sms_a145),1125 SCR_COPY (sizeof(struct sym_lcbh)),1126}/*-------------------------< _SMS_A145 >------------------------*/,{1127 0,1128 HADDR_1 (lcb_head),1129 /*1130 * Load the DSA with the unique ITL task.1131 */1132 SCR_COPY (4),1133 HADDR_1 (lcb_head.itl_task_sa),1134 RADDR_1 (dsa),1135 SCR_JUMP,1136 PADDR_A (resel_go),1137}/*-------------------------< DATA_IN >--------------------------*/,{1138/*1139 * Because the size depends on the1140 * #define SYM_CONF_MAX_SG parameter,1141 * it is filled in at runtime.1142 *1143 * ##===========< i=0; i<SYM_CONF_MAX_SG >=========1144 * || SCR_CHMOV_TBL ^ SCR_DATA_IN,1145 * || offsetof (struct sym_dsb, data[ i]),1146 * ##==========================================1147 */114801149}/*-------------------------< DATA_IN2 >-------------------------*/,{1150 SCR_CALL,1151 PADDR_A (datai_done),1152 SCR_JUMP,1153 PADDR_B (data_ovrun),1154}/*-------------------------< DATA_OUT >-------------------------*/,{1155/*1156 * Because the size depends on the1157 * #define SYM_CONF_MAX_SG parameter,1158 * it is filled in at runtime.1159 *1160 * ##===========< i=0; i<SYM_CONF_MAX_SG >=========1161 * || SCR_CHMOV_TBL ^ SCR_DATA_OUT,1162 * || offsetof (struct sym_dsb, data[ i]),1163 * ##==========================================1164 */116501166}/*-------------------------< DATA_OUT2 >------------------------*/,{1167 SCR_CALL,1168 PADDR_A (datao_done),1169 SCR_JUMP,1170 PADDR_B (data_ovrun),1171}/*-------------------------< PM0_DATA >-------------------------*/,{1172 /*1173 * Read our host flags to SFBR, so we will be able 1174 * to check against the data direction we expect.1175 */1176 SCR_FROM_REG (HF_REG),1177 0,1178 /*1179 * Check against actual DATA PHASE.1180 */1181 SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),1182 PADDR_A (pm0_data_out),1183 /*1184 * Actual phase is DATA IN.1185 * Check against expected direction.1186 */1187 SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),1188 PADDR_B (data_ovrun),1189 /*1190 * Keep track we are moving data from the 1191 * PM0 DATA mini-script.1192 */1193 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),1194 0,1195 /*1196 * Move the data to memory.1197 */1198 SCR_CHMOV_TBL ^ SCR_DATA_IN,1199 offsetof (struct sym_ccb, phys.pm0.sg),1200 SCR_JUMP,1201 PADDR_A (pm0_data_end),1202}/*-------------------------< PM0_DATA_OUT >---------------------*/,{1203 /*1204 * Actual phase is DATA OUT.1205 * Check against expected direction.1206 */1207 SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),1208 PADDR_B (data_ovrun),1209 /*1210 * Keep track we are moving data from the 1211 * PM0 DATA mini-script.1212 */1213 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),1214 0,1215 /*1216 * Move the data from memory.1217 */1218 SCR_CHMOV_TBL ^ SCR_DATA_OUT,1219 offsetof (struct sym_ccb, phys.pm0.sg),1220}/*-------------------------< PM0_DATA_END >---------------------*/,{1221 /*1222 * Clear the flag that told we were moving 1223 * data from the PM0 DATA mini-script.1224 */1225 SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)),1226 0,1227 /*1228 * Return to the previous DATA script which 1229 * is guaranteed by design (if no bug) to be 1230 * the main DATA script for this transfer.1231 */1232 SCR_COPY (4),1233 RADDR_1 (dsa),1234 RADDR_1 (scratcha),1235 SCR_REG_REG (scratcha, SCR_ADD, offsetof (struct sym_ccb,phys.pm0.ret)),1236 0,1237}/*-------------------------< PM_DATA_END >----------------------*/,{1238 SCR_COPY (4),1239 RADDR_1 (scratcha),1240 PADDR_A (_sms_a150),1241 SCR_COPY (4),1242}/*-------------------------< _SMS_A150 >------------------------*/,{1243 0,1244 RADDR_1 (temp),1245 SCR_RETURN,1246 0,1247}/*-------------------------< PM1_DATA >-------------------------*/,{1248 /*1249 * Read our host flags to SFBR, so we will be able 1250 * to check against the data direction we expect.1251 */1252 SCR_FROM_REG (HF_REG),1253 0,1254 /*1255 * Check against actual DATA PHASE.1256 */1257 SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),1258 PADDR_A (pm1_data_out),1259 /*1260 * Actual phase is DATA IN.1261 * Check against expected direction.1262 */1263 SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),1264 PADDR_B (data_ovrun),1265 /*1266 * Keep track we are moving data from the 1267 * PM1 DATA mini-script.1268 */1269 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),1270 0,1271 /*1272 * Move the data to memory.1273 */1274 SCR_CHMOV_TBL ^ SCR_DATA_IN,1275 offsetof (struct sym_ccb, phys.pm1.sg),1276 SCR_JUMP,1277 PADDR_A (pm1_data_end),1278}/*-------------------------< PM1_DATA_OUT >---------------------*/,{1279 /*1280 * Actual phase is DATA OUT.1281 * Check against expected direction.1282 */1283 SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),1284 PADDR_B (data_ovrun),1285 /*1286 * Keep track we are moving data from the 1287 * PM1 DATA mini-script.1288 */1289 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),1290 0,1291 /*1292 * Move the data from memory.1293 */1294 SCR_CHMOV_TBL ^ SCR_DATA_OUT,1295 offsetof (struct sym_ccb, phys.pm1.sg),1296}/*-------------------------< PM1_DATA_END >---------------------*/,{1297 /*1298 * Clear the flag that told we were moving 1299 * data from the PM1 DATA mini-script.1300 */1301 SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)),1302 0,1303 /*1304 * Return to the previous DATA script which 1305 * is guaranteed by design (if no bug) to be 1306 * the main DATA script for this transfer.1307 */1308 SCR_COPY (4),1309 RADDR_1 (dsa),1310 RADDR_1 (scratcha),1311 SCR_REG_REG (scratcha, SCR_ADD, offsetof (struct sym_ccb,phys.pm1.ret)),1312 0,1313 SCR_JUMP,1314 PADDR_A (pm_data_end),1315}/*--------------------------<>----------------------------------*/1316};1317 1318static struct SYM_FWB_SCR SYM_FWB_SCR = {1319/*-------------------------< NO_DATA >--------------------------*/ {1320 SCR_JUMP,1321 PADDR_B (data_ovrun),1322}/*-------------------------< SEL_FOR_ABORT >--------------------*/,{1323 /*1324 * We are jumped here by the C code, if we have 1325 * some target to reset or some disconnected 1326 * job to abort. Since error recovery is a serious 1327 * busyness, we will really reset the SCSI BUS, if 1328 * case of a SCSI interrupt occurring in this path.1329 */1330 1331#ifdef SYM_CONF_TARGET_ROLE_SUPPORT1332 /*1333 * Set initiator mode.1334 */1335 SCR_CLR (SCR_TRG),1336 0,1337#endif1338 /*1339 * And try to select this target.1340 */1341 SCR_SEL_TBL_ATN ^ offsetof (struct sym_hcb, abrt_sel),1342 PADDR_A (reselect),1343 /*1344 * Wait for the selection to complete or 1345 * the selection to time out.1346 */1347 SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)),1348 -8,1349 /*1350 * Call the C code.1351 */1352 SCR_INT,1353 SIR_TARGET_SELECTED,1354 /*1355 * The C code should let us continue here. 1356 * Send the 'kiss of death' message.1357 * We expect an immediate disconnect once 1358 * the target has eaten the message.1359 */1360 SCR_REG_REG (scntl2, SCR_AND, 0x7f),1361 0,1362 SCR_MOVE_TBL ^ SCR_MSG_OUT,1363 offsetof (struct sym_hcb, abrt_tbl),1364 SCR_CLR (SCR_ACK|SCR_ATN),1365 0,1366 SCR_WAIT_DISC,1367 0,1368 /*1369 * Tell the C code that we are done.1370 */1371 SCR_INT,1372 SIR_ABORT_SENT,1373}/*-------------------------< SEL_FOR_ABORT_1 >------------------*/,{1374 /*1375 * Jump at scheduler.1376 */1377 SCR_JUMP,1378 PADDR_A (start),1379}/*-------------------------< MSG_IN_ETC >-----------------------*/,{1380 /*1381 * If it is an EXTENDED (variable size message)1382 * Handle it.1383 */1384 SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),1385 PADDR_B (msg_extended),1386 /*1387 * Let the C code handle any other 1388 * 1 byte message.1389 */1390 SCR_JUMP ^ IFTRUE (MASK (0x00, 0xf0)),1391 PADDR_B (msg_received),1392 SCR_JUMP ^ IFTRUE (MASK (0x10, 0xf0)),1393 PADDR_B (msg_received),1394 /*1395 * We donnot handle 2 bytes messages from SCRIPTS.1396 * So, let the C code deal with these ones too.1397 */1398 SCR_JUMP ^ IFFALSE (MASK (0x20, 0xf0)),1399 PADDR_B (msg_weird_seen),1400 SCR_CLR (SCR_ACK),1401 0,1402 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,1403 HADDR_1 (msgin[1]),1404}/*-------------------------< MSG_RECEIVED >---------------------*/,{1405 SCR_COPY (4), /* DUMMY READ */1406 HADDR_1 (scratch),1407 RADDR_1 (scratcha),1408 SCR_INT,1409 SIR_MSG_RECEIVED,1410}/*-------------------------< MSG_WEIRD_SEEN >-------------------*/,{1411 SCR_COPY (4), /* DUMMY READ */1412 HADDR_1 (scratch),1413 RADDR_1 (scratcha),1414 SCR_INT,1415 SIR_MSG_WEIRD,1416}/*-------------------------< MSG_EXTENDED >---------------------*/,{1417 /*1418 * Clear ACK and get the next byte 1419 * assumed to be the message length.1420 */1421 SCR_CLR (SCR_ACK),1422 0,1423 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,1424 HADDR_1 (msgin[1]),1425 /*1426 * Try to catch some unlikely situations as 0 length 1427 * or too large the length.1428 */1429 SCR_JUMP ^ IFTRUE (DATA (0)),1430 PADDR_B (msg_weird_seen),1431 SCR_TO_REG (scratcha),1432 0,1433 SCR_REG_REG (sfbr, SCR_ADD, (256-8)),1434 0,1435 SCR_JUMP ^ IFTRUE (CARRYSET),1436 PADDR_B (msg_weird_seen),1437 /*1438 * We donnot handle extended messages from SCRIPTS.1439 * Read the amount of data corresponding to the 1440 * message length and call the C code.1441 */1442 SCR_COPY (1),1443 RADDR_1 (scratcha),1444 PADDR_B (_sms_b10),1445 SCR_CLR (SCR_ACK),1446 0,1447}/*-------------------------< _SMS_B10 >-------------------------*/,{1448 SCR_MOVE_ABS (0) ^ SCR_MSG_IN,1449 HADDR_1 (msgin[2]),1450 SCR_JUMP,1451 PADDR_B (msg_received),1452}/*-------------------------< MSG_BAD >--------------------------*/,{1453 /*1454 * unimplemented message - reject it.1455 */1456 SCR_INT,1457 SIR_REJECT_TO_SEND,1458 SCR_SET (SCR_ATN),1459 0,1460 SCR_JUMP,1461 PADDR_A (clrack),1462}/*-------------------------< MSG_WEIRD >------------------------*/,{1463 /*1464 * weird message received1465 * ignore all MSG IN phases and reject it.1466 */1467 SCR_INT,1468 SIR_REJECT_TO_SEND,1469 SCR_SET (SCR_ATN),1470 0,1471}/*-------------------------< MSG_WEIRD1 >-----------------------*/,{1472 SCR_CLR (SCR_ACK),1473 0,1474 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),1475 PADDR_A (dispatch),1476 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,1477 HADDR_1 (scratch),1478 SCR_JUMP,1479 PADDR_B (msg_weird1),1480}/*-------------------------< WDTR_RESP >------------------------*/,{1481 /*1482 * let the target fetch our answer.1483 */1484 SCR_SET (SCR_ATN),1485 0,1486 SCR_CLR (SCR_ACK),1487 0,1488 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),1489 PADDR_B (nego_bad_phase),1490}/*-------------------------< SEND_WDTR >------------------------*/,{1491 /*1492 * Send the M_X_WIDE_REQ1493 */1494 SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,1495 HADDR_1 (msgout),1496 SCR_JUMP,1497 PADDR_B (msg_out_done),1498}/*-------------------------< SDTR_RESP >------------------------*/,{1499 /*1500 * let the target fetch our answer.1501 */1502 SCR_SET (SCR_ATN),1503 0,1504 SCR_CLR (SCR_ACK),1505 0,1506 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),1507 PADDR_B (nego_bad_phase),1508}/*-------------------------< SEND_SDTR >------------------------*/,{1509 /*1510 * Send the M_X_SYNC_REQ1511 */1512 SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,1513 HADDR_1 (msgout),1514 SCR_JUMP,1515 PADDR_B (msg_out_done),1516}/*-------------------------< PPR_RESP >-------------------------*/,{1517 /*1518 * let the target fetch our answer.1519 */1520 SCR_SET (SCR_ATN),1521 0,1522 SCR_CLR (SCR_ACK),1523 0,1524 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),1525 PADDR_B (nego_bad_phase),1526}/*-------------------------< SEND_PPR >-------------------------*/,{1527 /*1528 * Send the M_X_PPR_REQ1529 */1530 SCR_MOVE_ABS (8) ^ SCR_MSG_OUT,1531 HADDR_1 (msgout),1532 SCR_JUMP,1533 PADDR_B (msg_out_done),1534}/*-------------------------< NEGO_BAD_PHASE >-------------------*/,{1535 SCR_INT,1536 SIR_NEGO_PROTO,1537 SCR_JUMP,1538 PADDR_A (dispatch),1539}/*-------------------------< MSG_OUT >--------------------------*/,{1540 /*1541 * The target requests a message.1542 * We donnot send messages that may 1543 * require the device to go to bus free.1544 */1545 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,1546 HADDR_1 (msgout),1547 /*1548 * ... wait for the next phase1549 * if it's a message out, send it again, ...1550 */1551 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),1552 PADDR_B (msg_out),1553}/*-------------------------< MSG_OUT_DONE >---------------------*/,{1554 /*1555 * Let the C code be aware of the 1556 * sent message and clear the message.1557 */1558 SCR_INT,1559 SIR_MSG_OUT_DONE,1560 /*1561 * ... and process the next phase1562 */1563 SCR_JUMP,1564 PADDR_A (dispatch),1565}/*-------------------------< DATA_OVRUN >-----------------------*/,{1566 /*1567 * Zero scratcha that will count the 1568 * extras bytes.1569 */1570 SCR_COPY (4),1571 PADDR_B (zero),1572 RADDR_1 (scratcha),1573}/*-------------------------< DATA_OVRUN1 >----------------------*/,{1574 /*1575 * The target may want to transfer too much data.1576 *1577 * If phase is DATA OUT write 1 byte and count it.1578 */1579 SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),1580 16,1581 SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT,1582 HADDR_1 (scratch),1583 SCR_JUMP,1584 PADDR_B (data_ovrun2),1585 /*1586 * If WSR is set, clear this condition, and 1587 * count this byte.1588 */1589 SCR_FROM_REG (scntl2),1590 0,1591 SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),1592 16,1593 SCR_REG_REG (scntl2, SCR_OR, WSR),1594 0,1595 SCR_JUMP,1596 PADDR_B (data_ovrun2),1597 /*1598 * Finally check against DATA IN phase.1599 * Signal data overrun to the C code 1600 * and jump to dispatcher if not so.1601 * Read 1 byte otherwise and count it.1602 */1603 SCR_JUMPR ^ IFTRUE (WHEN (SCR_DATA_IN)),1604 16,1605 SCR_INT,1606 SIR_DATA_OVERRUN,1607 SCR_JUMP,1608 PADDR_A (dispatch),1609 SCR_CHMOV_ABS (1) ^ SCR_DATA_IN,1610 HADDR_1 (scratch),1611}/*-------------------------< DATA_OVRUN2 >----------------------*/,{1612 /*1613 * Count this byte.1614 * This will allow to return a negative 1615 * residual to user.1616 */1617 SCR_REG_REG (scratcha, SCR_ADD, 0x01),1618 0,1619 SCR_REG_REG (scratcha1, SCR_ADDC, 0),1620 0,1621 SCR_REG_REG (scratcha2, SCR_ADDC, 0),1622 0,1623 /*1624 * .. and repeat as required.1625 */1626 SCR_JUMP,1627 PADDR_B (data_ovrun1),1628}/*-------------------------< ABORT_RESEL >----------------------*/,{1629 SCR_SET (SCR_ATN),1630 0,1631 SCR_CLR (SCR_ACK),1632 0,1633 /*1634 * send the abort/abortag/reset message1635 * we expect an immediate disconnect1636 */1637 SCR_REG_REG (scntl2, SCR_AND, 0x7f),1638 0,1639 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,1640 HADDR_1 (msgout),1641 SCR_CLR (SCR_ACK|SCR_ATN),1642 0,1643 SCR_WAIT_DISC,1644 0,1645 SCR_INT,1646 SIR_RESEL_ABORTED,1647 SCR_JUMP,1648 PADDR_A (start),1649}/*-------------------------< RESEND_IDENT >---------------------*/,{1650 /*1651 * The target stays in MSG OUT phase after having acked 1652 * Identify [+ Tag [+ Extended message ]]. Targets shall1653 * behave this way on parity error.1654 * We must send it again all the messages.1655 */1656 SCR_SET (SCR_ATN), /* Shall be asserted 2 deskew delays before the */1657 0, /* 1rst ACK = 90 ns. Hope the chip isn't too fast */1658 SCR_JUMP,1659 PADDR_A (send_ident),1660}/*-------------------------< IDENT_BREAK >----------------------*/,{1661 SCR_CLR (SCR_ATN),1662 0,1663 SCR_JUMP,1664 PADDR_A (select2),1665}/*-------------------------< IDENT_BREAK_ATN >------------------*/,{1666 SCR_SET (SCR_ATN),1667 0,1668 SCR_JUMP,1669 PADDR_A (select2),1670}/*-------------------------< SDATA_IN >-------------------------*/,{1671 SCR_CHMOV_TBL ^ SCR_DATA_IN,1672 offsetof (struct sym_dsb, sense),1673 SCR_CALL,1674 PADDR_A (datai_done),1675 SCR_JUMP,1676 PADDR_B (data_ovrun),1677}/*-------------------------< RESEL_BAD_LUN >--------------------*/,{1678 /*1679 * Message is an IDENTIFY, but lun is unknown.1680 * Signal problem to C code for logging the event.1681 * Send a M_ABORT to clear all pending tasks.1682 */1683 SCR_INT,1684 SIR_RESEL_BAD_LUN,1685 SCR_JUMP,1686 PADDR_B (abort_resel),1687}/*-------------------------< BAD_I_T_L >------------------------*/,{1688 /*1689 * We donnot have a task for that I_T_L.1690 * Signal problem to C code for logging the event.1691 * Send a M_ABORT message.1692 */1693 SCR_INT,1694 SIR_RESEL_BAD_I_T_L,1695 SCR_JUMP,1696 PADDR_B (abort_resel),1697}/*-------------------------< BAD_I_T_L_Q >----------------------*/,{1698 /*1699 * We donnot have a task that matches the tag.1700 * Signal problem to C code for logging the event.1701 * Send a M_ABORTTAG message.1702 */1703 SCR_INT,1704 SIR_RESEL_BAD_I_T_L_Q,1705 SCR_JUMP,1706 PADDR_B (abort_resel),1707}/*-------------------------< BAD_STATUS >-----------------------*/,{1708 /*1709 * Anything different from INTERMEDIATE 1710 * CONDITION MET should be a bad SCSI status, 1711 * given that GOOD status has already been tested.1712 * Call the C code.1713 */1714 SCR_COPY (4),1715 PADDR_B (startpos),1716 RADDR_1 (scratcha),1717 SCR_INT ^ IFFALSE (DATA (S_COND_MET)),1718 SIR_BAD_SCSI_STATUS,1719 SCR_RETURN,1720 0,1721}/*-------------------------< WSR_MA_HELPER >--------------------*/,{1722 /*1723 * Helper for the C code when WSR bit is set.1724 * Perform the move of the residual byte.1725 */1726 SCR_CHMOV_TBL ^ SCR_DATA_IN,1727 offsetof (struct sym_ccb, phys.wresid),1728 SCR_JUMP,1729 PADDR_A (dispatch),1730 1731}/*-------------------------< ZERO >-----------------------------*/,{1732 SCR_DATA_ZERO,1733}/*-------------------------< SCRATCH >--------------------------*/,{1734 SCR_DATA_ZERO, /* MUST BE BEFORE SCRATCH1 */1735}/*-------------------------< SCRATCH1 >-------------------------*/,{1736 SCR_DATA_ZERO,1737}/*-------------------------< PREV_DONE >------------------------*/,{1738 SCR_DATA_ZERO, /* MUST BE BEFORE DONE_POS ! */1739}/*-------------------------< DONE_POS >-------------------------*/,{1740 SCR_DATA_ZERO,1741}/*-------------------------< NEXTJOB >--------------------------*/,{1742 SCR_DATA_ZERO, /* MUST BE BEFORE STARTPOS ! */1743}/*-------------------------< STARTPOS >-------------------------*/,{1744 SCR_DATA_ZERO,1745}/*-------------------------< TARGTBL >--------------------------*/,{1746 SCR_DATA_ZERO,1747}/*--------------------------<>----------------------------------*/1748};1749 1750static struct SYM_FWZ_SCR SYM_FWZ_SCR = {1751 /*-------------------------< SNOOPTEST >------------------------*/{1752 /*1753 * Read the variable.1754 */1755 SCR_COPY (4),1756 HADDR_1 (scratch),1757 RADDR_1 (scratcha),1758 /*1759 * Write the variable.1760 */1761 SCR_COPY (4),1762 RADDR_1 (temp),1763 HADDR_1 (scratch),1764 /*1765 * Read back the variable.1766 */1767 SCR_COPY (4),1768 HADDR_1 (scratch),1769 RADDR_1 (temp),1770}/*-------------------------< SNOOPEND >-------------------------*/,{1771 /*1772 * And stop.1773 */1774 SCR_INT,1775 99,1776}/*--------------------------<>----------------------------------*/1777};1778