FlashPoint.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:308k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1.       dataXferProcessor(port, &BL_Card[p_card]);
  2.       while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
  3.          (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
  4.       }
  5.       }  /*End Data In specific code. */
  6. #if defined(DOS)
  7.    asm { mov dx,port;
  8.       add dx,hp_xfercnt_2;
  9.       in  al,dx;
  10.       dec dx;
  11.       xor ah,ah;
  12.       mov word ptr xfercnt+2,ax;
  13.       in  al,dx;
  14.       dec dx;
  15.       mov ah,al;
  16.       in  al,dx;
  17.       mov word ptr xfercnt,ax;
  18.       }
  19. #else
  20.    GET_XFER_CNT(port,xfercnt);
  21. #endif
  22.    WR_HARPOON(port+hp_xfercnt_0, 0x00);
  23.    WR_HARPOON(port+hp_portctrl_0, 0x00);
  24.    currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
  25.    currSCCB->Sccb_XferCnt = xfercnt;
  26.    if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
  27.       (currSCCB->HostStatus == SCCB_COMPLETE)) {
  28.       currSCCB->HostStatus = SCCB_PARITY_ERR;
  29.       WRW_HARPOON((port+hp_intstat), PARITY);
  30.       }
  31.    hostDataXferAbort(port,p_card,currSCCB);
  32.    WR_HARPOON(port+hp_fifowrite, 0x00);
  33.    WR_HARPOON(port+hp_fiforead, 0x00);
  34.    WR_HARPOON(port+hp_xferstat, 0x00);
  35.    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
  36. }
  37. /*---------------------------------------------------------------------
  38.  *
  39.  * Function: Phase Bus Free
  40.  *
  41.  * Description: We just went bus free so figure out if it was
  42.  *              because of command complete or from a disconnect.
  43.  *
  44.  *---------------------------------------------------------------------*/
  45. #if defined(DOS)
  46. void phaseBusFree(USHORT port, UCHAR p_card)
  47. #else
  48. void phaseBusFree(ULONG port, UCHAR p_card)
  49. #endif
  50. {
  51.    PSCCB currSCCB;
  52.    currSCCB = BL_Card[p_card].currentSCCB;
  53.    if (currSCCB != NULL)
  54.       {
  55.       DISABLE_AUTO(port);
  56.       if (currSCCB->OperationCode == RESET_COMMAND)
  57.          {
  58. if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  59. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  60.      sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
  61. else
  62.      sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
  63.       queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
  64.       queueSearchSelect(&BL_Card[p_card],p_card);
  65.       }
  66.       else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
  67.       {
  68.       sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
  69.          (UCHAR)SYNC_SUPPORTED;
  70.       sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
  71.       }
  72.       else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
  73.       {
  74.       sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
  75.             (sccbMgrTbl[p_card][currSCCB->TargID].
  76.    TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
  77.       sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
  78.       }
  79. #if !defined(DOS)
  80.       else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
  81.       {
  82.       /* Make sure this is not a phony BUS_FREE.  If we were
  83.       reselected or if BUSY is NOT on then this is a
  84.       valid BUS FREE.  SRR Wednesday, 5/10/1995.     */
  85.       if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
  86.          (RDW_HARPOON((port+hp_intstat)) & RSEL))
  87.          {
  88.          sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
  89.          sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
  90.          }
  91.       else
  92.             {
  93.          return;
  94.          }
  95.          }
  96. #endif
  97.       else
  98.       {
  99.       currSCCB->Sccb_scsistat = BUS_FREE_ST;
  100.          if (!currSCCB->HostStatus)
  101.          {
  102.          currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
  103.          }
  104. if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  105. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  106.      sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
  107. else
  108.      sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
  109.       queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
  110.       return;
  111.       }
  112.       BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
  113.       } /*end if !=null */
  114. }
  115. #ident "$Id: automate.c 1.14 1997/01/31 02:11:46 mohan Exp $"
  116. /*----------------------------------------------------------------------
  117.  *
  118.  *
  119.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  120.  *
  121.  *   This file is available under both the GNU General Public License
  122.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  123.  *
  124.  *   $Workfile:   automate.c  $
  125.  *
  126.  *   Description:  Functions relating to programming the automation of
  127.  *                 the HARPOON.
  128.  *
  129.  *   $Date: 1997/01/31 02:11:46 $
  130.  *
  131.  *   $Revision: 1.14 $
  132.  *
  133.  *----------------------------------------------------------------------*/
  134. /*#include <globals.h>*/
  135. #if (FW_TYPE==_UCB_MGR_)
  136. /*#include <budi.h>*/
  137. #endif
  138. /*#include <sccbmgr.h>*/
  139. /*#include <blx30.h>*/
  140. /*#include <target.h>*/
  141. /*#include <scsi2.h>*/
  142. /*#include <harpoon.h>*/
  143. /*
  144. extern SCCBCARD BL_Card[MAX_CARDS];
  145. extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  146. extern SCCBCARD BL_Card[MAX_CARDS];
  147. */
  148. /*---------------------------------------------------------------------
  149.  *
  150.  * Function: Auto Load Default Map
  151.  *
  152.  * Description: Load the Automation RAM with the defualt map values.
  153.  *
  154.  *---------------------------------------------------------------------*/
  155. #if defined(DOS)
  156. void autoLoadDefaultMap(USHORT p_port)
  157. #else
  158. void autoLoadDefaultMap(ULONG p_port)
  159. #endif
  160. {
  161. #if defined(DOS)
  162.    USHORT map_addr;
  163. #else
  164.    ULONG map_addr;
  165. #endif
  166.    ARAM_ACCESS(p_port);
  167.    map_addr = p_port + hp_aramBase;
  168.    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0));  /*ID MESSAGE */
  169.    map_addr +=2;
  170.    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20));  /*SIMPLE TAG QUEUEING MSG */
  171.    map_addr +=2;
  172.    WRW_HARPOON(map_addr, RAT_OP);                   /*RESET ATTENTION */
  173.    map_addr +=2;
  174.    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00));  /*TAG ID MSG */
  175.    map_addr +=2;
  176.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 0 */
  177.    map_addr +=2;
  178.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 1 */
  179.    map_addr +=2;
  180.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 2 */
  181.    map_addr +=2;
  182.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 3 */
  183.    map_addr +=2;
  184.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 4 */
  185.    map_addr +=2;
  186.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 5 */
  187.    map_addr +=2;
  188.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 6 */
  189.    map_addr +=2;
  190.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 7 */
  191.    map_addr +=2;
  192.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 8 */
  193.    map_addr +=2;
  194.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 9 */
  195.    map_addr +=2;
  196.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 10 */
  197.    map_addr +=2;
  198.    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 11 */
  199.    map_addr +=2;
  200.    WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
  201.    map_addr +=2;
  202.    WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI));     /*JUMP IF NO DATA IN FIFO */
  203.    map_addr +=2;                                   /*This means AYNC DATA IN */
  204.    WRW_HARPOON(map_addr, (SSI_OP+   SSI_IDO_STRT)); /*STOP AND INTERRUPT */
  205.    map_addr +=2;
  206.    WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT));   /*JUMP IF NOT DATA IN PHZ */
  207.    map_addr +=2;
  208.    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  ST));    /*IF NOT MSG IN CHECK 4 DATA IN */
  209.    map_addr +=2;
  210.    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x02));  /*SAVE DATA PTR MSG? */
  211.    map_addr +=2;
  212.    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   DC));    /*GO CHECK FOR DISCONNECT MSG */
  213.    map_addr +=2;
  214.    WRW_HARPOON(map_addr, (MRR_OP+SDATA+    D_AR1)); /*SAVE DATA PTRS MSG */
  215.    map_addr +=2;
  216.    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  ST));    /*IF NOT MSG IN CHECK DATA IN */
  217.    map_addr +=2;
  218.    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x04));  /*DISCONNECT MSG? */
  219.    map_addr +=2;
  220.    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   UNKNWN));/*UKNKNOWN MSG */
  221.    map_addr +=2;
  222.    WRW_HARPOON(map_addr, (MRR_OP+SDATA+    D_BUCKET));/*XFER DISCONNECT MSG */
  223.    map_addr +=2;
  224.    WRW_HARPOON(map_addr, (SSI_OP+          SSI_ITAR_DISC));/*STOP AND INTERRUPT */
  225.    map_addr +=2;
  226.    WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+  UNKNWN));/*JUMP IF NOT STATUS PHZ. */
  227.    map_addr +=2;
  228.    WRW_HARPOON(map_addr, (MRR_OP+SDATA+  D_AR0));   /*GET STATUS BYTE */
  229.    map_addr +=2;
  230.    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  CC));    /*ERROR IF NOT MSG IN PHZ */
  231.    map_addr +=2;
  232.    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x00));  /*CHECK FOR CMD COMPLETE MSG. */
  233.    map_addr +=2;
  234.    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   CC));    /*ERROR IF NOT CMD COMPLETE MSG. */
  235.    map_addr +=2;
  236.    WRW_HARPOON(map_addr, (MRR_OP+SDATA+  D_BUCKET));/*GET CMD COMPLETE MSG */
  237.    map_addr +=2;
  238.    WRW_HARPOON(map_addr, (SSI_OP+       SSI_ICMD_COMP));/*END OF COMMAND */
  239.    map_addr +=2;
  240.    WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN));  /*RECEIVED UNKNOWN MSG BYTE */
  241.    map_addr +=2;
  242.    WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC));  /*NO COMMAND COMPLETE AFTER STATUS */
  243.    map_addr +=2;
  244.    WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
  245.    map_addr +=2;
  246.    WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL));  /*EXPECTED ID/TAG MESSAGES AND */
  247.    map_addr +=2;                             /* DIDN'T GET ONE */
  248.    WRW_HARPOON(map_addr, (CRR_OP+AR3+  S_IDREG)); /* comp SCSI SEL ID & AR3*/
  249.    map_addr +=2;
  250.    WRW_HARPOON(map_addr, (BRH_OP+EQUAL+   0x00));    /*SEL ID OK then Conti. */
  251.    map_addr +=2;
  252.    WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC));  /*NO COMMAND COMPLETE AFTER STATUS */
  253.    SGRAM_ACCESS(p_port);
  254. }
  255. /*---------------------------------------------------------------------
  256.  *
  257.  * Function: Auto Command Complete
  258.  *
  259.  * Description: Post command back to host and find another command
  260.  *              to execute.
  261.  *
  262.  *---------------------------------------------------------------------*/
  263. #if defined(DOS)
  264. void autoCmdCmplt(USHORT p_port, UCHAR p_card)
  265. #else
  266. void autoCmdCmplt(ULONG p_port, UCHAR p_card)
  267. #endif
  268. {
  269.    PSCCB currSCCB;
  270.    UCHAR status_byte;
  271.    currSCCB = BL_Card[p_card].currentSCCB;
  272.    status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
  273.    sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = FALSE;
  274.    if (status_byte != SSGOOD) {
  275.       if (status_byte == SSQ_FULL) {
  276. if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  277. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  278. {
  279.          sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
  280. if(BL_Card[p_card].discQCount != 0)
  281. BL_Card[p_card].discQCount--;
  282. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
  283. }
  284. else
  285. {
  286.          sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
  287. if(currSCCB->Sccb_tag)
  288. {
  289. if(BL_Card[p_card].discQCount != 0)
  290. BL_Card[p_card].discQCount--;
  291. BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  292. }else
  293. {
  294. if(BL_Card[p_card].discQCount != 0)
  295. BL_Card[p_card].discQCount--;
  296. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
  297. }
  298. }
  299.          currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
  300.          queueSelectFail(&BL_Card[p_card],p_card);
  301.          return;
  302.          }
  303.       if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
  304.          {
  305.          sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
  306.             (UCHAR)SYNC_SUPPORTED;
  307.       sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
  308.          BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
  309. if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  310. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  311. {
  312.          sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
  313. if(BL_Card[p_card].discQCount != 0)
  314. BL_Card[p_card].discQCount--;
  315. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
  316. }
  317. else
  318. {
  319.          sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
  320. if(currSCCB->Sccb_tag)
  321. {
  322. if(BL_Card[p_card].discQCount != 0)
  323. BL_Card[p_card].discQCount--;
  324. BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  325. }else
  326. {
  327. if(BL_Card[p_card].discQCount != 0)
  328. BL_Card[p_card].discQCount--;
  329. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
  330. }
  331. }
  332.          return;
  333.          }
  334.       if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
  335.          {
  336.       sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
  337.          (sccbMgrTbl[p_card][currSCCB->TargID].
  338.          TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
  339.       sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
  340.          BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
  341. if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  342. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  343. {
  344.          sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
  345. if(BL_Card[p_card].discQCount != 0)
  346. BL_Card[p_card].discQCount--;
  347. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
  348. }
  349. else
  350. {
  351.          sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
  352. if(currSCCB->Sccb_tag)
  353. {
  354. if(BL_Card[p_card].discQCount != 0)
  355. BL_Card[p_card].discQCount--;
  356. BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  357. }else
  358. {
  359. if(BL_Card[p_card].discQCount != 0)
  360. BL_Card[p_card].discQCount--;
  361. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
  362. }
  363. }
  364.          return;
  365.       
  366.          }
  367.      
  368.    if (status_byte == SSCHECK) 
  369. {
  370. if(BL_Card[p_card].globalFlags & F_DO_RENEGO)
  371. {
  372. if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
  373. {
  374. sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
  375. }
  376. if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
  377. {
  378. sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
  379. }
  380. }
  381. }
  382.       if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
  383.          currSCCB->SccbStatus = SCCB_ERROR;
  384.          currSCCB->TargetStatus = status_byte;
  385.          if (status_byte == SSCHECK) {
  386.             sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
  387.                = TRUE;
  388.      
  389. #if (FW_TYPE==_SCCB_MGR_)
  390.             if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
  391.                if (currSCCB->RequestSenseLength == 0)
  392.                   currSCCB->RequestSenseLength = 14;
  393.                ssenss(&BL_Card[p_card]);
  394.                BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
  395.   if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  396. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  397. {
  398.          sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
  399. if(BL_Card[p_card].discQCount != 0)
  400. BL_Card[p_card].discQCount--;
  401. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
  402. }
  403. else
  404. {
  405.           sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
  406. if(currSCCB->Sccb_tag)
  407. {
  408. if(BL_Card[p_card].discQCount != 0)
  409. BL_Card[p_card].discQCount--;
  410. BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  411. }else
  412. {
  413. if(BL_Card[p_card].discQCount != 0)
  414. BL_Card[p_card].discQCount--;
  415. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
  416. }
  417. }
  418.                return;
  419.                }
  420. #else
  421.    if ((!(currSCCB->Sccb_ucb_ptr->UCB_opcode & OPC_NO_AUTO_SENSE)) &&
  422.     (currSCCB->RequestSenseLength))
  423.    {
  424.     ssenss(&BL_Card[p_card]);
  425.       BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
  426. if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  427. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  428. {
  429.           sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
  430. if(BL_Card[p_card].discQCount != 0)
  431. BL_Card[p_card].discQCount--;
  432. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
  433. }
  434. else
  435. {
  436.           sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
  437. if(currSCCB->Sccb_tag)
  438. {
  439. if(BL_Card[p_card].discQCount != 0)
  440. BL_Card[p_card].discQCount--;
  441. BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  442. }else
  443. {
  444. if(BL_Card[p_card].discQCount != 0)
  445. BL_Card[p_card].discQCount--;
  446. BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
  447. }
  448. }
  449.       return;
  450.    }
  451. #endif
  452.             }
  453.          }
  454.       }
  455. if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  456. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  457.    sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
  458. else
  459.    sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
  460.    queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
  461. }
  462. #ident "$Id: busmstr.c 1.8 1997/01/31 02:10:27 mohan Exp $"
  463. /*----------------------------------------------------------------------
  464.  *
  465.  *
  466.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  467.  *
  468.  *   This file is available under both the GNU General Public License
  469.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  470.  *
  471.  *   $Workfile:   busmstr.c  $
  472.  *
  473.  *   Description:  Functions to start, stop, and abort BusMaster operations.
  474.  *
  475.  *   $Date: 1997/01/31 02:10:27 $
  476.  *
  477.  *   $Revision: 1.8 $
  478.  *
  479.  *----------------------------------------------------------------------*/
  480. /*#include <globals.h>*/
  481. #if (FW_TYPE==_UCB_MGR_)
  482. /*#include <budi.h>*/
  483. #endif
  484. /*#include <sccbmgr.h>*/
  485. /*#include <blx30.h>*/
  486. /*#include <target.h>*/
  487. /*#include <scsi2.h>*/
  488. /*#include <harpoon.h>*/
  489. /*
  490. extern SCCBCARD BL_Card[MAX_CARDS];
  491. extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  492. */
  493. #define SHORT_WAIT   0x0000000F
  494. #define LONG_WAIT    0x0000FFFFL
  495. #if defined(BUGBUG)
  496. void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
  497. #endif
  498. /*---------------------------------------------------------------------
  499.  *
  500.  * Function: Data Transfer Processor
  501.  *
  502.  * Description: This routine performs two tasks.
  503.  *              (1) Start data transfer by calling HOST_DATA_XFER_START
  504.  *              function.  Once data transfer is started, (2) Depends
  505.  *              on the type of data transfer mode Scatter/Gather mode
  506.  *              or NON Scatter/Gather mode.  In NON Scatter/Gather mode,
  507.  *              this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
  508.  *              data transfer done.  In Scatter/Gather mode, this routine
  509.  *              checks bus master command complete and dual rank busy
  510.  *              bit to keep chaining SC transfer command.  Similarly,
  511.  *              in Scatter/Gather mode, it checks Sccb_MGRFlag
  512.  *              (F_HOST_XFER_ACT bit) for data transfer done.
  513.  *              
  514.  *---------------------------------------------------------------------*/
  515. #if defined(DOS)
  516. void dataXferProcessor(USHORT port, PSCCBcard pCurrCard)
  517. #else
  518. void dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
  519. #endif
  520. {
  521.    PSCCB currSCCB;
  522.    currSCCB = pCurrCard->currentSCCB;
  523.       if (currSCCB->Sccb_XferState & F_SG_XFER)
  524. {
  525. if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
  526. {
  527.     currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
  528.           currSCCB->Sccb_SGoffset = 0x00; 
  529.   }
  530. pCurrCard->globalFlags |= F_HOST_XFER_ACT;
  531.          
  532.          busMstrSGDataXferStart(port, currSCCB);
  533. }
  534.       else
  535. {
  536. if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
  537. {
  538. pCurrCard->globalFlags |= F_HOST_XFER_ACT;
  539.          
  540.           busMstrDataXferStart(port, currSCCB);
  541.           }
  542. }
  543. }
  544. /*---------------------------------------------------------------------
  545.  *
  546.  * Function: BusMaster Scatter Gather Data Transfer Start
  547.  *
  548.  * Description:
  549.  *
  550.  *---------------------------------------------------------------------*/
  551. #if defined(DOS)
  552. void busMstrSGDataXferStart(USHORT p_port, PSCCB pcurrSCCB)
  553. #else
  554. void busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
  555. #endif
  556. {
  557.    ULONG count,addr,tmpSGCnt;
  558.    UINT sg_index;
  559.    UCHAR sg_count, i;
  560. #if defined(DOS)
  561.    USHORT reg_offset;
  562. #else
  563.    ULONG reg_offset;
  564. #endif
  565.    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
  566.       count =  ((ULONG) HOST_RD_CMD)<<24;
  567.       }
  568.    else {
  569.       count =  ((ULONG) HOST_WRT_CMD)<<24;
  570.       }
  571.    sg_count = 0;
  572.    tmpSGCnt = 0;
  573.    sg_index = pcurrSCCB->Sccb_sgseg;
  574.    reg_offset = hp_aramBase;
  575. i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
  576. WR_HARPOON(p_port+hp_page_ctrl, i);
  577.    while ((sg_count < (UCHAR)SG_BUF_CNT) &&
  578.       ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
  579. #if defined(COMPILER_16_BIT) && !defined(DOS)
  580.       tmpSGCnt += *(((ULONG far *)pcurrSCCB->DataPointer)+
  581.          (sg_index * 2));
  582.       count |= *(((ULONG far *)pcurrSCCB->DataPointer)+
  583.          (sg_index * 2));
  584.       addr = *(((ULONG far *)pcurrSCCB->DataPointer)+
  585.          ((sg_index * 2) + 1));
  586. #else
  587.       tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
  588.          (sg_index * 2));
  589.       count |= *(((ULONG *)pcurrSCCB->DataPointer)+
  590.          (sg_index * 2));
  591.       addr = *(((ULONG *)pcurrSCCB->DataPointer)+
  592.          ((sg_index * 2) + 1));
  593. #endif
  594.       if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
  595.          addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
  596.          count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
  597.          tmpSGCnt = count & 0x00FFFFFFL;
  598.          }
  599.       WR_HARP32(p_port,reg_offset,addr);
  600.       reg_offset +=4;
  601.       WR_HARP32(p_port,reg_offset,count);
  602.       reg_offset +=4;
  603.       count &= 0xFF000000L;
  604.       sg_index++;
  605.       sg_count++;
  606.       } /*End While */
  607.    pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
  608.    WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
  609.    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
  610.       WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
  611.       WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
  612.       WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
  613.       }
  614.    else {
  615.       if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
  616.          (tmpSGCnt & 0x000000001))
  617.          {
  618.          pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
  619.          tmpSGCnt--;
  620.          }
  621.       WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
  622.       WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
  623.       WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
  624.       }
  625.    WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
  626. }
  627. /*---------------------------------------------------------------------
  628.  *
  629.  * Function: BusMaster Data Transfer Start
  630.  *
  631.  * Description: 
  632.  *
  633.  *---------------------------------------------------------------------*/
  634. #if defined(DOS)
  635. void busMstrDataXferStart(USHORT p_port, PSCCB pcurrSCCB)
  636. #else
  637. void busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
  638. #endif
  639. {
  640.    ULONG addr,count;
  641.    if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
  642.       count = pcurrSCCB->Sccb_XferCnt;
  643.       addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
  644.       }
  645.    else {
  646.       addr = pcurrSCCB->SensePointer;
  647.       count = pcurrSCCB->RequestSenseLength;
  648.       }
  649. #if defined(DOS)
  650.    asm { mov dx,p_port;
  651.          mov ax,word ptr count;
  652.          add dx,hp_xfer_cnt_lo;
  653.          out dx,al;
  654.          inc dx;
  655.          xchg ah,al
  656.          out dx,al;
  657.          inc dx;
  658.          mov ax,word ptr count+2;
  659.          out dx,al;
  660.          inc dx;
  661.          inc dx;
  662.          mov ax,word ptr addr;
  663.          out dx,al;
  664.          inc dx;
  665.          xchg ah,al
  666.          out dx,al;
  667.          inc dx;
  668.          mov ax,word ptr addr+2;
  669.          out dx,al;
  670.          inc dx;
  671.          xchg ah,al
  672.          out dx,al;
  673.          }
  674.    WR_HARP32(p_port,hp_xfercnt_0,count);
  675. #else
  676.    HP_SETUP_ADDR_CNT(p_port,addr,count);
  677. #endif
  678.    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
  679.       WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
  680.       WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
  681.       WR_HARPOON(p_port+hp_xfer_cmd,
  682.          (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
  683.       }
  684.    else {
  685.       WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
  686.       WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
  687.       WR_HARPOON(p_port+hp_xfer_cmd,
  688.          (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
  689.       }
  690. }
  691. /*---------------------------------------------------------------------
  692.  *
  693.  * Function: BusMaster Timeout Handler
  694.  *
  695.  * Description: This function is called after a bus master command busy time
  696.  *               out is detected.  This routines issue halt state machine
  697.  *               with a software time out for command busy.  If command busy
  698.  *               is still asserted at the end of the time out, it issues
  699.  *               hard abort with another software time out.  It hard abort
  700.  *               command busy is also time out, it'll just give up.
  701.  *
  702.  *---------------------------------------------------------------------*/
  703. #if defined(DOS)
  704. UCHAR busMstrTimeOut(USHORT p_port)
  705. #else
  706. UCHAR busMstrTimeOut(ULONG p_port)
  707. #endif
  708. {
  709.    ULONG timeout;
  710.    timeout = LONG_WAIT;
  711.    WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
  712.    while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
  713.    
  714.    
  715.    if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
  716.       WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
  717.       timeout = LONG_WAIT;
  718.       while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
  719.       }
  720.    RD_HARPOON(p_port+hp_int_status);           /*Clear command complete */
  721.    if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
  722.       return(TRUE);
  723.       }
  724.    else {
  725.       return(FALSE);
  726.       }
  727. }
  728. /*---------------------------------------------------------------------
  729.  *
  730.  * Function: Host Data Transfer Abort
  731.  *
  732.  * Description: Abort any in progress transfer.
  733.  *
  734.  *---------------------------------------------------------------------*/
  735. #if defined(DOS)
  736. void hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB)
  737. #else
  738. void hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
  739. #endif
  740. {
  741.    ULONG timeout;
  742.    ULONG remain_cnt;
  743.    UINT sg_ptr;
  744.    BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
  745.    if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
  746.       if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
  747.          WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
  748.          timeout = LONG_WAIT;
  749.          while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
  750.          WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
  751.          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
  752.             if (busMstrTimeOut(port)) {
  753.                if (pCurrSCCB->HostStatus == 0x00)
  754.                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
  755.                }
  756.             if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) 
  757.                if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) 
  758.                   if (pCurrSCCB->HostStatus == 0x00)
  759.                      {
  760.                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
  761. #if defined(BUGBUG)
  762.                      WR_HARPOON(port+hp_dual_addr_lo,
  763.                         RD_HARPOON(port+hp_ext_status));
  764. #endif
  765.                      }
  766.             }
  767.          }
  768.       }
  769.    else if (pCurrSCCB->Sccb_XferCnt) {
  770.       if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
  771.               WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
  772.             ~SCATTER_EN));
  773.          WR_HARPOON(port+hp_sg_addr,0x00);
  774.          sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
  775.          if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
  776.             sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
  777.             }
  778.          remain_cnt = pCurrSCCB->Sccb_XferCnt;
  779.          while (remain_cnt < 0x01000000L) {
  780.             sg_ptr--;
  781. #if defined(COMPILER_16_BIT) && !defined(DOS)
  782.             if (remain_cnt > (ULONG)(*(((ULONG far *)pCurrSCCB->
  783.                DataPointer) + (sg_ptr * 2)))) {
  784.                remain_cnt -= (ULONG)(*(((ULONG far *)pCurrSCCB->
  785.                   DataPointer) + (sg_ptr * 2)));
  786.                }
  787. #else
  788.             if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
  789.                DataPointer) + (sg_ptr * 2)))) {
  790.                remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
  791.                   DataPointer) + (sg_ptr * 2)));
  792.                }
  793. #endif
  794.             else {
  795.                break;
  796.                }
  797.             }
  798.          if (remain_cnt < 0x01000000L) {
  799.             pCurrSCCB->Sccb_SGoffset = remain_cnt;
  800.             pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
  801.             if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength 
  802.                 && (remain_cnt == 0))
  803.                pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
  804.             }
  805.          else {
  806.             if (pCurrSCCB->HostStatus == 0x00) {
  807.                pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
  808.                }
  809.             }
  810.          }
  811.       if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
  812.          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
  813.             busMstrTimeOut(port);
  814.             }
  815.          else {
  816.             if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
  817.                if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
  818.                   if (pCurrSCCB->HostStatus == 0x00) {
  819.                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
  820. #if defined(BUGBUG)
  821.                      WR_HARPOON(port+hp_dual_addr_lo,
  822.                         RD_HARPOON(port+hp_ext_status));
  823. #endif
  824.                      }
  825.                   }
  826.                }
  827.             }
  828.          }
  829.       else {
  830.          if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
  831.             timeout = SHORT_WAIT;
  832.             while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
  833.                ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
  834.                timeout--) {}
  835.             }
  836.          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
  837.             WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
  838.                FLUSH_XFER_CNTR));
  839.             timeout = LONG_WAIT;
  840.             while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
  841.                timeout--) {}
  842.             WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
  843.                ~FLUSH_XFER_CNTR));
  844.             if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
  845.                if (pCurrSCCB->HostStatus == 0x00) {
  846.                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
  847.                   }
  848.                busMstrTimeOut(port);
  849.                }
  850.             }
  851.          if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
  852.             if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
  853.                if (pCurrSCCB->HostStatus == 0x00) {
  854.                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
  855. #if defined(BUGBUG)
  856.                   WR_HARPOON(port+hp_dual_addr_lo,
  857.                      RD_HARPOON(port+hp_ext_status));
  858. #endif
  859.                   }
  860.                }
  861.             }
  862.          }
  863.       }
  864.    else {
  865.       if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
  866.          timeout = LONG_WAIT;
  867.          while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
  868.          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
  869.             if (pCurrSCCB->HostStatus == 0x00) {
  870.                pCurrSCCB->HostStatus = SCCB_BM_ERR;
  871.                }
  872.             busMstrTimeOut(port);
  873.             }
  874.          }
  875.       if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
  876.          if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
  877.             if (pCurrSCCB->HostStatus == 0x00) {
  878.                pCurrSCCB->HostStatus = SCCB_BM_ERR;
  879. #if defined(BUGBUG)
  880.                WR_HARPOON(port+hp_dual_addr_lo,
  881.                   RD_HARPOON(port+hp_ext_status));
  882. #endif
  883.                }
  884.             }
  885.          }
  886.       if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
  887.          WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
  888.                  ~SCATTER_EN));
  889.          WR_HARPOON(port+hp_sg_addr,0x00);
  890.          pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
  891.          pCurrSCCB->Sccb_SGoffset = 0x00; 
  892.          if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
  893.             pCurrSCCB->DataLength) {
  894.             pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
  895.             pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
  896.             }
  897.          }
  898.       else {
  899.          if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
  900.             pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
  901.          }
  902.       }
  903.    WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
  904. }
  905. /*---------------------------------------------------------------------
  906.  *
  907.  * Function: Host Data Transfer Restart
  908.  *
  909.  * Description: Reset the available count due to a restore data
  910.  *              pointers message.
  911.  *
  912.  *---------------------------------------------------------------------*/
  913. void hostDataXferRestart(PSCCB currSCCB)
  914. {
  915.    ULONG data_count;
  916.    UINT  sg_index;
  917. #if defined(COMPILER_16_BIT) && !defined(DOS)
  918.    ULONG far *sg_ptr;
  919. #else
  920.    ULONG *sg_ptr;
  921. #endif
  922.    if (currSCCB->Sccb_XferState & F_SG_XFER) {
  923.       currSCCB->Sccb_XferCnt = 0;
  924.       sg_index = 0xffff;         /*Index by long words into sg list. */
  925.       data_count = 0;            /*Running count of SG xfer counts. */
  926. #if defined(COMPILER_16_BIT) && !defined(DOS)
  927.       sg_ptr = (ULONG far *)currSCCB->DataPointer;
  928. #else
  929.       sg_ptr = (ULONG *)currSCCB->DataPointer;
  930. #endif
  931.       while (data_count < currSCCB->Sccb_ATC) {
  932.          sg_index++;
  933.          data_count += *(sg_ptr+(sg_index * 2));
  934.          }
  935.       if (data_count == currSCCB->Sccb_ATC) {
  936.          currSCCB->Sccb_SGoffset = 0;
  937.          sg_index++;
  938.          }
  939.       else {
  940.          currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
  941.          }
  942.       currSCCB->Sccb_sgseg = (USHORT)sg_index;
  943.       }
  944.    else {
  945.       currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
  946.       }
  947. }
  948. #ident "$Id: scam.c 1.17 1997/03/20 23:49:37 mohan Exp $"
  949. /*----------------------------------------------------------------------
  950.  *
  951.  *
  952.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  953.  *
  954.  *   This file is available under both the GNU General Public License
  955.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  956.  *
  957.  *   $Workfile:   scam.c  $
  958.  *
  959.  *   Description:  Functions relating to handling of the SCAM selection
  960.  *                 and the determination of the SCSI IDs to be assigned
  961.  *                 to all perspective SCSI targets.
  962.  *
  963.  *   $Date: 1997/03/20 23:49:37 $
  964.  *
  965.  *   $Revision: 1.17 $
  966.  *
  967.  *----------------------------------------------------------------------*/
  968. /*#include <globals.h>*/
  969. #if (FW_TYPE==_UCB_MGR_)
  970. /*#include <budi.h>*/
  971. #endif
  972. /*#include <sccbmgr.h>*/
  973. /*#include <blx30.h>*/
  974. /*#include <target.h>*/
  975. /*#include <scsi2.h>*/
  976. /*#include <eeprom.h>*/
  977. /*#include <harpoon.h>*/
  978. /*
  979. extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  980. extern SCCBCARD BL_Card[MAX_CARDS];
  981. extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR];
  982. extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
  983. #if defined(DOS) || defined(OS2)
  984. extern UCHAR temp_id_string[ID_STRING_LENGTH];
  985. #endif
  986. extern UCHAR scamHAString[];
  987. */
  988. /*---------------------------------------------------------------------
  989.  *
  990.  * Function: scini
  991.  *
  992.  * Description: Setup all data structures necessary for SCAM selection.
  993.  *
  994.  *---------------------------------------------------------------------*/
  995. void scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
  996. {
  997. #if defined(SCAM_LEV_2)
  998.    UCHAR loser,assigned_id;
  999. #endif
  1000. #if defined(DOS)
  1001.    USHORT p_port;
  1002. #else
  1003.    ULONG p_port;
  1004. #endif
  1005.    UCHAR i,k,ScamFlg ;
  1006.    PSCCBcard currCard;
  1007. PNVRamInfo pCurrNvRam;
  1008.    currCard = &BL_Card[p_card];
  1009.    p_port = currCard->ioPort;
  1010. pCurrNvRam = currCard->pNvRamInfo;
  1011. if(pCurrNvRam){
  1012. ScamFlg = pCurrNvRam->niScamConf;
  1013. i = pCurrNvRam->niSysConf;
  1014. }
  1015. else{
  1016.    ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2);
  1017.    i = (UCHAR)(utilEERead(p_port, (SYSTEM_CONFIG/2)));
  1018. }
  1019. if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
  1020. return;
  1021.    inisci(p_card,p_port, p_our_id);
  1022.    /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
  1023.       too slow to return to SCAM selection */
  1024.    /* if (p_power_up)
  1025.          Wait1Second(p_port);
  1026.       else
  1027.          Wait(p_port, TO_250ms); */
  1028.    Wait1Second(p_port);
  1029. #if defined(SCAM_LEV_2)
  1030.    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
  1031.       {
  1032.       while (!(scarb(p_port,INIT_SELTD))) {}
  1033.       scsel(p_port);
  1034.       do {
  1035.          scxferc(p_port,SYNC_PTRN);
  1036.          scxferc(p_port,DOM_MSTR);
  1037.          loser = scsendi(p_port,&scamInfo[p_our_id].id_string[0]);
  1038.          } while ( loser == 0xFF );
  1039.       scbusf(p_port);
  1040.       if ((p_power_up) && (!loser))
  1041.          {
  1042.          sresb(p_port,p_card);
  1043.          Wait(p_port, TO_250ms);
  1044.          while (!(scarb(p_port,INIT_SELTD))) {}
  1045.          scsel(p_port);
  1046.          do {
  1047.             scxferc(p_port, SYNC_PTRN);
  1048.             scxferc(p_port, DOM_MSTR);
  1049.             loser = scsendi(p_port,&scamInfo[p_our_id].
  1050.                id_string[0]);
  1051.             } while ( loser == 0xFF );
  1052.          scbusf(p_port);
  1053.          }
  1054.       }
  1055.    else
  1056.       {
  1057.       loser = FALSE;
  1058.       }
  1059.    if (!loser)
  1060.       {
  1061. #endif  /* SCAM_LEV_2 */
  1062.       scamInfo[p_our_id].state = ID_ASSIGNED;
  1063. if (ScamFlg & SCAM_ENABLED)
  1064. {
  1065.       for (i=0; i < MAX_SCSI_TAR; i++)
  1066.       {
  1067.           if ((scamInfo[i].state == ID_UNASSIGNED) ||
  1068.              (scamInfo[i].state == ID_UNUSED))
  1069.          {
  1070.              if (scsell(p_port,i))
  1071.              {
  1072.                 scamInfo[i].state = LEGACY;
  1073.                 if ((scamInfo[i].id_string[0] != 0xFF) ||
  1074.                    (scamInfo[i].id_string[1] != 0xFA))
  1075.                {
  1076.                    scamInfo[i].id_string[0] = 0xFF;
  1077.                    scamInfo[i].id_string[1] = 0xFA;
  1078. if(pCurrNvRam == NULL)
  1079.                    currCard->globalFlags |= F_UPDATE_EEPROM;
  1080.                 }
  1081.             }
  1082.           }
  1083.        }
  1084.       sresb(p_port,p_card);
  1085.        Wait1Second(p_port);
  1086.          while (!(scarb(p_port,INIT_SELTD))) {}
  1087.          scsel(p_port);
  1088.          scasid(p_card, p_port);
  1089.          }
  1090. #if defined(SCAM_LEV_2)
  1091.       }
  1092.    else if ((loser) && (ScamFlg & SCAM_ENABLED))
  1093.       {
  1094.       scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
  1095.       assigned_id = FALSE;
  1096.       scwtsel(p_port);
  1097.       do {
  1098.          while (scxferc(p_port,0x00) != SYNC_PTRN) {}
  1099.          i = scxferc(p_port,0x00);
  1100.          if (i == ASSIGN_ID)
  1101.             {
  1102.             if (!(scsendi(p_port,&scamInfo[p_our_id].id_string[0])))
  1103.                   {
  1104.                   i = scxferc(p_port,0x00);
  1105.                   if (scvalq(i))
  1106.                      {
  1107.                      k = scxferc(p_port,0x00);
  1108.                      if (scvalq(k))
  1109.                         {
  1110.                         currCard->ourId =
  1111.                            ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
  1112.                         inisci(p_card, p_port, p_our_id);
  1113.                         scamInfo[currCard->ourId].state = ID_ASSIGNED;
  1114.                         scamInfo[currCard->ourId].id_string[0]
  1115.                            = SLV_TYPE_CODE0;
  1116.                         assigned_id = TRUE;
  1117.                         }
  1118.                      }
  1119.                   }
  1120.             }
  1121.          else if (i == SET_P_FLAG)
  1122.             {
  1123.                if (!(scsendi(p_port,
  1124.                         &scamInfo[p_our_id].id_string[0])))
  1125.                         scamInfo[p_our_id].id_string[0] |= 0x80;
  1126.             }
  1127.          }while (!assigned_id);
  1128.       while (scxferc(p_port,0x00) != CFG_CMPLT) {}
  1129.       }
  1130. #endif   /* SCAM_LEV_2 */
  1131.    if (ScamFlg & SCAM_ENABLED)
  1132.       {
  1133.       scbusf(p_port);
  1134.       if (currCard->globalFlags & F_UPDATE_EEPROM)
  1135.          {
  1136.          scsavdi(p_card, p_port);
  1137.          currCard->globalFlags &= ~F_UPDATE_EEPROM;
  1138.          }
  1139.       }
  1140. #if defined(DOS)
  1141.    for (i=0; i < MAX_SCSI_TAR; i++)
  1142.    {
  1143.       if (((ScamFlg & SCAM_ENABLED) && (scamInfo[i].state == LEGACY))
  1144. || (i != p_our_id))
  1145.          {
  1146.          scsellDOS(p_port,i);
  1147.          }
  1148.    }
  1149. #endif
  1150. /*
  1151.    for (i=0,k=0; i < MAX_SCSI_TAR; i++)
  1152.       {
  1153.       if ((scamInfo[i].state == ID_ASSIGNED) ||
  1154.          (scamInfo[i].state == LEGACY))
  1155.          k++;
  1156.       }
  1157.    if (k==2)
  1158.       currCard->globalFlags |= F_SINGLE_DEVICE;
  1159.    else
  1160.       currCard->globalFlags &= ~F_SINGLE_DEVICE;
  1161. */
  1162. }
  1163. /*---------------------------------------------------------------------
  1164.  *
  1165.  * Function: scarb
  1166.  *
  1167.  * Description: Gain control of the bus and wait SCAM select time (250ms)
  1168.  *
  1169.  *---------------------------------------------------------------------*/
  1170. #if defined(DOS)
  1171. int scarb(USHORT p_port, UCHAR p_sel_type)
  1172. #else
  1173. int scarb(ULONG p_port, UCHAR p_sel_type)
  1174. #endif
  1175. {
  1176.    if (p_sel_type == INIT_SELTD)
  1177.       {
  1178.       while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
  1179.       if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
  1180.          return(FALSE);
  1181.       if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
  1182.          return(FALSE);
  1183.       WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
  1184.       if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
  1185.          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
  1186.             ~SCSI_BSY));
  1187.          return(FALSE);
  1188.          }
  1189.       WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
  1190.       if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
  1191.          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
  1192.             ~(SCSI_BSY | SCSI_SEL)));
  1193.          return(FALSE);
  1194.          }
  1195.       }
  1196.    WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
  1197.       & ~ACTdeassert));
  1198.    WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
  1199.    WR_HARPOON(p_port+hp_scsidata_0, 0x00);
  1200. #if defined(WIDE_SCSI)
  1201.    WR_HARPOON(p_port+hp_scsidata_1, 0x00);
  1202. #endif
  1203.    WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
  1204.    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
  1205.    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
  1206.       & ~SCSI_BSY));
  1207.    Wait(p_port,TO_250ms);
  1208.    return(TRUE);
  1209. }
  1210. /*---------------------------------------------------------------------
  1211.  *
  1212.  * Function: scbusf
  1213.  *
  1214.  * Description: Release the SCSI bus and disable SCAM selection.
  1215.  *
  1216.  *---------------------------------------------------------------------*/
  1217. #if defined(DOS)
  1218. void scbusf(USHORT p_port)
  1219. #else
  1220. void scbusf(ULONG p_port)
  1221. #endif
  1222. {
  1223.    WR_HARPOON(p_port+hp_page_ctrl,
  1224.       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
  1225.    WR_HARPOON(p_port+hp_scsidata_0, 0x00);
  1226.    WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
  1227.       & ~SCSI_BUS_EN));
  1228.    WR_HARPOON(p_port+hp_scsisig, 0x00);
  1229.    WR_HARPOON(p_port+hp_scsireset,  (RD_HARPOON(p_port+hp_scsireset)
  1230.       & ~SCAM_EN));
  1231.    WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
  1232.       | ACTdeassert));
  1233. #if defined(SCAM_LEV_2)
  1234.    WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
  1235. #else
  1236.    WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT));
  1237. #endif
  1238.    WR_HARPOON(p_port+hp_page_ctrl,
  1239.       (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
  1240. }
  1241. /*---------------------------------------------------------------------
  1242.  *
  1243.  * Function: scasid
  1244.  *
  1245.  * Description: Assign an ID to all the SCAM devices.
  1246.  *
  1247.  *---------------------------------------------------------------------*/
  1248. #if defined(DOS)
  1249. void scasid(UCHAR p_card, USHORT p_port)
  1250. #else
  1251. void scasid(UCHAR p_card, ULONG p_port)
  1252. #endif
  1253. {
  1254. #if defined(DOS) || defined(OS2)
  1255.    /* Use external defined in global space area, instead of Stack
  1256.       space. WIN/95 DOS doesnot work TINY mode. The OS doesnot intialize
  1257.       SS equal to DS. Thus the array allocated on stack doesnot get
  1258.       access correctly */
  1259. #else
  1260.    UCHAR temp_id_string[ID_STRING_LENGTH];
  1261. #endif
  1262.    UCHAR i,k,scam_id;
  1263. UCHAR crcBytes[3];
  1264. PNVRamInfo pCurrNvRam;
  1265. ushort_ptr pCrcBytes;
  1266. pCurrNvRam = BL_Card[p_card].pNvRamInfo;
  1267.    i=FALSE;
  1268.    while (!i)
  1269.       {
  1270.       for (k=0; k < ID_STRING_LENGTH; k++)
  1271.          {
  1272.          temp_id_string[k] = (UCHAR) 0x00;
  1273.          }
  1274.       scxferc(p_port,SYNC_PTRN);
  1275.       scxferc(p_port,ASSIGN_ID);
  1276.       if (!(sciso(p_port,&temp_id_string[0])))
  1277.          {
  1278. if(pCurrNvRam){
  1279. pCrcBytes = (ushort_ptr)&crcBytes[0];
  1280. *pCrcBytes = CalcCrc16(&temp_id_string[0]);
  1281. crcBytes[2] = CalcLrc(&temp_id_string[0]);
  1282. temp_id_string[1] = crcBytes[2];
  1283. temp_id_string[2] = crcBytes[0];
  1284. temp_id_string[3] = crcBytes[1];
  1285. for(k = 4; k < ID_STRING_LENGTH; k++)
  1286. temp_id_string[k] = (UCHAR) 0x00;
  1287. }
  1288.          i = scmachid(p_card,temp_id_string);
  1289.          if (i == CLR_PRIORITY)
  1290.             {
  1291.             scxferc(p_port,MISC_CODE);
  1292.             scxferc(p_port,CLR_P_FLAG);
  1293.             i = FALSE;  /*Not the last ID yet. */
  1294.             }
  1295.          else if (i != NO_ID_AVAIL)
  1296.             {
  1297.             if (i < 8 )
  1298.                scxferc(p_port,ID_0_7);
  1299.             else
  1300.                scxferc(p_port,ID_8_F);
  1301.             scam_id = (i & (UCHAR) 0x07);
  1302.             for (k=1; k < 0x08; k <<= 1)
  1303.                if (!( k & i ))
  1304.                   scam_id += 0x08;        /*Count number of zeros in DB0-3. */
  1305.             scxferc(p_port,scam_id);
  1306.             i = FALSE;  /*Not the last ID yet. */
  1307.             }
  1308.          }
  1309.       else
  1310.          {
  1311.          i = TRUE;
  1312.          }
  1313.       }  /*End while */
  1314.    scxferc(p_port,SYNC_PTRN);
  1315.    scxferc(p_port,CFG_CMPLT);
  1316. }
  1317. /*---------------------------------------------------------------------
  1318.  *
  1319.  * Function: scsel
  1320.  *
  1321.  * Description: Select all the SCAM devices.
  1322.  *
  1323.  *---------------------------------------------------------------------*/
  1324. #if defined(DOS)
  1325. void scsel(USHORT p_port)
  1326. #else
  1327. void scsel(ULONG p_port)
  1328. #endif
  1329. {
  1330.    WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
  1331.    scwiros(p_port, SCSI_MSG);
  1332.    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
  1333.    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
  1334.    WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
  1335.       (UCHAR)(BIT(7)+BIT(6))));
  1336.    WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
  1337.    scwiros(p_port, SCSI_SEL);
  1338.    WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
  1339.       ~(UCHAR)BIT(6)));
  1340.    scwirod(p_port, BIT(6));
  1341.    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
  1342. }
  1343. /*---------------------------------------------------------------------
  1344.  *
  1345.  * Function: scxferc
  1346.  *
  1347.  * Description: Handshake the p_data (DB4-0) across the bus.
  1348.  *
  1349.  *---------------------------------------------------------------------*/
  1350. #if defined(DOS)
  1351. UCHAR scxferc(USHORT p_port, UCHAR p_data)
  1352. #else
  1353. UCHAR scxferc(ULONG p_port, UCHAR p_data)
  1354. #endif
  1355. {
  1356.    UCHAR curr_data, ret_data;
  1357.    curr_data = p_data | BIT(7) | BIT(5);   /*Start with DB7 & DB5 asserted. */
  1358.    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
  1359.    curr_data &= ~BIT(7);
  1360.    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
  1361.    scwirod(p_port,BIT(7));              /*Wait for DB7 to be released. */
  1362. while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
  1363.    ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
  1364.    curr_data |= BIT(6);
  1365.    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
  1366.    curr_data &= ~BIT(5);
  1367.    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
  1368.    scwirod(p_port,BIT(5));              /*Wait for DB5 to be released. */
  1369.    curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
  1370.    curr_data |= BIT(7);
  1371.    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
  1372.    curr_data &= ~BIT(6);
  1373.    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
  1374.    scwirod(p_port,BIT(6));              /*Wait for DB6 to be released. */
  1375.    return(ret_data);
  1376. }
  1377. /*---------------------------------------------------------------------
  1378.  *
  1379.  * Function: scsendi
  1380.  *
  1381.  * Description: Transfer our Identification string to determine if we
  1382.  *              will be the dominant master.
  1383.  *
  1384.  *---------------------------------------------------------------------*/
  1385. #if defined(DOS)
  1386. UCHAR scsendi(USHORT p_port, UCHAR p_id_string[])
  1387. #else
  1388. UCHAR scsendi(ULONG p_port, UCHAR p_id_string[])
  1389. #endif
  1390. {
  1391.    UCHAR ret_data,byte_cnt,bit_cnt,defer;
  1392.    defer = FALSE;
  1393.    for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
  1394.       for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
  1395.          if (defer)
  1396.             ret_data = scxferc(p_port,00);
  1397.          else if (p_id_string[byte_cnt] & bit_cnt)
  1398.                ret_data = scxferc(p_port,02);
  1399.             else {
  1400.                ret_data = scxferc(p_port,01);
  1401.                if (ret_data & 02)
  1402.                   defer = TRUE;
  1403.                }
  1404.          if ((ret_data & 0x1C) == 0x10)
  1405.             return(0x00);  /*End of isolation stage, we won! */
  1406.          if (ret_data & 0x1C)
  1407.             return(0xFF);
  1408.          if ((defer) && (!(ret_data & 0x1F)))
  1409.             return(0x01);  /*End of isolation stage, we lost. */
  1410.          } /*bit loop */
  1411.       } /*byte loop */
  1412.    if (defer)
  1413.       return(0x01);  /*We lost */
  1414.    else
  1415.       return(0);  /*We WON! Yeeessss! */
  1416. }
  1417. /*---------------------------------------------------------------------
  1418.  *
  1419.  * Function: sciso
  1420.  *
  1421.  * Description: Transfer the Identification string.
  1422.  *
  1423.  *---------------------------------------------------------------------*/
  1424. #if defined(DOS)
  1425. UCHAR sciso(USHORT p_port, UCHAR p_id_string[])
  1426. #else
  1427. UCHAR sciso(ULONG p_port, UCHAR p_id_string[])
  1428. #endif
  1429. {
  1430.    UCHAR ret_data,the_data,byte_cnt,bit_cnt;
  1431.    the_data = 0;
  1432.    for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
  1433.       for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
  1434.          ret_data = scxferc(p_port,0);
  1435.          if (ret_data & 0xFC)
  1436.             return(0xFF);
  1437.          else {
  1438.             the_data <<= 1;
  1439.             if (ret_data & BIT(1)) {
  1440.                the_data |= 1;
  1441.                }
  1442.             }
  1443.          if ((ret_data & 0x1F) == 0)
  1444.    {
  1445. /*
  1446. if(bit_cnt != 0 || bit_cnt != 8)
  1447. {
  1448. byte_cnt = 0;
  1449. bit_cnt = 0;
  1450. scxferc(p_port, SYNC_PTRN);
  1451. scxferc(p_port, ASSIGN_ID);
  1452. continue;
  1453. }
  1454. */
  1455.             if (byte_cnt)
  1456.                return(0x00);
  1457.             else
  1458.                return(0xFF);
  1459.    }
  1460.          } /*bit loop */
  1461.       p_id_string[byte_cnt] = the_data;
  1462.       } /*byte loop */
  1463.    return(0);
  1464. }
  1465. /*---------------------------------------------------------------------
  1466.  *
  1467.  * Function: scwirod
  1468.  *
  1469.  * Description: Sample the SCSI data bus making sure the signal has been
  1470.  *              deasserted for the correct number of consecutive samples.
  1471.  *
  1472.  *---------------------------------------------------------------------*/
  1473. #if defined(DOS)
  1474. void scwirod(USHORT p_port, UCHAR p_data_bit)
  1475. #else
  1476. void scwirod(ULONG p_port, UCHAR p_data_bit)
  1477. #endif
  1478. {
  1479.    UCHAR i;
  1480.    i = 0;
  1481.    while ( i < MAX_SCSI_TAR ) {
  1482.       if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
  1483.          i = 0;
  1484.       else
  1485.          i++;
  1486.       }
  1487. }
  1488. /*---------------------------------------------------------------------
  1489.  *
  1490.  * Function: scwiros
  1491.  *
  1492.  * Description: Sample the SCSI Signal lines making sure the signal has been
  1493.  *              deasserted for the correct number of consecutive samples.
  1494.  *
  1495.  *---------------------------------------------------------------------*/
  1496. #if defined(DOS)
  1497. void scwiros(USHORT p_port, UCHAR p_data_bit)
  1498. #else
  1499. void scwiros(ULONG p_port, UCHAR p_data_bit)
  1500. #endif
  1501. {
  1502.    UCHAR i;
  1503.    i = 0;
  1504.    while ( i < MAX_SCSI_TAR ) {
  1505.       if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
  1506.          i = 0;
  1507.       else
  1508.          i++;
  1509.       }
  1510. }
  1511. /*---------------------------------------------------------------------
  1512.  *
  1513.  * Function: scvalq
  1514.  *
  1515.  * Description: Make sure we received a valid data byte.
  1516.  *
  1517.  *---------------------------------------------------------------------*/
  1518. UCHAR scvalq(UCHAR p_quintet)
  1519. {
  1520.    UCHAR count;
  1521.    for (count=1; count < 0x08; count<<=1) {
  1522.       if (!(p_quintet & count))
  1523.          p_quintet -= 0x80;
  1524.       }
  1525.    if (p_quintet & 0x18)
  1526.       return(FALSE);
  1527.    else
  1528.       return(TRUE);
  1529. }
  1530. /*---------------------------------------------------------------------
  1531.  *
  1532.  * Function: scsell
  1533.  *
  1534.  * Description: Select the specified device ID using a selection timeout
  1535.  *              less than 4ms.  If somebody responds then it is a legacy
  1536.  *              drive and this ID must be marked as such.
  1537.  *
  1538.  *---------------------------------------------------------------------*/
  1539. #if defined(DOS)
  1540. UCHAR scsell(USHORT p_port, UCHAR targ_id)
  1541. #else
  1542. UCHAR scsell(ULONG p_port, UCHAR targ_id)
  1543. #endif
  1544. {
  1545. #if defined(DOS)
  1546.    USHORT i;
  1547. #else
  1548.    ULONG i;
  1549. #endif
  1550.    WR_HARPOON(p_port+hp_page_ctrl,
  1551.       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
  1552.    ARAM_ACCESS(p_port);
  1553.    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
  1554.    WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
  1555.    for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
  1556.       WRW_HARPOON(i, (MPM_OP+ACOMMAND));
  1557.       }
  1558.    WRW_HARPOON(i, (BRH_OP+ALWAYS+    NP));
  1559.    WRW_HARPOON((p_port+hp_intstat),
  1560.        (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
  1561.    WR_HARPOON(p_port+hp_select_id, targ_id);
  1562.    WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
  1563.    WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
  1564.    WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
  1565.    while (!(RDW_HARPOON((p_port+hp_intstat)) &
  1566.     (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
  1567.    if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
  1568.          Wait(p_port, TO_250ms);
  1569.    DISABLE_AUTO(p_port);
  1570.    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
  1571.    WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
  1572.    SGRAM_ACCESS(p_port);
  1573.    if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
  1574.       WRW_HARPOON((p_port+hp_intstat),
  1575.   (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
  1576.       WR_HARPOON(p_port+hp_page_ctrl,
  1577.          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
  1578.       return(FALSE);  /*No legacy device */
  1579.       }
  1580.    else {
  1581.       while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
  1582. if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
  1583. {
  1584. WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
  1585.        ACCEPT_MSG(p_port);
  1586. }
  1587. }
  1588.       WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
  1589.       WR_HARPOON(p_port+hp_page_ctrl,
  1590.          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
  1591.       return(TRUE);  /*Found one of them oldies! */
  1592.       }
  1593. }
  1594. #if defined(DOS)
  1595. /*---------------------------------------------------------------------
  1596.  *
  1597.  * Function: scsell for DOS
  1598.  *
  1599.  * Description: Select the specified device ID using a selection timeout
  1600.  *              less than 2ms.  This was specially required to solve
  1601.  *              the problem with Plextor 12X CD-ROM drive. This drive
  1602.  *  was responding the Selection at the end of 4ms and 
  1603.  *  hanging the system.
  1604.  *
  1605.  *---------------------------------------------------------------------*/
  1606. UCHAR scsellDOS(USHORT p_port, UCHAR targ_id)
  1607. {
  1608.    USHORT i;
  1609.    WR_HARPOON(p_port+hp_page_ctrl,
  1610.       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
  1611.    ARAM_ACCESS(p_port);
  1612.    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
  1613.    WR_HARPOON(p_port+hp_seltimeout,TO_2ms);
  1614.    for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
  1615.       WRW_HARPOON(i, (MPM_OP+ACOMMAND));
  1616.       }
  1617.    WRW_HARPOON(i, (BRH_OP+ALWAYS+    NP));
  1618.    WRW_HARPOON((p_port+hp_intstat),
  1619.        (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
  1620.    WR_HARPOON(p_port+hp_select_id, targ_id);
  1621.    WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
  1622.    WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
  1623.    WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
  1624.    while (!(RDW_HARPOON((p_port+hp_intstat)) &
  1625.     (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
  1626.    if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
  1627.          Wait(p_port, TO_250ms);
  1628.    DISABLE_AUTO(p_port);
  1629.    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
  1630.    WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
  1631.    SGRAM_ACCESS(p_port);
  1632.    if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
  1633.       WRW_HARPOON((p_port+hp_intstat),
  1634.   (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
  1635.       WR_HARPOON(p_port+hp_page_ctrl,
  1636.          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
  1637.       return(FALSE);  /*No legacy device */
  1638.       }
  1639.    else {
  1640.       while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
  1641. if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
  1642. {
  1643. WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
  1644.        ACCEPT_MSG(p_port);
  1645. }
  1646. }
  1647.       WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
  1648.       WR_HARPOON(p_port+hp_page_ctrl,
  1649.          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
  1650.       return(TRUE);  /*Found one of them oldies! */
  1651.       }
  1652. }
  1653. #endif  /* DOS */
  1654. /*---------------------------------------------------------------------
  1655.  *
  1656.  * Function: scwtsel
  1657.  *
  1658.  * Description: Wait to be selected by another SCAM initiator.
  1659.  *
  1660.  *---------------------------------------------------------------------*/
  1661. #if defined(DOS)
  1662. void scwtsel(USHORT p_port)
  1663. #else
  1664. void scwtsel(ULONG p_port)
  1665. #endif
  1666. {
  1667.    while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
  1668. }
  1669. /*---------------------------------------------------------------------
  1670.  *
  1671.  * Function: inisci
  1672.  *
  1673.  * Description: Setup the data Structure with the info from the EEPROM.
  1674.  *
  1675.  *---------------------------------------------------------------------*/
  1676. #if defined(DOS)
  1677. void inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id)
  1678. #else
  1679. void inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
  1680. #endif
  1681. {
  1682.    UCHAR i,k,max_id;
  1683.    USHORT ee_data;
  1684. PNVRamInfo pCurrNvRam;
  1685. pCurrNvRam = BL_Card[p_card].pNvRamInfo;
  1686.    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
  1687.       max_id = 0x08;
  1688.    else
  1689.       max_id = 0x10;
  1690. if(pCurrNvRam){
  1691. for(i = 0; i < max_id; i++){
  1692. for(k = 0; k < 4; k++)
  1693. scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
  1694. for(k = 4; k < ID_STRING_LENGTH; k++)
  1695. scamInfo[i].id_string[k] = (UCHAR) 0x00;
  1696.       if(scamInfo[i].id_string[0] == 0x00)
  1697.           scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
  1698.       else
  1699.           scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
  1700. }
  1701. }else {
  1702.    for (i=0; i < max_id; i++)
  1703.        {
  1704.        for (k=0; k < ID_STRING_LENGTH; k+=2)
  1705.          {
  1706.           ee_data = utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
  1707.             (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
  1708.           scamInfo[i].id_string[k] = (UCHAR) ee_data;
  1709.          ee_data >>= 8;
  1710.           scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
  1711.           }
  1712.       if ((scamInfo[i].id_string[0] == 0x00) ||
  1713.            (scamInfo[i].id_string[0] == 0xFF))
  1714.           scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
  1715.       else
  1716.           scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
  1717.        }
  1718. }
  1719. for(k = 0; k < ID_STRING_LENGTH; k++)
  1720. scamInfo[p_our_id].id_string[k] = scamHAString[k];
  1721. }
  1722. /*---------------------------------------------------------------------
  1723.  *
  1724.  * Function: scmachid
  1725.  *
  1726.  * Description: Match the Device ID string with our values stored in
  1727.  *              the EEPROM.
  1728.  *
  1729.  *---------------------------------------------------------------------*/
  1730. UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[])
  1731. {
  1732.    UCHAR i,k,match;
  1733.    for (i=0; i < MAX_SCSI_TAR; i++) {
  1734. #if !defined(SCAM_LEV_2)
  1735.       if (scamInfo[i].state == ID_UNASSIGNED)
  1736.          {
  1737. #endif
  1738.          match = TRUE;
  1739.          for (k=0; k < ID_STRING_LENGTH; k++)
  1740.             {
  1741.             if (p_id_string[k] != scamInfo[i].id_string[k])
  1742.                match = FALSE;
  1743.             }
  1744.          if (match)
  1745.             {
  1746.             scamInfo[i].state = ID_ASSIGNED;
  1747.             return(i);
  1748.             }
  1749. #if !defined(SCAM_LEV_2)
  1750.          }
  1751. #endif
  1752.       }
  1753.    if (p_id_string[0] & BIT(5))
  1754.       i = 8;
  1755.    else
  1756.       i = MAX_SCSI_TAR;
  1757.    if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
  1758.       match = p_id_string[1] & (UCHAR) 0x1F;
  1759.    else
  1760.       match = 7;
  1761.    while (i > 0)
  1762.       {
  1763.       i--;
  1764.       if (scamInfo[match].state == ID_UNUSED)
  1765.          {
  1766.          for (k=0; k < ID_STRING_LENGTH; k++)
  1767.             {
  1768.             scamInfo[match].id_string[k] = p_id_string[k];
  1769.             }
  1770.          scamInfo[match].state = ID_ASSIGNED;
  1771. if(BL_Card[p_card].pNvRamInfo == NULL)
  1772.          BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
  1773.          return(match);
  1774.          }
  1775.       match--;
  1776.       if (match == 0xFF)
  1777. {
  1778.          if (p_id_string[0] & BIT(5))
  1779.             match = 7;
  1780.          else
  1781.             match = MAX_SCSI_TAR-1;
  1782. }
  1783.       }
  1784.    if (p_id_string[0] & BIT(7))
  1785.       {
  1786.       return(CLR_PRIORITY);
  1787.       }
  1788.    if (p_id_string[0] & BIT(5))
  1789.       i = 8;
  1790.    else
  1791.       i = MAX_SCSI_TAR;
  1792.    if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
  1793.       match = p_id_string[1] & (UCHAR) 0x1F;
  1794.    else
  1795.       match = 7;
  1796.    while (i > 0)
  1797.       {
  1798.       i--;
  1799.       if (scamInfo[match].state == ID_UNASSIGNED)
  1800.          {
  1801.          for (k=0; k < ID_STRING_LENGTH; k++)
  1802.             {
  1803.             scamInfo[match].id_string[k] = p_id_string[k];
  1804.             }
  1805.          scamInfo[match].id_string[0] |= BIT(7);
  1806.          scamInfo[match].state = ID_ASSIGNED;
  1807. if(BL_Card[p_card].pNvRamInfo == NULL)
  1808.          BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
  1809.          return(match);
  1810.          }
  1811.       match--;
  1812.       if (match == 0xFF)
  1813. {
  1814.          if (p_id_string[0] & BIT(5))
  1815.             match = 7;
  1816.          else
  1817.             match = MAX_SCSI_TAR-1;
  1818. }
  1819.       }
  1820.    return(NO_ID_AVAIL);
  1821. }
  1822. /*---------------------------------------------------------------------
  1823.  *
  1824.  * Function: scsavdi
  1825.  *
  1826.  * Description: Save off the device SCAM ID strings.
  1827.  *
  1828.  *---------------------------------------------------------------------*/
  1829. #if defined(DOS)
  1830. void scsavdi(UCHAR p_card, USHORT p_port)
  1831. #else
  1832. void scsavdi(UCHAR p_card, ULONG p_port)
  1833. #endif
  1834. {
  1835.    UCHAR i,k,max_id;
  1836.    USHORT ee_data,sum_data;
  1837.    sum_data = 0x0000;
  1838.    for (i = 1; i < EE_SCAMBASE/2; i++)
  1839.       {
  1840.       sum_data += utilEERead(p_port, i);
  1841.       }
  1842.    utilEEWriteOnOff(p_port,1);   /* Enable write access to the EEPROM */
  1843.    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
  1844.       max_id = 0x08;
  1845.    else
  1846.       max_id = 0x10;
  1847.    for (i=0; i < max_id; i++)
  1848.       {
  1849.       for (k=0; k < ID_STRING_LENGTH; k+=2)
  1850.          {
  1851.          ee_data = scamInfo[i].id_string[k+1];
  1852.          ee_data <<= 8;
  1853.          ee_data |= scamInfo[i].id_string[k];
  1854.          sum_data += ee_data;
  1855.          utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
  1856.             (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
  1857.          }
  1858.       }
  1859.    utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
  1860.    utilEEWriteOnOff(p_port,0);   /* Turn off write access */
  1861. }
  1862. #ident "$Id: diagnose.c 1.10 1997/06/10 16:51:47 mohan Exp $"
  1863. /*----------------------------------------------------------------------
  1864.  *
  1865.  *
  1866.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  1867.  *
  1868.  *   This file is available under both the GNU General Public License
  1869.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  1870.  *
  1871.  *   $Workfile:   diagnose.c  $
  1872.  *
  1873.  *   Description:  Diagnostic funtions for testing the integrity of
  1874.  *                 the HARPOON.
  1875.  *
  1876.  *   $Date: 1997/06/10 16:51:47 $
  1877.  *
  1878.  *   $Revision: 1.10 $
  1879.  *
  1880.  *----------------------------------------------------------------------*/
  1881. /*#include <globals.h>*/
  1882. #if (FW_TYPE==_UCB_MGR_)
  1883. /*#include <budi.h>*/
  1884. #endif
  1885. /*#include <sccbmgr.h>*/
  1886. /*#include <blx30.h>*/
  1887. /*#include <target.h>*/
  1888. /*#include <eeprom.h>*/
  1889. /*#include <harpoon.h>*/
  1890. /*---------------------------------------------------------------------
  1891.  *
  1892.  * Function: XbowInit
  1893.  *
  1894.  * Description: Setup the Xbow for normal operation.
  1895.  *
  1896.  *---------------------------------------------------------------------*/
  1897. #if defined(DOS)
  1898. void XbowInit(USHORT port, UCHAR ScamFlg)
  1899. #else
  1900. void XbowInit(ULONG port, UCHAR ScamFlg)
  1901. #endif
  1902. {
  1903. UCHAR i;
  1904. i = RD_HARPOON(port+hp_page_ctrl);
  1905. WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
  1906.    WR_HARPOON(port+hp_scsireset,0x00);
  1907.    WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
  1908.    WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | 
  1909.  FIFO_CLR));
  1910.    WR_HARPOON(port+hp_scsireset,SCSI_INI);
  1911.    WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
  1912.    WR_HARPOON(port+hp_scsisig,0x00);         /*  Clear any signals we might */
  1913.    WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
  1914.    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
  1915. #if defined(SCAM_LEV_2)
  1916.    default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
  1917.     BUS_FREE | XFER_CNT_0 | AUTO_INT;
  1918.    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
  1919. default_intena |= SCAM_SEL;
  1920. #else
  1921.    default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
  1922.     BUS_FREE | XFER_CNT_0 | AUTO_INT;
  1923. #endif
  1924.    WRW_HARPOON((port+hp_intena), default_intena);
  1925.    WR_HARPOON(port+hp_seltimeout,TO_290ms);
  1926.    /* Turn on SCSI_MODE8 for narrow cards to fix the
  1927.       strapping issue with the DUAL CHANNEL card */
  1928.    if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
  1929.       WR_HARPOON(port+hp_addstat,SCSI_MODE8);
  1930. #if defined(NO_BIOS_OPTION)
  1931.    WR_HARPOON(port+hp_synctarg_0,NARROW_SCSI);
  1932.    WR_HARPOON(port+hp_synctarg_1,NARROW_SCSI);
  1933.    WR_HARPOON(port+hp_synctarg_2,NARROW_SCSI);
  1934.    WR_HARPOON(port+hp_synctarg_3,NARROW_SCSI);
  1935.    WR_HARPOON(port+hp_synctarg_4,NARROW_SCSI);
  1936.    WR_HARPOON(port+hp_synctarg_5,NARROW_SCSI);
  1937.    WR_HARPOON(port+hp_synctarg_6,NARROW_SCSI);
  1938.    WR_HARPOON(port+hp_synctarg_7,NARROW_SCSI);
  1939.    WR_HARPOON(port+hp_synctarg_8,NARROW_SCSI);
  1940.    WR_HARPOON(port+hp_synctarg_9,NARROW_SCSI);
  1941.    WR_HARPOON(port+hp_synctarg_10,NARROW_SCSI);
  1942.    WR_HARPOON(port+hp_synctarg_11,NARROW_SCSI);
  1943.    WR_HARPOON(port+hp_synctarg_12,NARROW_SCSI);
  1944.    WR_HARPOON(port+hp_synctarg_13,NARROW_SCSI);
  1945.    WR_HARPOON(port+hp_synctarg_14,NARROW_SCSI);
  1946.    WR_HARPOON(port+hp_synctarg_15,NARROW_SCSI);
  1947. #endif
  1948. WR_HARPOON(port+hp_page_ctrl, i);
  1949. }
  1950. /*---------------------------------------------------------------------
  1951.  *
  1952.  * Function: BusMasterInit
  1953.  *
  1954.  * Description: Initialize the BusMaster for normal operations.
  1955.  *
  1956.  *---------------------------------------------------------------------*/
  1957. #if defined(DOS)
  1958. void BusMasterInit(USHORT p_port)
  1959. #else
  1960. void BusMasterInit(ULONG p_port)
  1961. #endif
  1962. {
  1963.    WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
  1964.    WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
  1965.    WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
  1966.    WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
  1967.    WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
  1968. #if defined(NT)
  1969.    WR_HARPOON(p_port+hp_pci_cmd_cfg, (RD_HARPOON(p_port+hp_pci_cmd_cfg)
  1970.       & ~MEM_SPACE_ENA));
  1971. #endif
  1972.    RD_HARPOON(p_port+hp_int_status);        /*Clear interrupts. */
  1973.    WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
  1974.    WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
  1975.       ~SCATTER_EN));
  1976. }
  1977. /*---------------------------------------------------------------------
  1978.  *
  1979.  * Function: DiagXbow
  1980.  *
  1981.  * Description: Test Xbow integrity.  Non-zero return indicates an error.
  1982.  *
  1983.  *---------------------------------------------------------------------*/
  1984. #if defined(DOS)
  1985. int DiagXbow(USHORT port)
  1986. #else
  1987. int DiagXbow(ULONG port)
  1988. #endif
  1989. {
  1990.    unsigned char fifo_cnt,loop_cnt;
  1991.    unsigned char fifodata[5];
  1992.    fifodata[0] = 0x00;
  1993.    fifodata[1] = 0xFF;
  1994.    fifodata[2] = 0x55;
  1995.    fifodata[3] = 0xAA;
  1996.    fifodata[4] = 0x00;
  1997.    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
  1998.    WRW_HARPOON((port+hp_intena), 0x0000);
  1999.    WR_HARPOON(port+hp_seltimeout,TO_5ms);
  2000.    WR_HARPOON(port+hp_portctrl_0,START_TO);
  2001.    for(fifodata[4] = 0x01; fifodata[4] != (UCHAR) 0; fifodata[4] = fifodata[4] << 1) {
  2002.       WR_HARPOON(port+hp_selfid_0,fifodata[4]);
  2003.       WR_HARPOON(port+hp_selfid_1,fifodata[4]);
  2004.       if ((RD_HARPOON(port+hp_selfid_0) != fifodata[4]) ||
  2005.           (RD_HARPOON(port+hp_selfid_1) != fifodata[4]))
  2006.          return(1);
  2007.       }
  2008.    for(loop_cnt = 0; loop_cnt < 4; loop_cnt++) {
  2009.       WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | HOST_WRT | START_TO));
  2010.       for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) {
  2011.          WR_HARPOON(port+hp_fifodata_0, fifodata[loop_cnt]);
  2012.          }
  2013.       if (!(RD_HARPOON(port+hp_xferstat) & FIFO_FULL))
  2014.          return(1);
  2015.       WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | START_TO));
  2016.       for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) {
  2017.          if (RD_HARPOON(port+hp_fifodata_0) != fifodata[loop_cnt])
  2018.             return(1);
  2019.          }
  2020.       if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
  2021.          return(1);
  2022.       }
  2023.    while(!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
  2024.    WR_HARPOON(port+hp_seltimeout,TO_290ms);
  2025.    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
  2026.    WRW_HARPOON((port+hp_intena), default_intena);
  2027.    return(0);
  2028. }
  2029. /*---------------------------------------------------------------------
  2030.  *
  2031.  * Function: DiagBusMaster
  2032.  *
  2033.  * Description: Test BusMaster integrity.  Non-zero return indicates an
  2034.  *              error.
  2035.  *
  2036.  *---------------------------------------------------------------------*/
  2037. #if defined(DOS)
  2038. int DiagBusMaster(USHORT port)
  2039. #else
  2040. int DiagBusMaster(ULONG port)
  2041. #endif
  2042. {
  2043.    UCHAR testdata;
  2044.    for(testdata = (UCHAR) 1; testdata != (UCHAR)0; testdata = testdata << 1) {
  2045.       WR_HARPOON(port+hp_xfer_cnt_lo,testdata);
  2046.       WR_HARPOON(port+hp_xfer_cnt_mi,testdata);
  2047.       WR_HARPOON(port+hp_xfer_cnt_hi,testdata);
  2048.       WR_HARPOON(port+hp_host_addr_lo,testdata);
  2049.       WR_HARPOON(port+hp_host_addr_lmi,testdata);
  2050.       WR_HARPOON(port+hp_host_addr_hmi,testdata);
  2051.       WR_HARPOON(port+hp_host_addr_hi,testdata);
  2052.       if ((RD_HARPOON(port+hp_xfer_cnt_lo) != testdata)   ||
  2053.           (RD_HARPOON(port+hp_xfer_cnt_mi) != testdata)   ||
  2054.           (RD_HARPOON(port+hp_xfer_cnt_hi) != testdata)   ||
  2055.           (RD_HARPOON(port+hp_host_addr_lo) != testdata)  ||
  2056.           (RD_HARPOON(port+hp_host_addr_lmi) != testdata) ||
  2057.           (RD_HARPOON(port+hp_host_addr_hmi) != testdata) ||
  2058.           (RD_HARPOON(port+hp_host_addr_hi) != testdata))
  2059.          return(1);
  2060.       }
  2061.    RD_HARPOON(port+hp_int_status);        /*Clear interrupts. */
  2062.    return(0);
  2063. }
  2064. /*---------------------------------------------------------------------
  2065.  *
  2066.  * Function: DiagEEPROM
  2067.  *
  2068.  * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
  2069.  *              neccessary.
  2070.  *
  2071.  *---------------------------------------------------------------------*/
  2072. #if defined(DOS)
  2073. void DiagEEPROM(USHORT p_port)
  2074. #else
  2075. void DiagEEPROM(ULONG p_port)
  2076. #endif
  2077. {
  2078.    USHORT index,temp,max_wd_cnt;
  2079.    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
  2080.       max_wd_cnt = EEPROM_WD_CNT;
  2081.    else
  2082.       max_wd_cnt = EEPROM_WD_CNT * 2;
  2083.    temp = utilEERead(p_port, FW_SIGNATURE/2);
  2084.    if (temp == 0x4641) {
  2085.       for (index = 2; index < max_wd_cnt; index++) {
  2086.          temp += utilEERead(p_port, index);
  2087.          }
  2088.       if (temp == utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
  2089.          return;          /*EEPROM is Okay so return now! */
  2090.          }
  2091.       }
  2092.    utilEEWriteOnOff(p_port,(UCHAR)1);
  2093.    for (index = 0; index < max_wd_cnt; index++) {
  2094.       utilEEWrite(p_port, 0x0000, index);
  2095.       }
  2096.    temp = 0;
  2097.    utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
  2098.    temp += 0x4641;
  2099.    utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
  2100.    temp += 0x3920;
  2101.    utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
  2102.    temp += 0x3033;
  2103.    utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
  2104.    temp += 0x2020;
  2105.    utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
  2106.    temp += 0x70D3;
  2107.    utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
  2108.    temp += 0x0010;
  2109.    utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
  2110.    temp += 0x0003;
  2111.    utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
  2112.    temp += 0x0007;
  2113.    utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
  2114.    temp += 0x0000;
  2115.    utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
  2116.    temp += 0x0000;
  2117.    utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
  2118.    temp += 0x0000;
  2119.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
  2120.    temp += 0x4242;
  2121.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
  2122.    temp += 0x4242;
  2123.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
  2124.    temp += 0x4242;
  2125.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
  2126.    temp += 0x4242;
  2127.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
  2128.    temp += 0x4242;
  2129.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
  2130.    temp += 0x4242;
  2131.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
  2132.    temp += 0x4242;
  2133.    utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
  2134.    temp += 0x4242;
  2135.    utilEEWrite(p_port, 0x6C46, 64/2);  /*PRODUCT ID */
  2136.    temp += 0x6C46;
  2137.    utilEEWrite(p_port, 0x7361, 66/2);  /* FlashPoint LT   */
  2138.    temp += 0x7361;
  2139.    utilEEWrite(p_port, 0x5068, 68/2);
  2140.    temp += 0x5068;
  2141.    utilEEWrite(p_port, 0x696F, 70/2);
  2142.    temp += 0x696F;
  2143.    utilEEWrite(p_port, 0x746E, 72/2);
  2144.    temp += 0x746E;
  2145.    utilEEWrite(p_port, 0x4C20, 74/2);
  2146.    temp += 0x4C20;
  2147.    utilEEWrite(p_port, 0x2054, 76/2);
  2148.    temp += 0x2054;
  2149.    utilEEWrite(p_port, 0x2020, 78/2);
  2150.    temp += 0x2020;
  2151.    index = ((EE_SCAMBASE/2)+(7*16));
  2152.    utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
  2153.    temp += (0x0700+TYPE_CODE0);
  2154.    index++;
  2155.    utilEEWrite(p_port, 0x5542, index);            /*Vendor ID code */
  2156.    temp += 0x5542;                                /* BUSLOGIC      */
  2157.    index++;
  2158.    utilEEWrite(p_port, 0x4C53, index);
  2159.    temp += 0x4C53;
  2160.    index++;
  2161.    utilEEWrite(p_port, 0x474F, index);
  2162.    temp += 0x474F;
  2163.    index++;
  2164.    utilEEWrite(p_port, 0x4349, index);
  2165.    temp += 0x4349;
  2166.    index++;
  2167.    utilEEWrite(p_port, 0x5442, index);            /*Vendor unique code */
  2168.    temp += 0x5442;                         /* BT- 930           */
  2169.    index++;
  2170.    utilEEWrite(p_port, 0x202D, index);
  2171.    temp += 0x202D;
  2172.    index++;
  2173.    utilEEWrite(p_port, 0x3339, index);
  2174.    temp += 0x3339;
  2175.    index++;                                 /*Serial #          */
  2176.    utilEEWrite(p_port, 0x2030, index);             /* 01234567         */
  2177.    temp += 0x2030;
  2178.    index++;
  2179.    utilEEWrite(p_port, 0x5453, index);
  2180.    temp += 0x5453;
  2181.    index++;
  2182.    utilEEWrite(p_port, 0x5645, index);
  2183.    temp += 0x5645;
  2184.    index++;
  2185.    utilEEWrite(p_port, 0x2045, index);
  2186.    temp += 0x2045;
  2187.    index++;
  2188.    utilEEWrite(p_port, 0x202F, index);
  2189.    temp += 0x202F;
  2190.    index++;
  2191.    utilEEWrite(p_port, 0x4F4A, index);
  2192.    temp += 0x4F4A;
  2193.    index++;
  2194.    utilEEWrite(p_port, 0x204E, index);
  2195.    temp += 0x204E;
  2196.    index++;
  2197.    utilEEWrite(p_port, 0x3539, index);
  2198.    temp += 0x3539;
  2199.    utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
  2200.    utilEEWriteOnOff(p_port,(UCHAR)0);
  2201. }
  2202. #ident "$Id: utility.c 1.23 1997/06/10 16:55:06 mohan Exp $"
  2203. /*----------------------------------------------------------------------
  2204.  *
  2205.  *
  2206.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  2207.  *
  2208.  *   This file is available under both the GNU General Public License
  2209.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  2210.  *
  2211.  *   $Workfile:   utility.c  $
  2212.  *
  2213.  *   Description:  Utility functions relating to queueing and EEPROM
  2214.  *                 manipulation and any other garbage functions.
  2215.  *
  2216.  *   $Date: 1997/06/10 16:55:06 $
  2217.  *
  2218.  *   $Revision: 1.23 $
  2219.  *
  2220.  *----------------------------------------------------------------------*/
  2221. /*#include <globals.h>*/
  2222. #if (FW_TYPE==_UCB_MGR_)
  2223. /*#include <budi.h>*/
  2224. #endif
  2225. /*#include <sccbmgr.h>*/
  2226. /*#include <blx30.h>*/
  2227. /*#include <target.h>*/
  2228. /*#include <scsi2.h>*/
  2229. /*#include <harpoon.h>*/
  2230. /*
  2231. extern SCCBCARD BL_Card[MAX_CARDS];
  2232. extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  2233. extern unsigned int SccbGlobalFlags;
  2234. */
  2235. /*---------------------------------------------------------------------
  2236.  *
  2237.  * Function: Queue Search Select
  2238.  *
  2239.  * Description: Try to find a new command to execute.
  2240.  *
  2241.  *---------------------------------------------------------------------*/
  2242. void queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
  2243. {
  2244.    UCHAR scan_ptr, lun;
  2245.    PSCCBMgr_tar_info currTar_Info;
  2246. PSCCB pOldSccb;
  2247.    scan_ptr = pCurrCard->scanIndex;
  2248. do 
  2249. {
  2250. currTar_Info = &sccbMgrTbl[p_card][scan_ptr];
  2251. if((pCurrCard->globalFlags & F_CONLUN_IO) && 
  2252. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  2253. {
  2254. if (currTar_Info->TarSelQ_Cnt != 0)
  2255. {
  2256. scan_ptr++;
  2257. if (scan_ptr == MAX_SCSI_TAR)
  2258. scan_ptr = 0;
  2259. for(lun=0; lun < MAX_LUN; lun++)
  2260. {
  2261. if(currTar_Info->TarLUNBusy[lun] == FALSE)
  2262. {
  2263. pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
  2264. pOldSccb = NULL;
  2265. while((pCurrCard->currentSCCB != NULL) &&
  2266.  (lun != pCurrCard->currentSCCB->Lun))
  2267. {
  2268. pOldSccb = pCurrCard->currentSCCB;
  2269. pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
  2270. Sccb_forwardlink;
  2271. }
  2272. if(pCurrCard->currentSCCB == NULL)
  2273. continue;
  2274. if(pOldSccb != NULL)
  2275. {
  2276. pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
  2277. Sccb_forwardlink;
  2278. pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
  2279. Sccb_backlink;
  2280. currTar_Info->TarSelQ_Cnt--;
  2281. }
  2282. else
  2283. {
  2284. currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
  2285. if (currTar_Info->TarSelQ_Head == NULL)
  2286. {
  2287. currTar_Info->TarSelQ_Tail = NULL;
  2288. currTar_Info->TarSelQ_Cnt = 0;
  2289. }
  2290. else
  2291. {
  2292. currTar_Info->TarSelQ_Cnt--;
  2293. currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
  2294. }
  2295. }
  2296. pCurrCard->scanIndex = scan_ptr;
  2297. pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
  2298. break;
  2299. }
  2300. }
  2301. }
  2302. else 
  2303. {
  2304. scan_ptr++;
  2305. if (scan_ptr == MAX_SCSI_TAR) {
  2306. scan_ptr = 0;
  2307. }
  2308. }
  2309. }
  2310. else
  2311. {
  2312. if ((currTar_Info->TarSelQ_Cnt != 0) &&
  2313. (currTar_Info->TarLUNBusy[0] == FALSE))
  2314. {
  2315. pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
  2316. currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
  2317. if (currTar_Info->TarSelQ_Head == NULL)
  2318. {
  2319. currTar_Info->TarSelQ_Tail = NULL;
  2320. currTar_Info->TarSelQ_Cnt = 0;
  2321. }
  2322. else
  2323. {
  2324. currTar_Info->TarSelQ_Cnt--;
  2325. currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
  2326. }
  2327. scan_ptr++;
  2328. if (scan_ptr == MAX_SCSI_TAR)
  2329. scan_ptr = 0;
  2330. pCurrCard->scanIndex = scan_ptr;
  2331. pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
  2332. break;
  2333. }
  2334. else 
  2335. {
  2336. scan_ptr++;
  2337. if (scan_ptr == MAX_SCSI_TAR) 
  2338. {
  2339. scan_ptr = 0;
  2340. }
  2341. }
  2342. }
  2343. } while (scan_ptr != pCurrCard->scanIndex);
  2344. }
  2345. /*---------------------------------------------------------------------
  2346.  *
  2347.  * Function: Queue Select Fail
  2348.  *
  2349.  * Description: Add the current SCCB to the head of the Queue.
  2350.  *
  2351.  *---------------------------------------------------------------------*/
  2352. void queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
  2353. {
  2354.    UCHAR thisTarg;
  2355.    PSCCBMgr_tar_info currTar_Info;
  2356.    if (pCurrCard->currentSCCB != NULL)
  2357.   {
  2358.   thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
  2359.       currTar_Info = &sccbMgrTbl[p_card][thisTarg];
  2360.       pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
  2361.       pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
  2362.   if (currTar_Info->TarSelQ_Cnt == 0)
  2363.  {
  2364.  currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
  2365.  }
  2366.   else
  2367.  {
  2368.  currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
  2369.  }
  2370.   currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
  2371.   pCurrCard->currentSCCB = NULL;
  2372.   currTar_Info->TarSelQ_Cnt++;
  2373.   }
  2374. }
  2375. /*---------------------------------------------------------------------
  2376.  *
  2377.  * Function: Queue Command Complete
  2378.  *
  2379.  * Description: Call the callback function with the current SCCB.
  2380.  *
  2381.  *---------------------------------------------------------------------*/
  2382. void queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb, UCHAR p_card)
  2383. {
  2384. #if (FW_TYPE==_UCB_MGR_)
  2385.    u08bits SCSIcmd;
  2386.    CALL_BK_FN callback;
  2387.    PSCCBMgr_tar_info currTar_Info;
  2388.    PUCB p_ucb;
  2389.    p_ucb=p_sccb->Sccb_ucb_ptr;
  2390.    SCSIcmd = p_sccb->Cdb[0];
  2391.    if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED))
  2392.    {
  2393.       if ((p_ucb->UCB_opcode & OPC_CHK_UNDER_OVER_RUN)                     &&
  2394.          (p_sccb->HostStatus == SCCB_COMPLETE)                             &&
  2395.          (p_sccb->TargetStatus != SSCHECK))
  2396.          if ((SCSIcmd == SCSI_READ)             ||
  2397.              (SCSIcmd == SCSI_WRITE)            ||
  2398.              (SCSIcmd == SCSI_READ_EXTENDED)    ||
  2399.              (SCSIcmd == SCSI_WRITE_EXTENDED)   ||
  2400.              (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
  2401.              (SCSIcmd == SCSI_START_STOP_UNIT)  ||
  2402.              (pCurrCard->globalFlags & F_NO_FILTER)
  2403.             )
  2404.                p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
  2405.    }
  2406.    p_ucb->UCB_status=SCCB_SUCCESS;
  2407.    if ((p_ucb->UCB_hbastat=p_sccb->HostStatus) || (p_ucb->UCB_scsistat=p_sccb->TargetStatus))
  2408.    {
  2409.       p_ucb->UCB_status=SCCB_ERROR;
  2410.    }
  2411.    if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
  2412.       (p_sccb->OperationCode == RESIDUAL_COMMAND))
  2413.    {
  2414.          utilUpdateResidual(p_sccb);
  2415.          p_ucb->UCB_datalen=p_sccb->DataLength;
  2416.    }
  2417.    pCurrCard->cmdCounter--;
  2418.    if (!pCurrCard->cmdCounter)
  2419.    {
  2420.       if (pCurrCard->globalFlags & F_GREEN_PC)
  2421.       {
  2422.          WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
  2423.          WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
  2424.       }
  2425.       WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
  2426.       (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
  2427.    }
  2428. if(pCurrCard->discQCount != 0)
  2429. {
  2430.       currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
  2431. if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
  2432. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  2433. {
  2434. pCurrCard->discQCount--;
  2435. pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
  2436. }
  2437. else
  2438. {
  2439. if(p_sccb->Sccb_tag)
  2440. {
  2441. pCurrCard->discQCount--;
  2442. pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
  2443. }else
  2444. {
  2445. pCurrCard->discQCount--;
  2446. pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
  2447. }
  2448. }
  2449. }
  2450.    callback = (CALL_BK_FN)p_ucb->UCB_callback;
  2451.    callback(p_ucb);
  2452.    pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
  2453.    pCurrCard->currentSCCB = NULL;
  2454. }
  2455. #else
  2456.    UCHAR i, SCSIcmd;
  2457.    CALL_BK_FN callback;
  2458.    PSCCBMgr_tar_info currTar_Info;
  2459.    SCSIcmd = p_sccb->Cdb[0];
  2460.    if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
  2461.   if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
  2462.  (p_sccb->HostStatus == SCCB_COMPLETE)                             &&
  2463.  (p_sccb->TargetStatus != SSCHECK))
  2464.  if ((SCSIcmd == SCSI_READ)             ||
  2465.  (SCSIcmd == SCSI_WRITE)            ||
  2466.  (SCSIcmd == SCSI_READ_EXTENDED)    ||
  2467.  (SCSIcmd == SCSI_WRITE_EXTENDED)   ||
  2468.  (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
  2469.  (SCSIcmd == SCSI_START_STOP_UNIT)  ||
  2470.  (pCurrCard->globalFlags & F_NO_FILTER)
  2471. )
  2472.    p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
  2473.   }
  2474. if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
  2475. {
  2476.    if (p_sccb->HostStatus || p_sccb->TargetStatus)
  2477.   p_sccb->SccbStatus = SCCB_ERROR;
  2478.    else
  2479.   p_sccb->SccbStatus = SCCB_SUCCESS;
  2480. }
  2481.    if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
  2482.   p_sccb->CdbLength = p_sccb->Save_CdbLen;
  2483.   for (i=0; i < 6; i++) {
  2484.  p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
  2485.  }
  2486.   }
  2487.    if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
  2488.   (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
  2489.  utilUpdateResidual(p_sccb);
  2490.  }
  2491.    pCurrCard->cmdCounter--;
  2492.    if (!pCurrCard->cmdCounter) {
  2493.   if (pCurrCard->globalFlags & F_GREEN_PC) {
  2494.  WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
  2495.  WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
  2496.  }
  2497.   WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
  2498.   (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
  2499.   }
  2500. if(pCurrCard->discQCount != 0)
  2501. {
  2502.       currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
  2503. if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
  2504. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  2505. {
  2506. pCurrCard->discQCount--;
  2507. pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
  2508. }
  2509. else
  2510. {
  2511. if(p_sccb->Sccb_tag)
  2512. {
  2513. pCurrCard->discQCount--;
  2514. pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
  2515. }else
  2516. {
  2517. pCurrCard->discQCount--;
  2518. pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
  2519. }
  2520. }
  2521. }
  2522. callback = (CALL_BK_FN)p_sccb->SccbCallback;
  2523.    callback(p_sccb);
  2524.    pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
  2525.    pCurrCard->currentSCCB = NULL;
  2526. }
  2527. #endif /* ( if FW_TYPE==...) */
  2528. /*---------------------------------------------------------------------
  2529.  *
  2530.  * Function: Queue Disconnect
  2531.  *
  2532.  * Description: Add SCCB to our disconnect array.
  2533.  *
  2534.  *---------------------------------------------------------------------*/
  2535. void queueDisconnect(PSCCB p_sccb, UCHAR p_card)
  2536. {
  2537.    PSCCBMgr_tar_info currTar_Info;
  2538. currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
  2539. if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  2540. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  2541. {
  2542. BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
  2543. }
  2544. else
  2545. {
  2546. if (p_sccb->Sccb_tag)
  2547. {
  2548. BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
  2549. sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = FALSE;
  2550. sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
  2551. }else
  2552. {
  2553. BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
  2554. }
  2555. }
  2556. BL_Card[p_card].currentSCCB = NULL;
  2557. }
  2558. /*---------------------------------------------------------------------
  2559.  *
  2560.  * Function: Queue Flush SCCB
  2561.  *
  2562.  * Description: Flush all SCCB's back to the host driver for this target.
  2563.  *
  2564.  *---------------------------------------------------------------------*/
  2565. void  queueFlushSccb(UCHAR p_card, UCHAR error_code)
  2566. {
  2567.    UCHAR qtag,thisTarg;
  2568.    PSCCB currSCCB;
  2569.    PSCCBMgr_tar_info currTar_Info;
  2570.    currSCCB = BL_Card[p_card].currentSCCB;
  2571. if(currSCCB != NULL)
  2572. {
  2573.    thisTarg = (UCHAR)currSCCB->TargID;
  2574.     currTar_Info = &sccbMgrTbl[p_card][thisTarg];
  2575.    for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
  2576.   if (BL_Card[p_card].discQ_Tbl[qtag] && 
  2577. (BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
  2578.  {
  2579.  BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
  2580.  queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card);
  2581.  BL_Card[p_card].discQ_Tbl[qtag] = NULL;
  2582.  currTar_Info->TarTagQ_Cnt--;
  2583.  }
  2584.   }
  2585. }
  2586. }
  2587. /*---------------------------------------------------------------------
  2588.  *
  2589.  * Function: Queue Flush Target SCCB
  2590.  *
  2591.  * Description: Flush all SCCB's back to the host driver for this target.
  2592.  *
  2593.  *---------------------------------------------------------------------*/
  2594. void  queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code)
  2595. {
  2596.    UCHAR qtag;
  2597.    PSCCBMgr_tar_info currTar_Info;
  2598.    currTar_Info = &sccbMgrTbl[p_card][thisTarg];
  2599.    for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
  2600.   if (BL_Card[p_card].discQ_Tbl[qtag] && 
  2601. (BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
  2602.  {
  2603.  BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
  2604.  queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card);
  2605.  BL_Card[p_card].discQ_Tbl[qtag] = NULL;
  2606.  currTar_Info->TarTagQ_Cnt--;
  2607.  }
  2608.   }
  2609. }
  2610. void queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
  2611. {
  2612.    PSCCBMgr_tar_info currTar_Info;
  2613.    currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID];
  2614.    p_SCCB->Sccb_forwardlink = NULL;
  2615.    p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
  2616.    if (currTar_Info->TarSelQ_Cnt == 0) {
  2617.   currTar_Info->TarSelQ_Head = p_SCCB;
  2618.   }
  2619.    else {
  2620.   currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
  2621.   }
  2622.    currTar_Info->TarSelQ_Tail = p_SCCB;
  2623.    currTar_Info->TarSelQ_Cnt++;
  2624. }
  2625. /*---------------------------------------------------------------------
  2626.  *
  2627.  * Function: Queue Find SCCB
  2628.  *
  2629.  * Description: Search the target select Queue for this SCCB, and
  2630.  *              remove it if found.
  2631.  *
  2632.  *---------------------------------------------------------------------*/
  2633. UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
  2634. {
  2635.    PSCCB q_ptr;
  2636.    PSCCBMgr_tar_info currTar_Info;
  2637.    currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID];
  2638.    q_ptr = currTar_Info->TarSelQ_Head;
  2639.    while(q_ptr != NULL) {
  2640.   if (q_ptr == p_SCCB) {
  2641.  if (currTar_Info->TarSelQ_Head == q_ptr) {
  2642. currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
  2643. }
  2644.  if (currTar_Info->TarSelQ_Tail == q_ptr) {
  2645. currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
  2646. }
  2647.  if (q_ptr->Sccb_forwardlink != NULL) {
  2648. q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
  2649. }
  2650.  if (q_ptr->Sccb_backlink != NULL) {
  2651. q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
  2652. }
  2653.  currTar_Info->TarSelQ_Cnt--;
  2654.  return(TRUE);
  2655.  }
  2656.   else {
  2657.  q_ptr = q_ptr->Sccb_forwardlink;
  2658.  }
  2659.   }
  2660.    return(FALSE);
  2661. }
  2662. /*---------------------------------------------------------------------
  2663.  *
  2664.  * Function: Utility Update Residual Count
  2665.  *
  2666.  * Description: Update the XferCnt to the remaining byte count.
  2667.  *              If we transferred all the data then just write zero.
  2668.  *              If Non-SG transfer then report Total Cnt - Actual Transfer
  2669.  *              Cnt.  For SG transfers add the count fields of all
  2670.  *              remaining SG elements, as well as any partial remaining
  2671.  *              element.
  2672.  *
  2673.  *---------------------------------------------------------------------*/
  2674. void  utilUpdateResidual(PSCCB p_SCCB)
  2675. {
  2676.    ULONG partial_cnt;
  2677.    UINT  sg_index;
  2678. #if defined(COMPILER_16_BIT) && !defined(DOS)
  2679.    ULONG far *sg_ptr;
  2680. #else
  2681.    ULONG *sg_ptr;
  2682. #endif
  2683.    if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
  2684.   p_SCCB->DataLength = 0x0000;
  2685.   }
  2686.    else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
  2687.  partial_cnt = 0x0000;
  2688.  sg_index = p_SCCB->Sccb_sgseg;
  2689. #if defined(COMPILER_16_BIT) && !defined(DOS)
  2690.  sg_ptr = (ULONG far *)p_SCCB->DataPointer;
  2691. #else
  2692.  sg_ptr = (ULONG *)p_SCCB->DataPointer;
  2693. #endif
  2694.  if (p_SCCB->Sccb_SGoffset) {
  2695. partial_cnt = p_SCCB->Sccb_SGoffset;
  2696. sg_index++;
  2697. }
  2698.  while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
  2699. p_SCCB->DataLength ) {
  2700. partial_cnt += *(sg_ptr+(sg_index * 2));
  2701. sg_index++;
  2702. }
  2703.  p_SCCB->DataLength = partial_cnt;
  2704.  }
  2705.   else {
  2706.  p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
  2707.  }
  2708. }
  2709. /*---------------------------------------------------------------------
  2710.  *
  2711.  * Function: Wait 1 Second
  2712.  *
  2713.  * Description: Wait for 1 second.
  2714.  *
  2715.  *---------------------------------------------------------------------*/
  2716. #if defined(DOS)
  2717. void Wait1Second(USHORT p_port)
  2718. #else
  2719. void Wait1Second(ULONG p_port)
  2720. #endif
  2721. {
  2722.    UCHAR i;
  2723.    for(i=0; i < 4; i++) {
  2724.   Wait(p_port, TO_250ms);
  2725.   if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
  2726.  break;
  2727.   if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
  2728.  break;
  2729.   }
  2730. }
  2731. /*---------------------------------------------------------------------
  2732.  *
  2733.  * Function: Wait
  2734.  *
  2735.  * Description: Wait the desired delay.
  2736.  *
  2737.  *---------------------------------------------------------------------*/
  2738. #if defined(DOS)
  2739. void Wait(USHORT p_port, UCHAR p_delay)
  2740. #else
  2741. void Wait(ULONG p_port, UCHAR p_delay)
  2742. #endif
  2743. {
  2744.    UCHAR old_timer;
  2745.    UCHAR green_flag;
  2746.    old_timer = RD_HARPOON(p_port+hp_seltimeout);
  2747.    green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
  2748.    WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
  2749.    WR_HARPOON(p_port+hp_seltimeout,p_delay);
  2750.    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
  2751.    WRW_HARPOON((p_port+hp_intena), (default_intena & ~TIMEOUT));
  2752.    WR_HARPOON(p_port+hp_portctrl_0,
  2753.   (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
  2754.    while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
  2755.   if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
  2756.  break;
  2757.   if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
  2758.  break;
  2759.   }
  2760.    WR_HARPOON(p_port+hp_portctrl_0,
  2761.   (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
  2762.    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
  2763.    WRW_HARPOON((p_port+hp_intena), default_intena);
  2764.    WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
  2765.    WR_HARPOON(p_port+hp_seltimeout,old_timer);
  2766. }
  2767. /*---------------------------------------------------------------------
  2768.  *
  2769.  * Function: Enable/Disable Write to EEPROM
  2770.  *
  2771.  * Description: The EEPROM must first be enabled for writes
  2772.  *              A total of 9 clocks are needed.
  2773.  *
  2774.  *---------------------------------------------------------------------*/
  2775. #if defined(DOS)
  2776. void utilEEWriteOnOff(USHORT p_port,UCHAR p_mode)
  2777. #else
  2778. void utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
  2779. #endif
  2780. {
  2781.    UCHAR ee_value;
  2782.    ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
  2783.    if (p_mode)
  2784.   utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
  2785.    else
  2786.   utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
  2787.    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
  2788.    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);       /*Turn off Master Select */
  2789. }
  2790. /*---------------------------------------------------------------------
  2791.  *
  2792.  * Function: Write EEPROM
  2793.  *
  2794.  * Description: Write a word to the EEPROM at the specified
  2795.  *              address.
  2796.  *
  2797.  *---------------------------------------------------------------------*/
  2798. #if defined(DOS)
  2799. void utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr)
  2800. #else
  2801. void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
  2802. #endif
  2803. {
  2804.    UCHAR ee_value;
  2805.    USHORT i;
  2806.    ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
  2807.    (SEE_MS | SEE_CS));
  2808.    utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
  2809.    ee_value |= (SEE_MS + SEE_CS);
  2810.    for(i = 0x8000; i != 0; i>>=1) {
  2811.   if (i & ee_data)
  2812.  ee_value |= SEE_DO;
  2813.   else
  2814.  ee_value &= ~SEE_DO;
  2815.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2816.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2817.   ee_value |= SEE_CLK;          /* Clock  data! */
  2818.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2819.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2820.   ee_value &= ~SEE_CLK;
  2821.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2822.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2823.   }
  2824.    ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
  2825.    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
  2826.    Wait(p_port, TO_10ms);
  2827.    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
  2828.    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));       /* Turn off CS */
  2829.    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);       /* Turn off Master Select */
  2830. }
  2831. /*---------------------------------------------------------------------
  2832.  *
  2833.  * Function: Read EEPROM
  2834.  *
  2835.  * Description: Read a word from the EEPROM at the desired
  2836.  *              address.
  2837.  *
  2838.  *---------------------------------------------------------------------*/
  2839. #if defined(DOS)
  2840. USHORT utilEERead(USHORT p_port, USHORT ee_addr)
  2841. #else
  2842. USHORT utilEERead(ULONG p_port, USHORT ee_addr)
  2843. #endif
  2844. {
  2845.    USHORT i, ee_data1, ee_data2;
  2846. i = 0;
  2847. ee_data1 = utilEEReadOrg(p_port, ee_addr);
  2848. do
  2849. {
  2850. ee_data2 = utilEEReadOrg(p_port, ee_addr);
  2851. if(ee_data1 == ee_data2)
  2852. return(ee_data1);
  2853. ee_data1 = ee_data2;
  2854. i++;
  2855. }while(i < 4);
  2856. return(ee_data1);
  2857. }
  2858. /*---------------------------------------------------------------------
  2859.  *
  2860.  * Function: Read EEPROM Original 
  2861.  *
  2862.  * Description: Read a word from the EEPROM at the desired
  2863.  *              address.
  2864.  *
  2865.  *---------------------------------------------------------------------*/
  2866. #if defined(DOS)
  2867. USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr)
  2868. #else
  2869. USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr)
  2870. #endif
  2871. {
  2872.    UCHAR ee_value;
  2873.    USHORT i, ee_data;
  2874.    ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
  2875.    (SEE_MS | SEE_CS));
  2876.    utilEESendCmdAddr(p_port, EE_READ, ee_addr);
  2877.    ee_value |= (SEE_MS + SEE_CS);
  2878.    ee_data = 0;
  2879.    for(i = 1; i <= 16; i++) {
  2880.   ee_value |= SEE_CLK;          /* Clock  data! */
  2881.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2882.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2883.   ee_value &= ~SEE_CLK;
  2884.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2885.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2886.   ee_data <<= 1;
  2887.   if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
  2888.  ee_data |= 1;
  2889.   }
  2890.    ee_value &= ~(SEE_MS + SEE_CS);
  2891.    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
  2892.    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);   /*Turn off Master Select */
  2893.    return(ee_data);
  2894. }
  2895. /*---------------------------------------------------------------------
  2896.  *
  2897.  * Function: Send EE command and Address to the EEPROM
  2898.  *
  2899.  * Description: Transfers the correct command and sends the address
  2900.  *              to the eeprom.
  2901.  *
  2902.  *---------------------------------------------------------------------*/
  2903. #if defined(DOS)
  2904. void utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr)
  2905. #else
  2906. void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
  2907. #endif
  2908. {
  2909.    UCHAR ee_value;
  2910.    UCHAR narrow_flg;
  2911.    USHORT i;
  2912.    narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
  2913.    ee_value = SEE_MS;
  2914.    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2915.    ee_value |= SEE_CS;                             /* Set CS to EEPROM */
  2916.    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2917.    for(i = 0x04; i != 0; i>>=1) {
  2918.   if (i & ee_cmd)
  2919.  ee_value |= SEE_DO;
  2920.   else
  2921.  ee_value &= ~SEE_DO;
  2922.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2923.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2924.   ee_value |= SEE_CLK;                         /* Clock  data! */
  2925.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2926.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2927.   ee_value &= ~SEE_CLK;
  2928.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2929.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2930.   }
  2931.    if (narrow_flg)
  2932.   i = 0x0080;
  2933.    else
  2934.   i = 0x0200;
  2935.    while (i != 0) {
  2936.   if (i & ee_addr)
  2937.  ee_value |= SEE_DO;
  2938.   else
  2939.  ee_value &= ~SEE_DO;
  2940.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2941.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2942.   ee_value |= SEE_CLK;                         /* Clock  data! */
  2943.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2944.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2945.   ee_value &= ~SEE_CLK;
  2946.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2947.   WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
  2948.   i >>= 1;
  2949.   }
  2950. }
  2951. USHORT CalcCrc16(UCHAR buffer[])
  2952. {
  2953.    USHORT crc=0;
  2954. int i,j;
  2955.    USHORT ch;
  2956.    for (i=0; i < ID_STRING_LENGTH; i++)
  2957.    {
  2958.       ch = (USHORT) buffer[i];
  2959.    for(j=0; j < 8; j++)
  2960.    {
  2961.    if ((crc ^ ch) & 1)
  2962.             crc = (crc >> 1) ^ CRCMASK;
  2963.    else
  2964.             crc >>= 1;
  2965.    ch >>= 1;
  2966.    }
  2967.    }
  2968. return(crc);
  2969. }
  2970. UCHAR CalcLrc(UCHAR buffer[])
  2971. {
  2972. int i;
  2973. UCHAR lrc;
  2974. lrc = 0;
  2975. for(i = 0; i < ID_STRING_LENGTH; i++)
  2976. lrc ^= buffer[i];
  2977. return(lrc);
  2978. }
  2979. /*
  2980.   The following inline definitions avoid type conflicts.
  2981. */
  2982. static inline unsigned char
  2983. FlashPoint__ProbeHostAdapter(FlashPoint_Info_T *FlashPointInfo)
  2984. {
  2985.   return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
  2986. }
  2987. static inline FlashPoint_CardHandle_T
  2988. FlashPoint__HardwareResetHostAdapter(FlashPoint_Info_T *FlashPointInfo)
  2989. {
  2990.   return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
  2991. }
  2992. static inline void
  2993. FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
  2994. {
  2995.   FlashPoint_ReleaseHostAdapter(CardHandle);
  2996. }
  2997. static inline void
  2998. FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB)
  2999. {
  3000.   FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
  3001. }
  3002. static inline void
  3003. FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB)
  3004. {
  3005.   FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
  3006. }
  3007. static inline boolean
  3008. FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
  3009. {
  3010.   return FlashPoint_InterruptPending(CardHandle);
  3011. }
  3012. static inline int
  3013. FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
  3014. {
  3015.   return FlashPoint_HandleInterrupt(CardHandle);
  3016. }
  3017. #define FlashPoint_ProbeHostAdapter     FlashPoint__ProbeHostAdapter
  3018. #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
  3019. #define FlashPoint_ReleaseHostAdapter     FlashPoint__ReleaseHostAdapter
  3020. #define FlashPoint_StartCCB     FlashPoint__StartCCB
  3021. #define FlashPoint_AbortCCB     FlashPoint__AbortCCB
  3022. #define FlashPoint_InterruptPending     FlashPoint__InterruptPending
  3023. #define FlashPoint_HandleInterrupt     FlashPoint__HandleInterrupt
  3024. /*
  3025.   FlashPoint_InquireTargetInfo returns the Synchronous Period, Synchronous
  3026.   Offset, and Wide Transfers Active information for TargetID on CardHandle.
  3027. */
  3028. void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T CardHandle,
  3029.   int TargetID,
  3030.   unsigned char *SynchronousPeriod,
  3031.   unsigned char *SynchronousOffset,
  3032.   unsigned char *WideTransfersActive)
  3033. {
  3034.   SCCBMGR_TAR_INFO *TargetInfo =
  3035.     &sccbMgrTbl[((SCCBCARD *)CardHandle)->cardIndex][TargetID];
  3036.   if ((TargetInfo->TarSyncCtrl & SYNC_OFFSET) > 0)
  3037.     {
  3038.       *SynchronousPeriod = 5 * ((TargetInfo->TarSyncCtrl >> 5) + 1);
  3039.       *SynchronousOffset = TargetInfo->TarSyncCtrl & SYNC_OFFSET;
  3040.     }
  3041.   else
  3042.     {
  3043.       *SynchronousPeriod = 0;
  3044.       *SynchronousOffset = 0;
  3045.     }
  3046.   *WideTransfersActive = (TargetInfo->TarSyncCtrl & NARROW_SCSI ? 0 : 1);
  3047. }
  3048. #else  /* CONFIG_SCSI_OMIT_FLASHPOINT */
  3049. /*
  3050.   Define prototypes for the FlashPoint SCCB Manager Functions.
  3051. */
  3052. extern unsigned char FlashPoint_ProbeHostAdapter(FlashPoint_Info_T *);
  3053. extern FlashPoint_CardHandle_T
  3054.        FlashPoint_HardwareResetHostAdapter(FlashPoint_Info_T *);
  3055. extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *);
  3056. extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *);
  3057. extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
  3058. extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
  3059. extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
  3060. extern void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T,
  3061.  int, unsigned char *,
  3062.  unsigned char *, unsigned char *);
  3063. #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */