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

Linux/Unix编程

开发平台:

Unix_Linux

  1. #endif /* (FW_TYPE==_UCB_MGR_)   */
  2. #ifndef NO_IOCTLS
  3. #if (FW_TYPE==_UCB_MGR_)
  4. void SccbMgr_unload_card(CARD_HANDLE pCurrCard)
  5. #else
  6. #if defined(DOS)
  7. void SccbMgr_unload_card(USHORT pCurrCard)
  8. #else
  9. void SccbMgr_unload_card(ULONG pCurrCard)
  10. #endif
  11. #endif
  12. {
  13. UCHAR i;
  14. #if defined(DOS)
  15. USHORT portBase;
  16. USHORT regOffset;
  17. #else
  18. ULONG portBase;
  19. ULONG regOffset;
  20. #endif
  21. ULONG scamData;
  22. #if defined(OS2)
  23. ULONG far *pScamTbl;
  24. #else
  25. ULONG *pScamTbl;
  26. #endif
  27. PNVRamInfo pCurrNvRam;
  28. pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
  29. if(pCurrNvRam){
  30. WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
  31. WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
  32. WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
  33. WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
  34. WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
  35. for(i = 0; i < MAX_SCSI_TAR / 2; i++)
  36. WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
  37. portBase = pCurrNvRam->niBaseAddr;
  38. for(i = 0; i < MAX_SCSI_TAR; i++){
  39. regOffset = hp_aramBase + 64 + i*4;
  40. #if defined(OS2)
  41. pScamTbl = (ULONG far *) &pCurrNvRam->niScamTbl[i];
  42. #else
  43. pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
  44. #endif
  45. scamData = *pScamTbl;
  46. WR_HARP32(portBase, regOffset, scamData);
  47. }
  48. }else{
  49. WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
  50. }
  51. }
  52. #endif /* NO_IOCTLS */
  53. void RNVRamData(PNVRamInfo pNvRamInfo)
  54. {
  55. UCHAR i;
  56. #if defined(DOS)
  57. USHORT portBase;
  58. USHORT regOffset;
  59. #else
  60. ULONG portBase;
  61. ULONG regOffset;
  62. #endif
  63. ULONG scamData;
  64. #if defined (OS2)
  65. ULONG far *pScamTbl;
  66. #else
  67. ULONG *pScamTbl;
  68. #endif
  69. pNvRamInfo->niModel    = RdStack(pNvRamInfo->niBaseAddr, 0);
  70. pNvRamInfo->niSysConf  = RdStack(pNvRamInfo->niBaseAddr, 1);
  71. pNvRamInfo->niScsiConf = RdStack(pNvRamInfo->niBaseAddr, 2);
  72. pNvRamInfo->niScamConf = RdStack(pNvRamInfo->niBaseAddr, 3);
  73. pNvRamInfo->niAdapId   = RdStack(pNvRamInfo->niBaseAddr, 4);
  74. for(i = 0; i < MAX_SCSI_TAR / 2; i++)
  75. pNvRamInfo->niSyncTbl[i] = RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
  76. portBase = pNvRamInfo->niBaseAddr;
  77. for(i = 0; i < MAX_SCSI_TAR; i++){
  78. regOffset = hp_aramBase + 64 + i*4;
  79. RD_HARP32(portBase, regOffset, scamData);
  80. #if defined(OS2)
  81. pScamTbl = (ULONG far *) &pNvRamInfo->niScamTbl[i];
  82. #else
  83. pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
  84. #endif
  85. *pScamTbl = scamData;
  86. }
  87. }
  88. #if defined(DOS)
  89. UCHAR RdStack(USHORT portBase, UCHAR index)
  90. #else
  91. UCHAR RdStack(ULONG portBase, UCHAR index)
  92. #endif
  93. {
  94. WR_HARPOON(portBase + hp_stack_addr, index);
  95. return(RD_HARPOON(portBase + hp_stack_data));
  96. }
  97. #if defined(DOS)
  98. void WrStack(USHORT portBase, UCHAR index, UCHAR data)
  99. #else
  100. void WrStack(ULONG portBase, UCHAR index, UCHAR data)
  101. #endif
  102. {
  103. WR_HARPOON(portBase + hp_stack_addr, index);
  104. WR_HARPOON(portBase + hp_stack_data, data);
  105. }
  106. #if (FW_TYPE==_UCB_MGR_)
  107. u08bits ChkIfChipInitialized(BASE_PORT ioPort)
  108. #else
  109. #if defined(DOS)
  110. UCHAR ChkIfChipInitialized(USHORT ioPort)
  111. #else
  112. UCHAR ChkIfChipInitialized(ULONG ioPort)
  113. #endif
  114. #endif
  115. {
  116. if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != RdStack(ioPort, 4))
  117. return(FALSE);
  118. if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
  119. != CLKCTRL_DEFAULT)
  120. return(FALSE);
  121. if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
  122. (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
  123. return(TRUE);
  124. return(FALSE);
  125. }
  126. /*---------------------------------------------------------------------
  127.  *
  128.  * Function: SccbMgr_start_sccb
  129.  *
  130.  * Description: Start a command pointed to by p_Sccb. When the
  131.  *              command is completed it will be returned via the
  132.  *              callback function.
  133.  *
  134.  *---------------------------------------------------------------------*/
  135. #if (FW_TYPE==_UCB_MGR_)
  136. void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb)
  137. #else
  138. #if defined(DOS)
  139. void SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_Sccb)
  140. #else
  141. void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
  142. #endif
  143. #endif
  144. {
  145. #if defined(DOS)
  146.    USHORT ioport;
  147. #else
  148.    ULONG ioport;
  149. #endif
  150.    UCHAR thisCard, lun;
  151. PSCCB pSaveSccb;
  152.    CALL_BK_FN callback;
  153. #if (FW_TYPE==_UCB_MGR_)
  154.    PSCCB p_Sccb;
  155. #endif
  156.    mOS_Lock((PSCCBcard)pCurrCard);
  157.    thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
  158.    ioport = ((PSCCBcard) pCurrCard)->ioPort;
  159. #if (FW_TYPE==_UCB_MGR_)
  160.    p_Sccb = (PSCCB)p_ucb->UCB_MgrPrivatePtr;
  161. #endif
  162. if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
  163. {
  164. #if (FW_TYPE==_UCB_MGR_)
  165. p_ucb->UCB_hbastat = SCCB_COMPLETE;
  166. p_ucb->UCB_status=SCCB_ERROR;
  167. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  168. if (callback)
  169. callback(p_ucb);
  170. #endif
  171. #if (FW_TYPE==_SCCB_MGR_)
  172. p_Sccb->HostStatus = SCCB_COMPLETE;
  173. p_Sccb->SccbStatus = SCCB_ERROR;
  174. callback = (CALL_BK_FN)p_Sccb->SccbCallback;
  175. if (callback)
  176. callback(p_Sccb);
  177. #endif
  178. mOS_UnLock((PSCCBcard)pCurrCard);
  179. return;
  180. }
  181. #if (FW_TYPE==_SCCB_MGR_)
  182.    sinits(p_Sccb,thisCard);
  183. #endif
  184. #if (FW_TYPE==_UCB_MGR_)
  185. #ifndef NO_IOCTLS
  186.    if (p_ucb->UCB_opcode & OPC_IOCTL)
  187. {
  188. switch (p_ucb->UCB_IOCTLCommand) 
  189. {
  190. case READ_NVRAM:
  191. ReadNVRam((PSCCBcard)pCurrCard,p_ucb);
  192. p_ucb->UCB_status=UCB_SUCCESS;
  193. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  194. if (callback)
  195. callback(p_ucb);
  196. mOS_UnLock((PSCCBcard)pCurrCard);
  197. return;
  198. case WRITE_NVRAM:
  199. WriteNVRam((PSCCBcard)pCurrCard,p_ucb);
  200. p_ucb->UCB_status=UCB_SUCCESS;
  201. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  202. if (callback)
  203. callback(p_ucb);
  204. mOS_UnLock((PSCCBcard)pCurrCard);
  205. return;
  206. case SEND_SCSI_PASSTHRU:
  207. #if (FW_TYPE != _SCCB_MGR_)
  208. if( p_ucb->UCB_targid >=
  209.     ((PSCCBcard)pCurrCard)->cardInfo->ai_MaxTarg )
  210. {
  211. p_ucb->UCB_status = UCB_ERROR;
  212. p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
  213. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  214. if (callback)
  215. callback(p_ucb);
  216. mOS_UnLock((PSCCBcard)pCurrCard);
  217. return;
  218. }
  219. #endif
  220. break;
  221. case HARD_RESET:
  222. p_ucb->UCB_status = UCB_INVALID;
  223. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  224. if (callback)
  225. callback(p_ucb);
  226. mOS_UnLock((PSCCBcard)pCurrCard);
  227. return;
  228. case GET_DEVICE_SYNCRATE:
  229. if( !GetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) )
  230. {
  231. p_ucb->UCB_status = UCB_SUCCESS;
  232. }
  233. else
  234. {
  235. p_ucb->UCB_status = UCB_ERROR;
  236. p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
  237. }
  238. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  239. if (callback)
  240. callback(p_ucb);
  241. mOS_UnLock((PSCCBcard)pCurrCard);
  242. return;
  243. case SET_DEVICE_SYNCRATE:
  244. if( !SetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) )
  245. {
  246. p_ucb->UCB_status = UCB_SUCCESS;
  247. }
  248. else
  249. {
  250. p_ucb->UCB_status = UCB_ERROR;
  251. p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
  252. }
  253. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  254. if (callback)
  255. callback(p_ucb);
  256. mOS_UnLock((PSCCBcard)pCurrCard);
  257. return;
  258. case GET_WIDE_MODE:
  259. if( !GetDevWideMode((PSCCBcard)pCurrCard,p_ucb) )
  260. {
  261. p_ucb->UCB_status = UCB_SUCCESS;
  262. }
  263. else
  264. {
  265. p_ucb->UCB_status = UCB_ERROR;
  266. p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
  267. }
  268. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  269. if (callback)
  270. callback(p_ucb);
  271. mOS_UnLock((PSCCBcard)pCurrCard);
  272. return;
  273. case SET_WIDE_MODE:
  274. if( !SetDevWideMode((PSCCBcard)pCurrCard,p_ucb) )
  275. {
  276. p_ucb->UCB_status = UCB_SUCCESS;
  277. }
  278. else
  279. {
  280. p_ucb->UCB_status = UCB_ERROR;
  281. p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
  282. }
  283. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  284. if (callback)
  285. callback(p_ucb);
  286. mOS_UnLock((PSCCBcard)pCurrCard);
  287. return;
  288. default:
  289. p_ucb->UCB_status=UCB_INVALID;
  290. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  291. if (callback)
  292. callback(p_ucb);
  293. mOS_UnLock((PSCCBcard)pCurrCard);
  294. return;
  295. }
  296. }
  297. #endif /* NO_IOCTLS */
  298. #endif /* (FW_TYPE==_UCB_MGR_) */
  299.    if (!((PSCCBcard) pCurrCard)->cmdCounter)
  300.       {
  301.       WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
  302.          | SCCB_MGR_ACTIVE));
  303.       if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
  304.          {
  305.  WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
  306.  WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
  307.          }
  308.       }
  309.    ((PSCCBcard)pCurrCard)->cmdCounter++;
  310.    if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
  311.       WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
  312.          | TICKLE_ME));
  313. if(p_Sccb->OperationCode == RESET_COMMAND)
  314. {
  315. pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
  316. ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
  317. queueSelectFail(&BL_Card[thisCard], thisCard);
  318. ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
  319. }
  320. else
  321. {
  322.       queueAddSccb(p_Sccb,thisCard);
  323. }
  324.       }
  325.    else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
  326. if(p_Sccb->OperationCode == RESET_COMMAND)
  327. {
  328. pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
  329. ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
  330. queueSelectFail(&BL_Card[thisCard], thisCard);
  331. ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
  332. }
  333. else
  334. {
  335.       queueAddSccb(p_Sccb,thisCard);
  336. }
  337.       }
  338.    else {
  339.       MDISABLE_INT(ioport);
  340. if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) && 
  341. ((sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  342. lun = p_Sccb->Lun;
  343. else
  344. lun = 0;
  345.       if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
  346.          (sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
  347.          (sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
  348.          == FALSE)) {
  349.             ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
  350.    mOS_UnLock((PSCCBcard)pCurrCard);
  351. #if defined(DOS)
  352.             ssel((USHORT)p_Sccb->SccbIOPort,thisCard);
  353. #else
  354.     ssel(p_Sccb->SccbIOPort,thisCard);
  355. #endif
  356.    mOS_Lock((PSCCBcard)pCurrCard);
  357.          }
  358.       else {
  359. if(p_Sccb->OperationCode == RESET_COMMAND)
  360. {
  361. pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
  362. ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
  363. queueSelectFail(&BL_Card[thisCard], thisCard);
  364. ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
  365. }
  366. else
  367. {
  368.           queueAddSccb(p_Sccb,thisCard);
  369. }
  370.          }
  371.       MENABLE_INT(ioport);
  372.       }
  373.    mOS_UnLock((PSCCBcard)pCurrCard);
  374. }
  375. /*---------------------------------------------------------------------
  376.  *
  377.  * Function: SccbMgr_abort_sccb
  378.  *
  379.  * Description: Abort the command pointed to by p_Sccb.  When the
  380.  *              command is completed it will be returned via the
  381.  *              callback function.
  382.  *
  383.  *---------------------------------------------------------------------*/
  384. #if (FW_TYPE==_UCB_MGR_)
  385. s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb)
  386. #else
  387. #if defined(DOS)
  388. int SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_Sccb)
  389. #else
  390. int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
  391. #endif
  392. #endif
  393. {
  394. #if defined(DOS)
  395. USHORT ioport;
  396. #else
  397. ULONG ioport;
  398. #endif
  399. UCHAR thisCard;
  400. CALL_BK_FN callback;
  401. UCHAR TID;
  402. PSCCB pSaveSCCB;
  403. PSCCBMgr_tar_info currTar_Info;
  404. #if (FW_TYPE==_UCB_MGR_)
  405. PSCCB    p_Sccb;
  406. p_Sccb=(PSCCB)p_ucb->UCB_MgrPrivatePtr;
  407. #endif
  408. ioport = ((PSCCBcard) pCurrCard)->ioPort;
  409. thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
  410. mOS_Lock((PSCCBcard)pCurrCard);
  411. if (RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)
  412. {
  413. mOS_UnLock((PSCCBcard)pCurrCard);
  414. }
  415. else
  416. {
  417. if (queueFindSccb(p_Sccb,thisCard))
  418. {
  419. mOS_UnLock((PSCCBcard)pCurrCard);
  420. ((PSCCBcard)pCurrCard)->cmdCounter--;
  421. if (!((PSCCBcard)pCurrCard)->cmdCounter)
  422. WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
  423. & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
  424. #if (FW_TYPE==_SCCB_MGR_)
  425. p_Sccb->SccbStatus = SCCB_ABORT;
  426. callback = p_Sccb->SccbCallback;
  427. callback(p_Sccb);
  428. #else
  429. p_ucb->UCB_status=SCCB_ABORT;
  430. callback = (CALL_BK_FN)p_ucb->UCB_callback;
  431. callback(p_ucb);
  432. #endif
  433. return(0);
  434. }
  435. else
  436. {
  437. mOS_UnLock((PSCCBcard)pCurrCard);
  438. if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
  439. {
  440. p_Sccb->SccbStatus = SCCB_ABORT;
  441. return(0);
  442. }
  443. else
  444. {
  445. TID = p_Sccb->TargID;
  446. if(p_Sccb->Sccb_tag)
  447. {
  448. MDISABLE_INT(ioport);
  449. if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
  450. {
  451. p_Sccb->SccbStatus = SCCB_ABORT;
  452. p_Sccb->Sccb_scsistat = ABORT_ST;
  453. #if (FW_TYPE==_UCB_MGR_)
  454. p_ucb->UCB_status=SCCB_ABORT;
  455. #endif
  456. p_Sccb->Sccb_scsimsg = SMABORT_TAG;
  457. if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
  458. {
  459. ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
  460. ssel(ioport, thisCard);
  461. }
  462. else
  463. {
  464. pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
  465. ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
  466. queueSelectFail((PSCCBcard) pCurrCard, thisCard);
  467. ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
  468. }
  469. }
  470. MENABLE_INT(ioport);
  471. return(0);
  472. }
  473. else
  474. {
  475. currTar_Info = &sccbMgrTbl[thisCard][p_Sccb->TargID];
  476. if(BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]] 
  477. == p_Sccb)
  478. {
  479. p_Sccb->SccbStatus = SCCB_ABORT;
  480. return(0);
  481. }
  482. }
  483. }
  484. }
  485. }
  486. return(-1);
  487. }
  488. /*---------------------------------------------------------------------
  489.  *
  490.  * Function: SccbMgr_my_int
  491.  *
  492.  * Description: Do a quick check to determine if there is a pending
  493.  *              interrupt for this card and disable the IRQ Pin if so.
  494.  *
  495.  *---------------------------------------------------------------------*/
  496. #if (FW_TYPE==_UCB_MGR_)
  497. u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard)
  498. #else
  499. #if defined(DOS)
  500. UCHAR SccbMgr_my_int(USHORT pCurrCard)
  501. #else
  502. UCHAR SccbMgr_my_int(ULONG pCurrCard)
  503. #endif
  504. #endif
  505. {
  506. #if defined(DOS)
  507.    USHORT ioport;
  508. #else
  509.    ULONG ioport;
  510. #endif
  511.    ioport = ((PSCCBcard)pCurrCard)->ioPort;
  512.    if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
  513.    {
  514. #if defined(DOS)
  515.       MDISABLE_INT(ioport);
  516. #endif
  517.       return(TRUE);
  518.    }
  519.    else
  520.       return(FALSE);
  521. }
  522. /*---------------------------------------------------------------------
  523.  *
  524.  * Function: SccbMgr_isr
  525.  *
  526.  * Description: This is our entry point when an interrupt is generated
  527.  *              by the card and the upper level driver passes it on to
  528.  *              us.
  529.  *
  530.  *---------------------------------------------------------------------*/
  531. #if (FW_TYPE==_UCB_MGR_)
  532. s32bits SccbMgr_isr(CARD_HANDLE pCurrCard)
  533. #else
  534. #if defined(DOS)
  535. int SccbMgr_isr(USHORT pCurrCard)
  536. #else
  537. int SccbMgr_isr(ULONG pCurrCard)
  538. #endif
  539. #endif
  540. {
  541.    PSCCB currSCCB;
  542.    UCHAR thisCard,result,bm_status, bm_int_st;
  543.    USHORT hp_int;
  544.    UCHAR i, target;
  545. #if defined(DOS)
  546.    USHORT ioport;
  547. #else
  548.    ULONG ioport;
  549. #endif
  550.    mOS_Lock((PSCCBcard)pCurrCard);
  551.    thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
  552.    ioport = ((PSCCBcard)pCurrCard)->ioPort;
  553.    MDISABLE_INT(ioport);
  554. #if defined(BUGBUG)
  555.    WR_HARPOON(ioport+hp_user_defined_D, RD_HARPOON(ioport+hp_int_status));
  556. #endif
  557.    if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
  558. bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
  559.    else
  560.       bm_status = 0;
  561.    WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
  562.    mOS_UnLock((PSCCBcard)pCurrCard);
  563.    while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & default_intena) |
  564.   bm_status)
  565.      {
  566.        currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
  567. #if defined(BUGBUG)
  568.    Debug_Load(thisCard,(UCHAR) 0XFF);
  569.    Debug_Load(thisCard,bm_int_st);
  570.    Debug_Load(thisCard,hp_int_0);
  571.    Debug_Load(thisCard,hp_int_1);
  572. #endif
  573.       if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
  574.          result = SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
  575.          WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
  576.          bm_status = 0;
  577.          if (result) {
  578.    mOS_Lock((PSCCBcard)pCurrCard);
  579.             MENABLE_INT(ioport);
  580.    mOS_UnLock((PSCCBcard)pCurrCard);
  581.             return(result);
  582.             }
  583.          }
  584.       else if (hp_int & ICMD_COMP) {
  585.          if ( !(hp_int & BUS_FREE) ) {
  586.             /* Wait for the BusFree before starting a new command.  We
  587.                must also check for being reselected since the BusFree
  588.                may not show up if another device reselects us in 1.5us or
  589.                less.  SRR Wednesday, 3/8/1995.
  590.          */
  591.    while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
  592.  }
  593.          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
  594.             phaseChkFifo(ioport, thisCard);
  595. /*         WRW_HARPOON((ioport+hp_intstat),
  596.             (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
  597.          */
  598.  WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
  599.          autoCmdCmplt(ioport,thisCard);
  600.          }
  601.       else if (hp_int & ITAR_DISC)
  602.          {
  603.          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
  604.             phaseChkFifo(ioport, thisCard);
  605.             }
  606.          if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
  607.             WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
  608.             currSCCB->Sccb_XferState |= F_NO_DATA_YET;
  609.             currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
  610.             }
  611.          currSCCB->Sccb_scsistat = DISCONNECT_ST;
  612.          queueDisconnect(currSCCB,thisCard);
  613.             /* Wait for the BusFree before starting a new command.  We
  614.                must also check for being reselected since the BusFree
  615.                may not show up if another device reselects us in 1.5us or
  616.                less.  SRR Wednesday, 3/8/1995.
  617.              */
  618.    while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
  619.   !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
  620.     RD_HARPOON((ioport+hp_scsisig)) ==
  621.     (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
  622.    /*
  623.      The additional loop exit condition above detects a timing problem
  624.      with the revision D/E harpoon chips.  The caller should reset the
  625.      host adapter to recover when 0xFE is returned.
  626.    */
  627.    if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
  628.      {
  629.        mOS_Lock((PSCCBcard)pCurrCard);
  630.        MENABLE_INT(ioport);
  631.        mOS_UnLock((PSCCBcard)pCurrCard);
  632.        return 0xFE;
  633.      }
  634.          WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
  635.          ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
  636.        }
  637.       else if (hp_int & RSEL) {
  638.          WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
  639.          if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
  640.       {
  641.             if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
  642.       {
  643.                phaseChkFifo(ioport, thisCard);
  644.                }
  645.             if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
  646.       {
  647.                WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
  648.                currSCCB->Sccb_XferState |= F_NO_DATA_YET;
  649.                currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
  650.                }
  651.             WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
  652.             currSCCB->Sccb_scsistat = DISCONNECT_ST;
  653.             queueDisconnect(currSCCB,thisCard);
  654.             }
  655.          sres(ioport,thisCard,((PSCCBcard)pCurrCard));
  656.          phaseDecode(ioport,thisCard);
  657.          }
  658.       else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
  659.          {
  660.             WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
  661.             phaseDecode(ioport,thisCard);
  662.          }
  663.       else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
  664.    {
  665.      WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
  666.      if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
  667.      {
  668.      phaseDecode(ioport,thisCard);
  669.      }
  670.      else
  671.      {
  672.    /* Harpoon problem some SCSI target device respond to selection
  673.    with short BUSY pulse (<400ns) this will make the Harpoon is not able
  674.    to latch the correct Target ID into reg. x53.
  675.    The work around require to correct this reg. But when write to this
  676.    reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
  677.    need to read this reg first then restore it later. After update to 0x53 */
  678.      i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
  679.      target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
  680.      WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
  681.      WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
  682.      WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
  683.      WR_HARPOON(ioport+hp_fifowrite, i);
  684.      WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
  685.      }
  686.      }
  687.       else if (hp_int & XFER_CNT_0) {
  688.          WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
  689.          schkdd(ioport,thisCard);
  690.          }
  691.       else if (hp_int & BUS_FREE) {
  692.          WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
  693.          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
  694.             hostDataXferAbort(ioport,thisCard,currSCCB);
  695. }
  696.          phaseBusFree(ioport,thisCard);
  697. }
  698.       else if (hp_int & ITICKLE) {
  699.          WRW_HARPOON((ioport+hp_intstat), ITICKLE);
  700.          ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
  701.          }
  702.       if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
  703.          ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
  704.          if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
  705.             queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
  706.             }
  707.          if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
  708.             ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
  709.             ssel(ioport,thisCard);
  710.             }
  711.          break;
  712.          }
  713.       }  /*end while */
  714.    mOS_Lock((PSCCBcard)pCurrCard);
  715.    MENABLE_INT(ioport);
  716.    mOS_UnLock((PSCCBcard)pCurrCard);
  717.    return(0);
  718. }
  719. /*---------------------------------------------------------------------
  720.  *
  721.  * Function: Sccb_bad_isr
  722.  *
  723.  * Description: Some type of interrupt has occurred which is slightly
  724.  *              out of the ordinary.  We will now decode it fully, in
  725.  *              this routine.  This is broken up in an attempt to save
  726.  *              processing time.
  727.  *
  728.  *---------------------------------------------------------------------*/
  729. #if defined(DOS)
  730. UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int)
  731. #else
  732. UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int)
  733. #endif
  734. {
  735. #if defined(HARP_REVX)
  736.    ULONG timer;
  737. #endif
  738. UCHAR temp, ScamFlg;
  739. PSCCBMgr_tar_info currTar_Info;
  740. PNVRamInfo pCurrNvRam;
  741.    if (RD_HARPOON(p_port+hp_ext_status) &
  742.          (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
  743.       {
  744.       if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
  745.          {
  746.          hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
  747.          }
  748.       if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
  749.          {
  750.          WR_HARPOON(p_port+hp_pci_stat_cfg,
  751.             (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
  752.          WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
  753.          }
  754.       if (pCurrCard->currentSCCB != NULL)
  755.          {
  756.          if (!pCurrCard->currentSCCB->HostStatus)
  757.             pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
  758.          sxfrp(p_port,p_card);
  759.      temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
  760. (EXT_ARB_ACK | SCSI_TERM_ENA_H));
  761.        WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
  762.          WR_HARPOON(p_port+hp_ee_ctrl, temp);
  763.          if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
  764.             {
  765.             phaseDecode(p_port,p_card);
  766.             }
  767.          }
  768.       }
  769.    else if (p_int & RESET)
  770.          {
  771. WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
  772. WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
  773.            if (pCurrCard->currentSCCB != NULL) {
  774.                if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
  775.                hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
  776.                }
  777.            DISABLE_AUTO(p_port);
  778.            sresb(p_port,p_card);
  779.            while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
  780. pCurrNvRam = pCurrCard->pNvRamInfo;
  781. if(pCurrNvRam){
  782. ScamFlg = pCurrNvRam->niScamConf;
  783. }
  784. else{
  785.    ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2);
  786. }
  787.            XbowInit(p_port, ScamFlg);
  788.                scini(p_card, pCurrCard->ourId, 0);
  789.            return(0xFF);
  790.          }
  791.    else if (p_int & FIFO) {
  792.       WRW_HARPOON((p_port+hp_intstat), FIFO);
  793. #if defined(HARP_REVX)
  794.       for (timer=0x00FFFFFFL; timer != 0x00000000L; timer--) {
  795.          if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
  796.             break;
  797.          if (RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)
  798.             break;
  799.          }
  800.       if ( (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY) &&
  801.            (RD_HARPOON(p_port+hp_fiforead) !=
  802.             RD_HARPOON(p_port+hp_fifowrite)) &&
  803.            (RD_HARPOON(p_port+hp_xfercnt_0))
  804.          )
  805.             WR_HARPOON((p_port+hp_xferstat), 0x01);
  806. /*      else
  807.  */
  808. /*         sxfrp(p_port,p_card);
  809.  */
  810. #else
  811.       if (pCurrCard->currentSCCB != NULL)
  812.          sxfrp(p_port,p_card);
  813. #endif
  814.       }
  815.    else if (p_int & TIMEOUT)
  816.       {
  817.       DISABLE_AUTO(p_port);
  818.       WRW_HARPOON((p_port+hp_intstat),
  819.   (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
  820.       pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
  821. currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
  822. if((pCurrCard->globalFlags & F_CONLUN_IO) &&
  823. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  824.       currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = FALSE;
  825. else
  826.       currTar_Info->TarLUNBusy[0] = FALSE;
  827.       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
  828.          {
  829.        currTar_Info->TarSyncCtrl = 0;
  830.          currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
  831.          }
  832.       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
  833.          {
  834.          currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
  835.          }
  836.       sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
  837.       queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
  838.       }
  839. #if defined(SCAM_LEV_2)
  840.    else if (p_int & SCAM_SEL)
  841.       {
  842.       scarb(p_port,LEVEL2_TAR);
  843.       scsel(p_port);
  844.       scasid(p_card, p_port);
  845.       scbusf(p_port);
  846.       WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
  847.       }
  848. #endif
  849.    return(0x00);
  850. }
  851. /*---------------------------------------------------------------------
  852.  *
  853.  * Function: SccbMgr_scsi_reset
  854.  *
  855.  * Description: A SCSI bus reset will be generated and all outstanding
  856.  *              Sccbs will be returned via the callback.
  857.  *
  858.  *---------------------------------------------------------------------*/
  859. #if (FW_TYPE==_UCB_MGR_)
  860. void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard)
  861. #else
  862. #if defined(DOS)
  863. void SccbMgr_scsi_reset(USHORT pCurrCard)
  864. #else
  865. void SccbMgr_scsi_reset(ULONG pCurrCard)
  866. #endif
  867. #endif
  868. {
  869.    UCHAR thisCard;
  870.    thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
  871.    mOS_Lock((PSCCBcard)pCurrCard);
  872.    if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
  873.       {
  874.       WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_clkctrl_0, CLKCTRL_DEFAULT);
  875.       WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sys_ctrl, 0x00);
  876.       }
  877.    sresb(((PSCCBcard)pCurrCard)->ioPort,thisCard);
  878.    if (RD_HARPOON(((PSCCBcard)pCurrCard)->ioPort+hp_ext_status) & BM_CMD_BUSY)
  879.       {
  880.       WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl,
  881.          (RD_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl)
  882.          & ~SCATTER_EN));
  883.       WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sg_addr,0x00);
  884.       ((PSCCBcard) pCurrCard)->globalFlags &= ~F_HOST_XFER_ACT;
  885.       busMstrTimeOut(((PSCCBcard) pCurrCard)->ioPort);
  886.       WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_int_mask,
  887.          (INT_CMD_COMPL | SCSI_INTERRUPT));
  888.       }
  889. /*
  890.       if (utilEERead(((PSCCBcard)pCurrCard)->ioPort, (SCAM_CONFIG/2))
  891.             & SCAM_ENABLED)
  892. */
  893.          scini(thisCard, ((PSCCBcard)pCurrCard)->ourId, 0);
  894. #if (FW_TYPE==_UCB_MGR_)
  895.    ((PSCCBcard)pCurrCard)->cardInfo->ai_AEN_routine(0x01,pCurrCard,0,0,0,0);
  896. #endif
  897.    mOS_UnLock((PSCCBcard)pCurrCard);
  898. }
  899. /*---------------------------------------------------------------------
  900.  *
  901.  * Function: SccbMgr_timer_expired
  902.  *
  903.  * Description: This function allow me to kill my own job that has not
  904.  *              yet completed, and has cause a timeout to occur.  This
  905.  *              timeout has caused the upper level driver to call this
  906.  *              function.
  907.  *
  908.  *---------------------------------------------------------------------*/
  909. #if (FW_TYPE==_UCB_MGR_)
  910. void SccbMgr_timer_expired(CARD_HANDLE pCurrCard)
  911. #else
  912. #if defined(DOS)
  913. void SccbMgr_timer_expired(USHORT pCurrCard)
  914. #else
  915. void SccbMgr_timer_expired(ULONG pCurrCard)
  916. #endif
  917. #endif
  918. {
  919. }
  920. #if defined(DOS)
  921. /*---------------------------------------------------------------------
  922.  *
  923.  * Function: SccbMgr_status
  924.  *
  925.  * Description: This function returns the number of outstanding SCCB's.
  926.  *              This is specific to the DOS enviroment, which needs this
  927.  *              to help them keep protected and real mode commands staight.
  928.  *
  929.  *---------------------------------------------------------------------*/
  930. USHORT SccbMgr_status(USHORT pCurrCard)
  931. {
  932.    return(BL_Card[pCurrCard].cmdCounter);
  933. }
  934. #endif
  935. /*---------------------------------------------------------------------
  936.  *
  937.  * Function: SccbMgrTableInit
  938.  *
  939.  * Description: Initialize all Sccb manager data structures.
  940.  *
  941.  *---------------------------------------------------------------------*/
  942. void SccbMgrTableInitAll()
  943. {
  944.    UCHAR thisCard;
  945.    for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
  946.       {
  947.       SccbMgrTableInitCard(&BL_Card[thisCard],thisCard);
  948.       BL_Card[thisCard].ioPort      = 0x00;
  949.       BL_Card[thisCard].cardInfo    = NULL;
  950.       BL_Card[thisCard].cardIndex   = 0xFF;
  951.       BL_Card[thisCard].ourId       = 0x00;
  952. BL_Card[thisCard].pNvRamInfo = NULL;
  953.       }
  954. }
  955. /*---------------------------------------------------------------------
  956.  *
  957.  * Function: SccbMgrTableInit
  958.  *
  959.  * Description: Initialize all Sccb manager data structures.
  960.  *
  961.  *---------------------------------------------------------------------*/
  962. void SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
  963. {
  964.    UCHAR scsiID, qtag;
  965. for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
  966. {
  967. BL_Card[p_card].discQ_Tbl[qtag] = NULL;
  968. }
  969.    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
  970.       {
  971.       sccbMgrTbl[p_card][scsiID].TarStatus = 0;
  972.       sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
  973.       SccbMgrTableInitTarget(p_card, scsiID);
  974.       }
  975.    pCurrCard->scanIndex = 0x00;
  976.    pCurrCard->currentSCCB = NULL;
  977.    pCurrCard->globalFlags = 0x00;
  978.    pCurrCard->cmdCounter  = 0x00;
  979. pCurrCard->tagQ_Lst = 0x01;
  980. pCurrCard->discQCount = 0; 
  981. }
  982. /*---------------------------------------------------------------------
  983.  *
  984.  * Function: SccbMgrTableInit
  985.  *
  986.  * Description: Initialize all Sccb manager data structures.
  987.  *
  988.  *---------------------------------------------------------------------*/
  989. void SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
  990. {
  991. UCHAR lun, qtag;
  992. PSCCBMgr_tar_info currTar_Info;
  993. currTar_Info = &sccbMgrTbl[p_card][target];
  994. currTar_Info->TarSelQ_Cnt = 0;
  995. currTar_Info->TarSyncCtrl = 0;
  996. currTar_Info->TarSelQ_Head = NULL;
  997. currTar_Info->TarSelQ_Tail = NULL;
  998. currTar_Info->TarTagQ_Cnt = 0;
  999. currTar_Info->TarLUN_CA = FALSE;
  1000. for (lun = 0; lun < MAX_LUN; lun++)
  1001. {
  1002. currTar_Info->TarLUNBusy[lun] = FALSE;
  1003. currTar_Info->LunDiscQ_Idx[lun] = 0;
  1004. }
  1005. for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
  1006. {
  1007. if(BL_Card[p_card].discQ_Tbl[qtag] != NULL)
  1008. {
  1009. if(BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
  1010. {
  1011. BL_Card[p_card].discQ_Tbl[qtag] = NULL;
  1012. BL_Card[p_card].discQCount--;
  1013. }
  1014. }
  1015. }
  1016. }
  1017. #if defined(BUGBUG)
  1018. /*****************************************************************
  1019.  * Save the current byte in the debug array
  1020.  *****************************************************************/
  1021. void Debug_Load(UCHAR p_card, UCHAR p_bug_data)
  1022. {
  1023.    debug_int[p_card][debug_index[p_card]] = p_bug_data;
  1024.    debug_index[p_card]++;
  1025.    if (debug_index[p_card] == debug_size)
  1026.       debug_index[p_card] = 0;
  1027. }
  1028. #endif
  1029. #ident "$Id: sccb_dat.c 1.10 1997/02/22 03:16:02 awin Exp $"
  1030. /*----------------------------------------------------------------------
  1031.  *
  1032.  *
  1033.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  1034.  *
  1035.  *   This file is available under both the GNU General Public License
  1036.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  1037.  *
  1038.  *   $Workfile:   sccb_dat.c  $
  1039.  *
  1040.  *   Description:  Functions relating to handling of the SCCB interface 
  1041.  *                 between the device driver and the HARPOON.
  1042.  *
  1043.  *   $Date: 1997/02/22 03:16:02 $
  1044.  *
  1045.  *   $Revision: 1.10 $
  1046.  *
  1047.  *----------------------------------------------------------------------*/
  1048. /*#include <globals.h>*/
  1049. #if (FW_TYPE==_UCB_MGR_)
  1050. /*#include <budi.h>*/
  1051. #endif
  1052. /*#include <sccbmgr.h>*/
  1053. /*#include <blx30.h>*/
  1054. /*#include <target.h>*/
  1055. /*#include <harpoon.h>*/
  1056. /*
  1057. **  IMPORTANT NOTE!!!
  1058. **
  1059. **  You MUST preassign all data to a valid value or zero.  This is
  1060. **  required due to the MS compiler bug under OS/2 and Solaris Real-Mode
  1061. **  driver environment.
  1062. */
  1063. SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
  1064. SCCBCARD BL_Card[MAX_CARDS] = { { 0 } };
  1065. SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
  1066. NVRAMINFO nvRamInfo[MAX_MB_CARDS] = { { 0 } };
  1067. #if defined(OS2)
  1068. void (far *s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 };
  1069. UCHAR temp_id_string[ID_STRING_LENGTH] = { 0 };
  1070. #elif defined(SOLARIS_REAL_MODE) || defined(__STDC__)
  1071. void (*s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 };
  1072. #else
  1073. void (*s_PhaseTbl[8]) ();
  1074. #endif
  1075. #if defined(DOS)
  1076. UCHAR first_time = 0;
  1077. #endif
  1078. UCHAR mbCards = 0;
  1079. UCHAR scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', 
  1080. ' ', 'B', 'T', '-', '9', '3', '0', 
  1081. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  1082. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
  1083. USHORT default_intena = 0;
  1084. #if defined(BUGBUG)
  1085. UCHAR    debug_int[MAX_CARDS][debug_size] = { 0 };
  1086. UCHAR    debug_index[MAX_CARDS] = { 0 };
  1087. UCHAR    reserved_1[3] = { 0 };
  1088. #endif
  1089. #ident "$Id: scsi.c 1.23 1997/07/09 21:42:54 mohan Exp $"
  1090. /*----------------------------------------------------------------------
  1091.  *
  1092.  *
  1093.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  1094.  *
  1095.  *   This file is available under both the GNU General Public License
  1096.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  1097.  *
  1098.  *   $Workfile:   scsi.c  $
  1099.  *
  1100.  *   Description:  Functions for handling SCSI bus functions such as
  1101.  *                 selection/reselection, sync negotiation, message-in
  1102.  *                 decoding.
  1103.  *
  1104.  *   $Date: 1997/07/09 21:42:54 $
  1105.  *
  1106.  *   $Revision: 1.23 $
  1107.  *
  1108.  *----------------------------------------------------------------------*/
  1109. /*#include <globals.h>*/
  1110. #if (FW_TYPE==_UCB_MGR_)
  1111. /*#include <budi.h>*/
  1112. #endif
  1113. /*#include <sccbmgr.h>*/
  1114. /*#include <blx30.h>*/
  1115. /*#include <target.h>*/
  1116. /*#include <scsi2.h>*/
  1117. /*#include <eeprom.h>*/
  1118. /*#include <harpoon.h>*/
  1119. /*
  1120. extern SCCBCARD BL_Card[MAX_CARDS];
  1121. extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  1122. #if defined(BUGBUG)
  1123. void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
  1124. #endif
  1125. */
  1126. /*---------------------------------------------------------------------
  1127.  *
  1128.  * Function: sfetm
  1129.  *
  1130.  * Description: Read in a message byte from the SCSI bus, and check
  1131.  *              for a parity error.
  1132.  *
  1133.  *---------------------------------------------------------------------*/
  1134. #if defined(DOS)
  1135. UCHAR sfm(USHORT port, PSCCB pCurrSCCB)
  1136. #else
  1137. UCHAR sfm(ULONG port, PSCCB pCurrSCCB)
  1138. #endif
  1139. {
  1140. UCHAR message;
  1141. USHORT TimeOutLoop;
  1142. TimeOutLoop = 0;
  1143. while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
  1144. (TimeOutLoop++ < 20000) ){}
  1145. WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
  1146. message = RD_HARPOON(port+hp_scsidata_0);
  1147. WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
  1148. if (TimeOutLoop > 20000)
  1149. message = 0x00;   /* force message byte = 0 if Time Out on Req */
  1150. if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
  1151. (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
  1152. {
  1153. WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
  1154. WR_HARPOON(port+hp_xferstat, 0);
  1155. WR_HARPOON(port+hp_fiforead, 0);
  1156. WR_HARPOON(port+hp_fifowrite, 0);
  1157. if (pCurrSCCB != NULL)
  1158. {
  1159. pCurrSCCB->Sccb_scsimsg = SMPARITY;
  1160. }
  1161. message = 0x00;
  1162. do
  1163. {
  1164. ACCEPT_MSG_ATN(port);
  1165. TimeOutLoop = 0;
  1166. while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
  1167. (TimeOutLoop++ < 20000) ){}
  1168. if (TimeOutLoop > 20000)
  1169. {
  1170. WRW_HARPOON((port+hp_intstat), PARITY);
  1171. return(message);
  1172. }
  1173. if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
  1174. {
  1175. WRW_HARPOON((port+hp_intstat), PARITY);
  1176. return(message);
  1177. }
  1178. WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
  1179. RD_HARPOON(port+hp_scsidata_0);
  1180. WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
  1181. }while(1);
  1182. }
  1183. WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
  1184. WR_HARPOON(port+hp_xferstat, 0);
  1185. WR_HARPOON(port+hp_fiforead, 0);
  1186. WR_HARPOON(port+hp_fifowrite, 0);
  1187. return(message);
  1188. }
  1189. /*---------------------------------------------------------------------
  1190.  *
  1191.  * Function: ssel
  1192.  *
  1193.  * Description: Load up automation and select target device.
  1194.  *
  1195.  *---------------------------------------------------------------------*/
  1196. #if defined(DOS)
  1197. void ssel(USHORT port, UCHAR p_card)
  1198. #else
  1199. void ssel(ULONG port, UCHAR p_card)
  1200. #endif
  1201. {
  1202. #if defined(DOS)
  1203.    UCHAR auto_loaded, i, target, *theCCB;
  1204. #elif defined(OS2)
  1205.    UCHAR auto_loaded, i, target;
  1206.    UCHAR far *theCCB;
  1207. #else
  1208.    UCHAR auto_loaded, i, target, *theCCB;
  1209. #endif
  1210. #if defined(DOS)
  1211.    USHORT cdb_reg;
  1212. #else
  1213.    ULONG cdb_reg;
  1214. #endif
  1215.    PSCCBcard CurrCard;
  1216.    PSCCB currSCCB;
  1217.    PSCCBMgr_tar_info currTar_Info;
  1218.    UCHAR lastTag, lun;
  1219.    CurrCard = &BL_Card[p_card];
  1220.    currSCCB = CurrCard->currentSCCB;
  1221.    target = currSCCB->TargID;
  1222.    currTar_Info = &sccbMgrTbl[p_card][target];
  1223.    lastTag = CurrCard->tagQ_Lst;
  1224.    ARAM_ACCESS(port);
  1225. if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
  1226. currSCCB->ControlByte &= ~F_USE_CMD_Q;
  1227. if(((CurrCard->globalFlags & F_CONLUN_IO) && 
  1228. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  1229.    lun = currSCCB->Lun;
  1230. else
  1231. lun = 0;
  1232. #if defined(DOS)
  1233.    currTar_Info->TarLUNBusy[lun] = TRUE;
  1234. #else
  1235.    if (CurrCard->globalFlags & F_TAG_STARTED)
  1236.       {
  1237.       if (!(currSCCB->ControlByte & F_USE_CMD_Q))
  1238.          {
  1239.        if ((currTar_Info->TarLUN_CA == FALSE)
  1240.            && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
  1241.            == TAG_Q_TRYING))
  1242.             {
  1243.          if (currTar_Info->TarTagQ_Cnt !=0)
  1244.                   {
  1245.              currTar_Info->TarLUNBusy[lun] = TRUE;
  1246.              queueSelectFail(CurrCard,p_card);
  1247.    SGRAM_ACCESS(port);
  1248.              return;
  1249.              }
  1250.             else {
  1251.             currTar_Info->TarLUNBusy[lun] = TRUE;
  1252.             }
  1253.           }  /*End non-tagged */
  1254.       else {
  1255.          currTar_Info->TarLUNBusy[lun] = TRUE;
  1256.          }
  1257.       }  /*!Use cmd Q Tagged */
  1258.    else {
  1259.          if (currTar_Info->TarLUN_CA == TRUE)
  1260.                {
  1261.              queueSelectFail(CurrCard,p_card);
  1262.    SGRAM_ACCESS(port);
  1263.              return;
  1264.             }
  1265.         currTar_Info->TarLUNBusy[lun] = TRUE;
  1266.          }  /*else use cmd Q tagged */
  1267.       }  /*if glob tagged started */
  1268.    else {
  1269.         currTar_Info->TarLUNBusy[lun] = TRUE;
  1270.         }
  1271. #endif /* DOS */
  1272. if((((CurrCard->globalFlags & F_CONLUN_IO) && 
  1273. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) 
  1274. || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
  1275. {
  1276. if(CurrCard->discQCount >= QUEUE_DEPTH)
  1277. {
  1278. currTar_Info->TarLUNBusy[lun] = TRUE;
  1279. queueSelectFail(CurrCard,p_card);
  1280. SGRAM_ACCESS(port);
  1281. return;
  1282. }
  1283. for (i = 1; i < QUEUE_DEPTH; i++)
  1284. {
  1285. if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
  1286. if (CurrCard->discQ_Tbl[lastTag] == NULL)
  1287. {
  1288. CurrCard->tagQ_Lst = lastTag;
  1289. currTar_Info->LunDiscQ_Idx[lun] = lastTag;
  1290. CurrCard->discQ_Tbl[lastTag] = currSCCB;
  1291. CurrCard->discQCount++;
  1292. break;
  1293. }
  1294. }
  1295. if(i == QUEUE_DEPTH)
  1296. {
  1297. currTar_Info->TarLUNBusy[lun] = TRUE;
  1298. queueSelectFail(CurrCard,p_card);
  1299. SGRAM_ACCESS(port);
  1300. return;
  1301. }
  1302. }
  1303.    auto_loaded = FALSE;
  1304.    WR_HARPOON(port+hp_select_id, target);
  1305.    WR_HARPOON(port+hp_gp_reg_3, target);  /* Use by new automation logic */
  1306.    if (currSCCB->OperationCode == RESET_COMMAND) {
  1307.       WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
  1308.                  (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
  1309.       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
  1310.       currSCCB->Sccb_scsimsg = SMDEV_RESET;
  1311.       WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
  1312.       auto_loaded = TRUE;
  1313.       currSCCB->Sccb_scsistat = SELECT_BDR_ST;
  1314.       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
  1315.          {
  1316.        currTar_Info->TarSyncCtrl = 0;
  1317.       currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
  1318.       }
  1319. #if defined(WIDE_SCSI)
  1320.       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
  1321.          {
  1322.        currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
  1323.        }
  1324. #endif
  1325.       sssyncv(port, target, NARROW_SCSI,currTar_Info);
  1326.       SccbMgrTableInitTarget(p_card, target);
  1327.       }
  1328. else if(currSCCB->Sccb_scsistat == ABORT_ST)
  1329. {
  1330. WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
  1331. (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
  1332.       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
  1333. WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
  1334. (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
  1335. >> 6) | (UCHAR)0x20)));
  1336. WRW_HARPOON((port+SYNC_MSGS+2),
  1337. (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
  1338. WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
  1339. WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
  1340. auto_loaded = TRUE;
  1341. }
  1342. #if defined(WIDE_SCSI)
  1343.    else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED))  {
  1344.       auto_loaded = siwidn(port,p_card);
  1345.       currSCCB->Sccb_scsistat = SELECT_WN_ST;
  1346.       }
  1347. #endif
  1348.    else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
  1349.       == SYNC_SUPPORTED))  {
  1350.       auto_loaded = sisyncn(port,p_card, FALSE);
  1351.       currSCCB->Sccb_scsistat = SELECT_SN_ST;
  1352.       }
  1353.    if (!auto_loaded)
  1354.       {
  1355. #if !defined(DOS)
  1356.       if (currSCCB->ControlByte & F_USE_CMD_Q)
  1357.          {
  1358.          CurrCard->globalFlags |= F_TAG_STARTED;
  1359.          if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
  1360.             == TAG_Q_REJECT)
  1361.             {
  1362.             currSCCB->ControlByte &= ~F_USE_CMD_Q;
  1363.             /* Fix up the start instruction with a jump to
  1364.                Non-Tag-CMD handling */
  1365.             WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
  1366.             WRW_HARPOON((port+NON_TAG_ID_MSG),
  1367.                      (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
  1368.          WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
  1369.          /* Setup our STATE so we know what happend when
  1370.                the wheels fall off. */
  1371.             currSCCB->Sccb_scsistat = SELECT_ST;
  1372.          currTar_Info->TarLUNBusy[lun] = TRUE;
  1373.             }
  1374.          else
  1375.             {
  1376.             WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
  1377.             WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
  1378.                         (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
  1379.                         >> 6) | (UCHAR)0x20)));
  1380. for (i = 1; i < QUEUE_DEPTH; i++)
  1381. {
  1382. if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
  1383. if (CurrCard->discQ_Tbl[lastTag] == NULL)
  1384. {
  1385. WRW_HARPOON((port+ID_MSG_STRT+6),
  1386. (MPM_OP+AMSG_OUT+lastTag));
  1387. CurrCard->tagQ_Lst = lastTag;
  1388. currSCCB->Sccb_tag = lastTag;
  1389. CurrCard->discQ_Tbl[lastTag] = currSCCB;
  1390. CurrCard->discQCount++;
  1391. break;
  1392. }
  1393. }
  1394.             if ( i == QUEUE_DEPTH )
  1395.                {
  1396.              currTar_Info->TarLUNBusy[lun] = TRUE;
  1397.                queueSelectFail(CurrCard,p_card);
  1398.    SGRAM_ACCESS(port);
  1399.              return;
  1400.              }
  1401.             currSCCB->Sccb_scsistat = SELECT_Q_ST;
  1402.           WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
  1403.             }
  1404.          }
  1405.       else
  1406.          {
  1407. #endif   /* !DOS */
  1408.          WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
  1409.        WRW_HARPOON((port+NON_TAG_ID_MSG),
  1410.             (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
  1411.          currSCCB->Sccb_scsistat = SELECT_ST;
  1412.          WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
  1413. #if !defined(DOS)
  1414.          }
  1415. #endif
  1416. #if defined(OS2)
  1417.       theCCB = (UCHAR far *)&currSCCB->Cdb[0];
  1418. #else
  1419.       theCCB = (UCHAR *)&currSCCB->Cdb[0];
  1420. #endif
  1421.       cdb_reg = port + CMD_STRT;
  1422.       for (i=0; i < currSCCB->CdbLength; i++)
  1423.          {
  1424.          WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
  1425.          cdb_reg +=2;
  1426.          theCCB++;
  1427.          }
  1428.       if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
  1429.          WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+    NP));
  1430.       }  /* auto_loaded */
  1431. #if defined(WIDE_SCSI)
  1432.    WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
  1433.    WR_HARPOON(port+hp_xferstat, 0x00);
  1434. #endif
  1435.    WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
  1436.    WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
  1437.    if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
  1438.       {
  1439.       WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
  1440.       }
  1441.    else
  1442.       {
  1443. /*      auto_loaded =  (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
  1444.       auto_loaded |= AUTO_IMMED; */
  1445.       auto_loaded = AUTO_IMMED;
  1446.       DISABLE_AUTO(port);
  1447.       WR_HARPOON(port+hp_autostart_3, auto_loaded);
  1448.       }
  1449.    SGRAM_ACCESS(port);
  1450. }
  1451. /*---------------------------------------------------------------------
  1452.  *
  1453.  * Function: sres
  1454.  *
  1455.  * Description: Hookup the correct CCB and handle the incoming messages.
  1456.  *
  1457.  *---------------------------------------------------------------------*/
  1458. #if defined(DOS)
  1459. void sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard)
  1460. #else
  1461. void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
  1462. #endif
  1463. {
  1464. #if defined(V302)
  1465. #ifdef DOS
  1466.    UCHAR our_target,message, msgRetryCount;
  1467.    extern UCHAR lun, tag;
  1468. #else
  1469.    UCHAR our_target,message,lun,tag, msgRetryCount;
  1470. #endif
  1471. #else  /* V302 */
  1472.    UCHAR our_target, message, lun = 0, tag, msgRetryCount;
  1473. #endif /* V302 */
  1474.    PSCCBMgr_tar_info currTar_Info;
  1475. PSCCB currSCCB;
  1476. if(pCurrCard->currentSCCB != NULL)
  1477. {
  1478. currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
  1479. DISABLE_AUTO(port);
  1480. WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
  1481. currSCCB = pCurrCard->currentSCCB;
  1482. if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
  1483. {
  1484. currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
  1485. currSCCB->Sccb_scsistat = BUS_FREE_ST;
  1486. }
  1487. if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
  1488. {
  1489. currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
  1490. currSCCB->Sccb_scsistat = BUS_FREE_ST;
  1491. }
  1492. if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
  1493. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  1494. {
  1495.        currTar_Info->TarLUNBusy[currSCCB->Lun] = FALSE;
  1496. if(currSCCB->Sccb_scsistat != ABORT_ST)
  1497. {
  1498. pCurrCard->discQCount--;
  1499. pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]] 
  1500. = NULL;
  1501. }
  1502. }
  1503. else
  1504. {
  1505.       currTar_Info->TarLUNBusy[0] = FALSE;
  1506. if(currSCCB->Sccb_tag)
  1507. {
  1508. if(currSCCB->Sccb_scsistat != ABORT_ST)
  1509. {
  1510. pCurrCard->discQCount--;
  1511. pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  1512. }
  1513. }else
  1514. {
  1515. if(currSCCB->Sccb_scsistat != ABORT_ST)
  1516. {
  1517. pCurrCard->discQCount--;
  1518. pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
  1519. }
  1520. }
  1521. }
  1522.       queueSelectFail(&BL_Card[p_card],p_card);
  1523. }
  1524. #if defined(WIDE_SCSI)
  1525. WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
  1526. #endif
  1527. our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
  1528. currTar_Info = &sccbMgrTbl[p_card][our_target];
  1529. msgRetryCount = 0;
  1530. do
  1531. {
  1532. #if defined(V302)
  1533. message = GetTarLun(port, p_card, our_target, pCurrCard, &tag, &lun);
  1534. #else /* V302 */
  1535. currTar_Info = &sccbMgrTbl[p_card][our_target];
  1536. tag = 0;
  1537. while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
  1538. {
  1539. if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
  1540. {
  1541. WRW_HARPOON((port+hp_intstat), PHASE);
  1542. return;
  1543. }
  1544. }
  1545. WRW_HARPOON((port+hp_intstat), PHASE);
  1546. if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
  1547. {
  1548. message = sfm(port,pCurrCard->currentSCCB);
  1549. if (message)
  1550. {
  1551. if (message <= (0x80 | LUN_MASK))
  1552. {
  1553. lun = message & (UCHAR)LUN_MASK;
  1554. #if !defined(DOS)
  1555. if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
  1556. {
  1557. if (currTar_Info->TarTagQ_Cnt != 0)
  1558. {
  1559. if (!(currTar_Info->TarLUN_CA))
  1560. {
  1561. ACCEPT_MSG(port);    /*Release the ACK for ID msg. */
  1562. message = sfm(port,pCurrCard->currentSCCB);
  1563. if (message)
  1564. {
  1565. ACCEPT_MSG(port);
  1566. }
  1567. else
  1568.     message = FALSE;
  1569. if(message != FALSE)
  1570. {
  1571. tag = sfm(port,pCurrCard->currentSCCB);
  1572. if (!(tag)) 
  1573. message = FALSE;
  1574. }
  1575. } /*C.A. exists! */
  1576. } /*End Q cnt != 0 */
  1577. } /*End Tag cmds supported! */
  1578. #endif /* !DOS */
  1579. } /*End valid ID message.  */
  1580. else
  1581. {
  1582. ACCEPT_MSG_ATN(port);
  1583. }
  1584. } /* End good id message. */
  1585. else
  1586. {
  1587. message = FALSE;
  1588. }
  1589. }
  1590. else
  1591. {
  1592. ACCEPT_MSG_ATN(port);
  1593.    while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
  1594.   !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
  1595.   (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
  1596. return;
  1597. }
  1598. #endif /* V302 */
  1599. if(message == FALSE)
  1600. {
  1601. msgRetryCount++;
  1602. if(msgRetryCount == 1)
  1603. {
  1604. SendMsg(port, SMPARITY);
  1605. }
  1606. else
  1607. {
  1608. SendMsg(port, SMDEV_RESET);
  1609. sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
  1610. if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK) 
  1611. {
  1612. sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
  1613. }
  1614. if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI) 
  1615. {
  1616. sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
  1617. }
  1618. queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
  1619. SccbMgrTableInitTarget(p_card,our_target);
  1620. return;
  1621. }
  1622. }
  1623. }while(message == FALSE);
  1624. if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
  1625. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
  1626. {
  1627. currTar_Info->TarLUNBusy[lun] = TRUE;
  1628. pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
  1629. if(pCurrCard->currentSCCB != NULL)
  1630. {
  1631. ACCEPT_MSG(port);
  1632. }
  1633. else 
  1634. {
  1635. ACCEPT_MSG_ATN(port);
  1636. }
  1637. }
  1638. else
  1639. {
  1640. currTar_Info->TarLUNBusy[0] = TRUE;
  1641. if (tag)
  1642. {
  1643. if (pCurrCard->discQ_Tbl[tag] != NULL)
  1644. {
  1645. pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
  1646.   currTar_Info->TarTagQ_Cnt--;
  1647. ACCEPT_MSG(port);
  1648. }
  1649. else
  1650. {
  1651. ACCEPT_MSG_ATN(port);
  1652. }
  1653. }else
  1654. {
  1655. pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
  1656. if(pCurrCard->currentSCCB != NULL)
  1657. {
  1658. ACCEPT_MSG(port);
  1659. }
  1660. else 
  1661. {
  1662. ACCEPT_MSG_ATN(port);
  1663. }
  1664. }
  1665. }
  1666. if(pCurrCard->currentSCCB != NULL)
  1667. {
  1668. if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
  1669. {
  1670. /* During Abort Tag command, the target could have got re-selected
  1671. and completed the command. Check the select Q and remove the CCB
  1672. if it is in the Select Q */
  1673. queueFindSccb(pCurrCard->currentSCCB, p_card);
  1674. }
  1675. }
  1676.    while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
  1677.   !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
  1678.   (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
  1679. }
  1680. #if defined(V302)
  1681. #if defined(DOS)
  1682. UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun)
  1683. #else
  1684. UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun)
  1685. #endif
  1686. {
  1687.    UCHAR message;
  1688.    PSCCBMgr_tar_info currTar_Info;
  1689. currTar_Info = &sccbMgrTbl[p_card][our_target];
  1690. *tag = 0;
  1691. while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
  1692. {
  1693. if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
  1694. {
  1695. WRW_HARPOON((port+hp_intstat), PHASE);
  1696. return(TRUE);
  1697. }
  1698. }
  1699. WRW_HARPOON((port+hp_intstat), PHASE);
  1700. if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
  1701. {
  1702. message = sfm(port,pCurrCard->currentSCCB);
  1703. if (message)
  1704. {
  1705. if (message <= (0x80 | LUN_MASK))
  1706. {
  1707. *lun = message & (UCHAR)LUN_MASK;
  1708. #if !defined(DOS)
  1709. if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
  1710. {
  1711. if (currTar_Info->TarTagQ_Cnt != 0)
  1712. {
  1713. if (!(currTar_Info->TarLUN_CA))
  1714. {
  1715. ACCEPT_MSG(port);    /*Release the ACK for ID msg. */
  1716. message = sfm(port,pCurrCard->currentSCCB);
  1717. if (message)
  1718. {
  1719. ACCEPT_MSG(port);
  1720. }
  1721. else
  1722.     return(FALSE);
  1723. *tag = sfm(port,pCurrCard->currentSCCB);
  1724. if (!(*tag)) return(FALSE);
  1725. } /*C.A. exists! */
  1726. } /*End Q cnt != 0 */
  1727. } /*End Tag cmds supported! */
  1728. #endif /* !DOS */
  1729. } /*End valid ID message.  */
  1730. else
  1731. {
  1732. ACCEPT_MSG_ATN(port);
  1733. }
  1734. } /* End good id message. */
  1735. else
  1736. {
  1737. return(FALSE);
  1738. }
  1739. }
  1740. else
  1741. {
  1742. ACCEPT_MSG_ATN(port);
  1743. return(TRUE);
  1744. }
  1745. return(TRUE);
  1746. }
  1747. #endif /* V302 */
  1748. #if defined(DOS)
  1749. void SendMsg(USHORT port, UCHAR message)
  1750. #else
  1751. void SendMsg(ULONG port, UCHAR message)
  1752. #endif
  1753. {
  1754. while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
  1755. {
  1756. if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
  1757. {
  1758. WRW_HARPOON((port+hp_intstat), PHASE);
  1759. return;
  1760. }
  1761. }
  1762. WRW_HARPOON((port+hp_intstat), PHASE);
  1763. if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
  1764. {
  1765. WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
  1766. WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
  1767. WR_HARPOON(port+hp_scsidata_0,message);
  1768. WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
  1769. ACCEPT_MSG(port);
  1770. WR_HARPOON(port+hp_portctrl_0, 0x00);
  1771. if ((message == SMABORT) || (message == SMDEV_RESET) ||
  1772. (message == SMABORT_TAG) )
  1773. {
  1774. while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
  1775. if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
  1776. {
  1777. WRW_HARPOON((port+hp_intstat), BUS_FREE);
  1778. }
  1779. }
  1780. }
  1781. }
  1782. /*---------------------------------------------------------------------
  1783.  *
  1784.  * Function: sdecm
  1785.  *
  1786.  * Description: Determine the proper responce to the message from the
  1787.  *              target device.
  1788.  *
  1789.  *---------------------------------------------------------------------*/
  1790. #if defined(DOS)
  1791. void sdecm(UCHAR message, USHORT port, UCHAR p_card)
  1792. #else
  1793. void sdecm(UCHAR message, ULONG port, UCHAR p_card)
  1794. #endif
  1795. {
  1796. PSCCB currSCCB;
  1797. PSCCBcard CurrCard;
  1798. PSCCBMgr_tar_info currTar_Info;
  1799. CurrCard = &BL_Card[p_card];
  1800. currSCCB = CurrCard->currentSCCB;
  1801. currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
  1802. if (message == SMREST_DATA_PTR)
  1803. {
  1804. if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
  1805. {
  1806. currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
  1807. hostDataXferRestart(currSCCB);
  1808. }
  1809. ACCEPT_MSG(port);
  1810. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1811. }
  1812. else if (message == SMCMD_COMP)
  1813. {
  1814. if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
  1815. {
  1816. currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
  1817. currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
  1818. }
  1819. ACCEPT_MSG(port);
  1820. }
  1821. else if ((message == SMNO_OP) || (message >= SMIDENT) 
  1822. || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
  1823. {
  1824. ACCEPT_MSG(port);
  1825. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1826. }
  1827. else if (message == SMREJECT)
  1828. {
  1829. if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
  1830. (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
  1831. ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
  1832. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
  1833. {
  1834. WRW_HARPOON((port+hp_intstat), BUS_FREE);
  1835. ACCEPT_MSG(port);
  1836. while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
  1837. (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
  1838. if(currSCCB->Lun == 0x00)
  1839. {
  1840. if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
  1841. {
  1842. currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
  1843. currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
  1844. }
  1845. #if defined(WIDE_SCSI)
  1846. else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
  1847. {
  1848. currTar_Info->TarStatus = (currTar_Info->TarStatus &
  1849. ~WIDE_ENABLED) | WIDE_NEGOCIATED;
  1850. currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
  1851. }
  1852. #endif
  1853. else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
  1854. {
  1855. currTar_Info->TarStatus = (currTar_Info->TarStatus &
  1856. ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
  1857. currSCCB->ControlByte &= ~F_USE_CMD_Q;
  1858. CurrCard->discQCount--;
  1859. CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  1860. currSCCB->Sccb_tag = 0x00;
  1861. }
  1862. }
  1863. if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
  1864. {
  1865. if(currSCCB->Lun == 0x00)
  1866. {
  1867. WRW_HARPOON((port+hp_intstat), BUS_FREE);
  1868. CurrCard->globalFlags |= F_NEW_SCCB_CMD;
  1869. }
  1870. }
  1871. else 
  1872. {
  1873. if((CurrCard->globalFlags & F_CONLUN_IO) &&
  1874. ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  1875. currTar_Info->TarLUNBusy[currSCCB->Lun] = TRUE;
  1876. else
  1877. currTar_Info->TarLUNBusy[0] = TRUE;
  1878. currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
  1879. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1880. }
  1881. }
  1882. else
  1883. {
  1884. ACCEPT_MSG(port);
  1885. while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
  1886. (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
  1887. if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
  1888. {
  1889. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1890. }
  1891. }
  1892. }
  1893. else if (message == SMEXT)
  1894. {
  1895. ACCEPT_MSG(port);
  1896. shandem(port,p_card,currSCCB);
  1897. }
  1898. else if (message == SMIGNORWR)
  1899. {
  1900. ACCEPT_MSG(port);          /* ACK the RESIDUE MSG */
  1901. message = sfm(port,currSCCB);
  1902. if(currSCCB->Sccb_scsimsg != SMPARITY)
  1903. ACCEPT_MSG(port);
  1904. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1905. }
  1906. else
  1907. {
  1908. currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
  1909. currSCCB->Sccb_scsimsg = SMREJECT;
  1910. ACCEPT_MSG_ATN(port);
  1911. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1912. }
  1913. }
  1914. /*---------------------------------------------------------------------
  1915.  *
  1916.  * Function: shandem
  1917.  *
  1918.  * Description: Decide what to do with the extended message.
  1919.  *
  1920.  *---------------------------------------------------------------------*/
  1921. #if defined(DOS)
  1922. void shandem(USHORT port, UCHAR p_card, PSCCB pCurrSCCB)
  1923. #else
  1924. void shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
  1925. #endif
  1926. {
  1927. UCHAR length,message;
  1928. length = sfm(port,pCurrSCCB);
  1929. if (length) 
  1930. {
  1931. ACCEPT_MSG(port);
  1932. message = sfm(port,pCurrSCCB);
  1933. if (message) 
  1934. {
  1935. if (message == SMSYNC) 
  1936. {
  1937. if (length == 0x03)
  1938. {
  1939. ACCEPT_MSG(port);
  1940. stsyncn(port,p_card);
  1941. }
  1942. else 
  1943. {
  1944. pCurrSCCB->Sccb_scsimsg = SMREJECT;
  1945. ACCEPT_MSG_ATN(port);
  1946. }
  1947. }
  1948. #if defined(WIDE_SCSI)
  1949. else if (message == SMWDTR) 
  1950. {
  1951. if (length == 0x02)
  1952. {
  1953. ACCEPT_MSG(port);
  1954. stwidn(port,p_card);
  1955. }
  1956. else 
  1957. {
  1958. pCurrSCCB->Sccb_scsimsg = SMREJECT;
  1959. ACCEPT_MSG_ATN(port);
  1960. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1961. }
  1962. }
  1963. #endif
  1964. else 
  1965. {
  1966. pCurrSCCB->Sccb_scsimsg = SMREJECT;
  1967. ACCEPT_MSG_ATN(port);
  1968. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1969. }
  1970. }
  1971. else
  1972. {
  1973. if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
  1974. ACCEPT_MSG(port);
  1975. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1976. }
  1977. }else
  1978. {
  1979. if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
  1980. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  1981. }
  1982. }
  1983. /*---------------------------------------------------------------------
  1984.  *
  1985.  * Function: sisyncn
  1986.  *
  1987.  * Description: Read in a message byte from the SCSI bus, and check
  1988.  *              for a parity error.
  1989.  *
  1990.  *---------------------------------------------------------------------*/
  1991. #if defined(DOS)
  1992. UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag)
  1993. #else
  1994. UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
  1995. #endif
  1996. {
  1997.    PSCCB currSCCB;
  1998.    PSCCBMgr_tar_info currTar_Info;
  1999.    currSCCB = BL_Card[p_card].currentSCCB;
  2000.    currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
  2001.    if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
  2002.       WRW_HARPOON((port+ID_MSG_STRT),
  2003.                  (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
  2004.       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
  2005.       WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
  2006.       WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03  ));
  2007.       WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
  2008.       if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
  2009.  WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
  2010.       else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
  2011.  WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
  2012.       else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
  2013.  WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
  2014.       else
  2015.  WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
  2016.       WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP                ));
  2017.       WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
  2018.       WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP      ));
  2019. if(syncFlag == FALSE)
  2020. {
  2021.    WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
  2022.       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
  2023.           ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
  2024. }
  2025. else
  2026. {
  2027.    WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
  2028. }
  2029.       return(TRUE);
  2030.       }
  2031.    else {
  2032.       currTar_Info->TarStatus |=  (UCHAR)SYNC_SUPPORTED;
  2033.       currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
  2034.       return(FALSE);
  2035.       }
  2036. }
  2037. /*---------------------------------------------------------------------
  2038.  *
  2039.  * Function: stsyncn
  2040.  *
  2041.  * Description: The has sent us a Sync Nego message so handle it as
  2042.  *              necessary.
  2043.  *
  2044.  *---------------------------------------------------------------------*/
  2045. #if defined(DOS)
  2046. void stsyncn(USHORT port, UCHAR p_card)
  2047. #else
  2048. void stsyncn(ULONG port, UCHAR p_card)
  2049. #endif
  2050. {
  2051.    UCHAR sync_msg,offset,sync_reg,our_sync_msg;
  2052.    PSCCB currSCCB;
  2053.    PSCCBMgr_tar_info currTar_Info;
  2054.    currSCCB = BL_Card[p_card].currentSCCB;
  2055.    currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
  2056.    sync_msg = sfm(port,currSCCB);
  2057. if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
  2058. {
  2059. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  2060. return;
  2061. }
  2062.    ACCEPT_MSG(port);
  2063.    offset = sfm(port,currSCCB);
  2064. if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
  2065. {
  2066. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  2067. return;
  2068. }
  2069.    if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
  2070.       our_sync_msg = 12;              /* Setup our Message to 20mb/s */
  2071.    else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
  2072.       our_sync_msg = 25;              /* Setup our Message to 10mb/s */
  2073.    else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
  2074.       our_sync_msg = 50;              /* Setup our Message to 5mb/s */
  2075.    else
  2076.       our_sync_msg = 0;               /* Message = Async */
  2077.    if (sync_msg < our_sync_msg) {
  2078.       sync_msg = our_sync_msg;    /*if faster, then set to max. */
  2079.       }
  2080.    if (offset == ASYNC)
  2081.       sync_msg = ASYNC;
  2082.    if (offset > MAX_OFFSET)
  2083.       offset = MAX_OFFSET;
  2084.    sync_reg = 0x00;
  2085.    if (sync_msg > 12)
  2086.       sync_reg = 0x20;        /* Use 10MB/s */
  2087.    if (sync_msg > 25)
  2088.       sync_reg = 0x40;        /* Use 6.6MB/s */
  2089.    if (sync_msg > 38)
  2090.       sync_reg = 0x60;        /* Use 5MB/s */
  2091.    if (sync_msg > 50)
  2092.       sync_reg = 0x80;        /* Use 4MB/s */
  2093.    if (sync_msg > 62)
  2094.       sync_reg = 0xA0;        /* Use 3.33MB/s */
  2095.    if (sync_msg > 75)
  2096.       sync_reg = 0xC0;        /* Use 2.85MB/s */
  2097.    if (sync_msg > 87)
  2098.       sync_reg = 0xE0;        /* Use 2.5MB/s */
  2099.    if (sync_msg > 100) {
  2100.       sync_reg = 0x00;        /* Use ASYNC */
  2101.       offset = 0x00;
  2102.       }
  2103. #if defined(WIDE_SCSI)
  2104.    if (currTar_Info->TarStatus & WIDE_ENABLED)
  2105.       sync_reg |= offset;
  2106.    else
  2107.       sync_reg |= (offset | NARROW_SCSI);
  2108. #else
  2109.    sync_reg |= (offset | NARROW_SCSI);
  2110. #endif
  2111.    sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
  2112.    if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
  2113.       ACCEPT_MSG(port);
  2114.       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
  2115.          ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
  2116.       WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  2117.       }
  2118.    else {
  2119.       ACCEPT_MSG_ATN(port);
  2120.       sisyncr(port,sync_msg,offset);
  2121.       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
  2122.          ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
  2123.       }
  2124. }
  2125. /*---------------------------------------------------------------------
  2126.  *
  2127.  * Function: sisyncr
  2128.  *
  2129.  * Description: Answer the targets sync message.
  2130.  *
  2131.  *---------------------------------------------------------------------*/
  2132. #if defined(DOS)
  2133. void sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset)
  2134. #else
  2135. void sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
  2136. #endif
  2137. {
  2138.    ARAM_ACCESS(port);
  2139.    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
  2140.    WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03  ));
  2141.    WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
  2142.    WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
  2143.    WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP                ));
  2144.    WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
  2145.    WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP      ));
  2146.    SGRAM_ACCESS(port);
  2147.    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
  2148.    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
  2149.    WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
  2150.    while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
  2151. }
  2152. #if defined(WIDE_SCSI)
  2153. /*---------------------------------------------------------------------
  2154.  *
  2155.  * Function: siwidn
  2156.  *
  2157.  * Description: Read in a message byte from the SCSI bus, and check
  2158.  *              for a parity error.
  2159.  *
  2160.  *---------------------------------------------------------------------*/
  2161. #if defined(DOS)
  2162. UCHAR siwidn(USHORT port, UCHAR p_card)
  2163. #else
  2164. UCHAR siwidn(ULONG port, UCHAR p_card)
  2165. #endif
  2166. {
  2167.    PSCCB currSCCB;
  2168.    PSCCBMgr_tar_info currTar_Info;
  2169.    currSCCB = BL_Card[p_card].currentSCCB;
  2170.    currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
  2171.    if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
  2172.       WRW_HARPOON((port+ID_MSG_STRT),
  2173.               (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
  2174.       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
  2175.       WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
  2176.       WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02  ));
  2177.       WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
  2178.       WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP                ));
  2179.       WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
  2180.       WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP      ));
  2181.       WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
  2182.       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
  2183.          ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
  2184.       return(TRUE);
  2185.       }
  2186.    else {
  2187.       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
  2188.                ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
  2189.       currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
  2190.       return(FALSE);
  2191.       }
  2192. }
  2193. /*---------------------------------------------------------------------
  2194.  *
  2195.  * Function: stwidn
  2196.  *
  2197.  * Description: The has sent us a Wide Nego message so handle it as
  2198.  *              necessary.
  2199.  *
  2200.  *---------------------------------------------------------------------*/
  2201. #if defined(DOS)
  2202. void stwidn(USHORT port, UCHAR p_card)
  2203. #else
  2204. void stwidn(ULONG port, UCHAR p_card)
  2205. #endif
  2206. {
  2207.    UCHAR width;
  2208.    PSCCB currSCCB;
  2209.    PSCCBMgr_tar_info currTar_Info;
  2210.    currSCCB = BL_Card[p_card].currentSCCB;
  2211.    currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
  2212.    width = sfm(port,currSCCB);
  2213. if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
  2214. {
  2215. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  2216. return;
  2217. }
  2218.    if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
  2219.       width = 0;
  2220.    if (width) {
  2221.       currTar_Info->TarStatus |= WIDE_ENABLED;
  2222.       width = 0;
  2223.       }
  2224.    else {
  2225.       width = NARROW_SCSI;
  2226.       currTar_Info->TarStatus &= ~WIDE_ENABLED;
  2227.       }
  2228.    sssyncv(port,currSCCB->TargID,width,currTar_Info);
  2229.    if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
  2230. {
  2231.       currTar_Info->TarStatus |=  WIDE_NEGOCIATED;
  2232.    if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
  2233. {
  2234.       ACCEPT_MSG_ATN(port);
  2235.    ARAM_ACCESS(port);
  2236.       sisyncn(port,p_card, TRUE);
  2237.       currSCCB->Sccb_scsistat = SELECT_SN_ST;
  2238.    SGRAM_ACCESS(port);
  2239. }
  2240. else
  2241. {
  2242.       ACCEPT_MSG(port);
  2243.       WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  2244. }
  2245.    }
  2246.    else {
  2247.       ACCEPT_MSG_ATN(port);
  2248.       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
  2249.         width = SM16BIT;
  2250.       else
  2251.         width = SM8BIT;
  2252.       siwidr(port,width);
  2253.       currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
  2254.       }
  2255. }
  2256. /*---------------------------------------------------------------------
  2257.  *
  2258.  * Function: siwidr
  2259.  *
  2260.  * Description: Answer the targets Wide nego message.
  2261.  *
  2262.  *---------------------------------------------------------------------*/
  2263. #if defined(DOS)
  2264. void siwidr(USHORT port, UCHAR width)
  2265. #else
  2266. void siwidr(ULONG port, UCHAR width)
  2267. #endif
  2268. {
  2269.    ARAM_ACCESS(port);
  2270.    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
  2271.    WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02  ));
  2272.    WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
  2273.    WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP                ));
  2274.    WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
  2275.    WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP      ));
  2276.    SGRAM_ACCESS(port);
  2277.    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
  2278.    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
  2279.    WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
  2280.    while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
  2281. }
  2282. #endif
  2283. /*---------------------------------------------------------------------
  2284.  *
  2285.  * Function: sssyncv
  2286.  *
  2287.  * Description: Write the desired value to the Sync Register for the
  2288.  *              ID specified.
  2289.  *
  2290.  *---------------------------------------------------------------------*/
  2291. #if defined(DOS)
  2292. void sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info)
  2293. #else
  2294. void sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info)
  2295. #endif
  2296. {
  2297.    UCHAR index;
  2298.    index = p_id;
  2299.    switch (index) {
  2300.       case 0:
  2301.  index = 12;             /* hp_synctarg_0 */
  2302.  break;
  2303.       case 1:
  2304.  index = 13;             /* hp_synctarg_1 */
  2305.  break;
  2306.       case 2:
  2307.  index = 14;             /* hp_synctarg_2 */
  2308.  break;
  2309.       case 3:
  2310.  index = 15;             /* hp_synctarg_3 */
  2311.  break;
  2312.       case 4:
  2313.  index = 8;              /* hp_synctarg_4 */
  2314.  break;
  2315.       case 5:
  2316.  index = 9;              /* hp_synctarg_5 */
  2317.  break;
  2318.       case 6:
  2319.  index = 10;             /* hp_synctarg_6 */
  2320.  break;
  2321.       case 7:
  2322.  index = 11;             /* hp_synctarg_7 */
  2323.  break;
  2324.       case 8:
  2325.  index = 4;              /* hp_synctarg_8 */
  2326.  break;
  2327.       case 9:
  2328.  index = 5;              /* hp_synctarg_9 */
  2329.  break;
  2330.       case 10:
  2331.  index = 6;              /* hp_synctarg_10 */
  2332.  break;
  2333.       case 11:
  2334.  index = 7;              /* hp_synctarg_11 */
  2335.  break;
  2336.       case 12:
  2337.  index = 0;              /* hp_synctarg_12 */
  2338.  break;
  2339.       case 13:
  2340.  index = 1;              /* hp_synctarg_13 */
  2341.  break;
  2342.       case 14:
  2343.  index = 2;              /* hp_synctarg_14 */
  2344.  break;
  2345.       case 15:
  2346.  index = 3;              /* hp_synctarg_15 */
  2347.       }
  2348.    WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
  2349. currTar_Info->TarSyncCtrl = p_sync_value;
  2350. }
  2351. /*---------------------------------------------------------------------
  2352.  *
  2353.  * Function: sresb
  2354.  *
  2355.  * Description: Reset the desired card's SCSI bus.
  2356.  *
  2357.  *---------------------------------------------------------------------*/
  2358. #if defined(DOS)
  2359. void sresb(USHORT port, UCHAR p_card)
  2360. #else
  2361. void sresb(ULONG port, UCHAR p_card)
  2362. #endif
  2363. {
  2364.    UCHAR scsiID, i;
  2365.    PSCCBMgr_tar_info currTar_Info;
  2366.    WR_HARPOON(port+hp_page_ctrl,
  2367.       (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
  2368.    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
  2369.    WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
  2370.    scsiID = RD_HARPOON(port+hp_seltimeout);
  2371.    WR_HARPOON(port+hp_seltimeout,TO_5ms);
  2372.    WRW_HARPOON((port+hp_intstat), TIMEOUT);
  2373.    WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
  2374.    while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
  2375.    WR_HARPOON(port+hp_seltimeout,scsiID);
  2376.    WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
  2377.    Wait(port, TO_5ms);
  2378.    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
  2379.    WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
  2380.    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
  2381.       {
  2382.       currTar_Info = &sccbMgrTbl[p_card][scsiID];
  2383.       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
  2384.          {
  2385.        currTar_Info->TarSyncCtrl = 0;
  2386.        currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
  2387.       }
  2388.       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
  2389.          {
  2390.        currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
  2391.        }
  2392.       sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
  2393.       SccbMgrTableInitTarget(p_card, scsiID);
  2394.       }
  2395.    BL_Card[p_card].scanIndex = 0x00;
  2396.    BL_Card[p_card].currentSCCB = NULL;
  2397.    BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT 
  2398. | F_NEW_SCCB_CMD);
  2399.    BL_Card[p_card].cmdCounter  = 0x00;
  2400. BL_Card[p_card].discQCount = 0x00;
  2401.    BL_Card[p_card].tagQ_Lst = 0x01; 
  2402. for(i = 0; i < QUEUE_DEPTH; i++)
  2403. BL_Card[p_card].discQ_Tbl[i] = NULL;
  2404.    WR_HARPOON(port+hp_page_ctrl,
  2405.       (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
  2406. }
  2407. /*---------------------------------------------------------------------
  2408.  *
  2409.  * Function: ssenss
  2410.  *
  2411.  * Description: Setup for the Auto Sense command.
  2412.  *
  2413.  *---------------------------------------------------------------------*/
  2414. void ssenss(PSCCBcard pCurrCard)
  2415. {
  2416.    UCHAR i;
  2417.    PSCCB currSCCB;
  2418.    currSCCB = pCurrCard->currentSCCB;
  2419.    currSCCB->Save_CdbLen = currSCCB->CdbLength;
  2420.    for (i = 0; i < 6; i++) {
  2421.       currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
  2422.       }
  2423.    currSCCB->CdbLength = SIX_BYTE_CMD;
  2424.    currSCCB->Cdb[0]    = SCSI_REQUEST_SENSE;
  2425.    currSCCB->Cdb[1]    = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
  2426.    currSCCB->Cdb[2]    = 0x00;
  2427.    currSCCB->Cdb[3]    = 0x00;
  2428.    currSCCB->Cdb[4]    = currSCCB->RequestSenseLength;
  2429.    currSCCB->Cdb[5]    = 0x00;
  2430.    currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
  2431.    currSCCB->Sccb_ATC = 0x00;
  2432.    currSCCB->Sccb_XferState |= F_AUTO_SENSE;
  2433.    currSCCB->Sccb_XferState &= ~F_SG_XFER;
  2434.    currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
  2435.    currSCCB->ControlByte = 0x00;
  2436.    currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
  2437. }
  2438. /*---------------------------------------------------------------------
  2439.  *
  2440.  * Function: sxfrp
  2441.  *
  2442.  * Description: Transfer data into the bit bucket until the device
  2443.  *              decides to switch phase.
  2444.  *
  2445.  *---------------------------------------------------------------------*/
  2446. #if defined(DOS)
  2447. void sxfrp(USHORT p_port, UCHAR p_card)
  2448. #else
  2449. void sxfrp(ULONG p_port, UCHAR p_card)
  2450. #endif
  2451. {
  2452.    UCHAR curr_phz;
  2453.    DISABLE_AUTO(p_port);
  2454.    if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
  2455.       hostDataXferAbort(p_port,p_card,BL_Card[p_card].currentSCCB);
  2456.       }
  2457.    /* If the Automation handled the end of the transfer then do not
  2458.       match the phase or we will get out of sync with the ISR.       */
  2459.    if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
  2460.       return;
  2461.    WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
  2462.    curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
  2463.    WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
  2464.    WR_HARPOON(p_port+hp_scsisig, curr_phz);
  2465.    while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
  2466.       (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
  2467.       {
  2468.       if (curr_phz & (UCHAR)SCSI_IOBIT)
  2469.          {
  2470.        WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
  2471.       if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
  2472.             {
  2473.          RD_HARPOON(p_port+hp_fifodata_0);
  2474.          }
  2475.       }
  2476.       else
  2477.          {
  2478.        WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
  2479.        if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
  2480.             {
  2481.          WR_HARPOON(p_port+hp_fifodata_0,0xFA);
  2482.          }
  2483.       }
  2484.       } /* End of While loop for padding data I/O phase */
  2485.       while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
  2486.          {
  2487.          if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
  2488.           break;
  2489.          }
  2490.       WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
  2491.       while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
  2492.          {
  2493.          RD_HARPOON(p_port+hp_fifodata_0);
  2494.          }
  2495.       if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
  2496.          {
  2497.          WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
  2498.          while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
  2499.          if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
  2500.        while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
  2501.          }
  2502. }
  2503. /*---------------------------------------------------------------------
  2504.  *
  2505.  * Function: schkdd
  2506.  *
  2507.  * Description: Make sure data has been flushed from both FIFOs and abort
  2508.  *              the operations if necessary.
  2509.  *
  2510.  *---------------------------------------------------------------------*/
  2511. #if defined(DOS)
  2512. void schkdd(USHORT port, UCHAR p_card)
  2513. #else
  2514. void schkdd(ULONG port, UCHAR p_card)
  2515. #endif
  2516. {
  2517.    USHORT TimeOutLoop;
  2518. UCHAR sPhase;
  2519.    PSCCB currSCCB;
  2520.    currSCCB = BL_Card[p_card].currentSCCB;
  2521.    if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
  2522.        (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
  2523.       return;
  2524.       }
  2525.    if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
  2526.       {
  2527.       currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
  2528.       currSCCB->Sccb_XferCnt = 1;
  2529.       currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
  2530.       WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
  2531.       WR_HARPOON(port+hp_xferstat, 0x00);
  2532.       }
  2533.    else
  2534.       {
  2535.       currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
  2536.       currSCCB->Sccb_XferCnt = 0;
  2537.       }
  2538.    if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
  2539.       (currSCCB->HostStatus == SCCB_COMPLETE)) {
  2540.       currSCCB->HostStatus = SCCB_PARITY_ERR;
  2541.       WRW_HARPOON((port+hp_intstat), PARITY);
  2542.       }
  2543.    hostDataXferAbort(port,p_card,currSCCB);
  2544.    while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
  2545.    TimeOutLoop = 0;
  2546.    while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
  2547.       {
  2548.       if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
  2549.       return;
  2550.        }
  2551.       if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
  2552.       break;
  2553.        }
  2554.       if (RDW_HARPOON((port+hp_intstat)) & RESET) {
  2555.       return;
  2556.        }
  2557.       if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
  2558.        break;
  2559.       }
  2560. sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
  2561.    if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))                     ||
  2562.       (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F)                       ||
  2563.       (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
  2564.       (sPhase == (SCSI_BSY | S_DATAI_PH)))
  2565.       {
  2566.    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
  2567.    if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
  2568.          {
  2569.       if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
  2570.          phaseDataIn(port,p_card);
  2571.        }
  2572.     else {
  2573.        phaseDataOut(port,p_card);
  2574.         }
  2575.     }
  2576. else
  2577.        {
  2578.     sxfrp(port,p_card);
  2579.     if (!(RDW_HARPOON((port+hp_intstat)) &
  2580.       (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
  2581.          {
  2582.     WRW_HARPOON((port+hp_intstat), AUTO_INT);
  2583.    phaseDecode(port,p_card);
  2584.    }
  2585.    }
  2586.    }
  2587.    else {
  2588.       WR_HARPOON(port+hp_portctrl_0, 0x00);
  2589.       }
  2590. }
  2591. /*---------------------------------------------------------------------
  2592.  *
  2593.  * Function: sinits
  2594.  *
  2595.  * Description: Setup SCCB manager fields in this SCCB.
  2596.  *
  2597.  *---------------------------------------------------------------------*/
  2598. void sinits(PSCCB p_sccb, UCHAR p_card)
  2599. {
  2600.    PSCCBMgr_tar_info currTar_Info;
  2601. if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
  2602. {
  2603. return;
  2604. }
  2605.    currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
  2606.    p_sccb->Sccb_XferState     = 0x00;
  2607.    p_sccb->Sccb_XferCnt       = p_sccb->DataLength;
  2608.    if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
  2609.       (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
  2610.       p_sccb->Sccb_SGoffset   = 0;
  2611.       p_sccb->Sccb_XferState  = F_SG_XFER;
  2612.       p_sccb->Sccb_XferCnt    = 0x00;
  2613.       }
  2614.    if (p_sccb->DataLength == 0x00)
  2615.       p_sccb->Sccb_XferState |= F_ALL_XFERRED;
  2616.    if (p_sccb->ControlByte & F_USE_CMD_Q)
  2617.       {
  2618.       if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
  2619.          p_sccb->ControlByte &= ~F_USE_CMD_Q;
  2620.       else
  2621.       currTar_Info->TarStatus |= TAG_Q_TRYING;
  2622.       }
  2623. /*      For !single SCSI device in system  & device allow Disconnect
  2624. or command is tag_q type then send Cmd with Disconnect Enable
  2625. else send Cmd with Disconnect Disable */
  2626. /*
  2627.    if (((!(BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
  2628.       (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
  2629.       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
  2630. */
  2631.    if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
  2632.       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
  2633.       p_sccb->Sccb_idmsg      = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
  2634.       }
  2635.    else {
  2636.       p_sccb->Sccb_idmsg      = (UCHAR)SMIDENT | p_sccb->Lun;
  2637.       }
  2638.    p_sccb->HostStatus         = 0x00;
  2639.    p_sccb->TargetStatus       = 0x00;
  2640.    p_sccb->Sccb_tag           = 0x00;
  2641.    p_sccb->Sccb_MGRFlags      = 0x00;
  2642.    p_sccb->Sccb_sgseg         = 0x00;
  2643.    p_sccb->Sccb_ATC           = 0x00;
  2644.    p_sccb->Sccb_savedATC      = 0x00;
  2645. /*
  2646.    p_sccb->SccbVirtDataPtr    = 0x00;
  2647.    p_sccb->Sccb_forwardlink   = NULL;
  2648.    p_sccb->Sccb_backlink      = NULL;
  2649.  */
  2650.    p_sccb->Sccb_scsistat      = BUS_FREE_ST;
  2651.    p_sccb->SccbStatus         = SCCB_IN_PROCESS;
  2652.    p_sccb->Sccb_scsimsg       = SMNO_OP;
  2653. }
  2654. #ident "$Id: phase.c 1.11 1997/01/31 02:08:49 mohan Exp $"
  2655. /*----------------------------------------------------------------------
  2656.  *
  2657.  *
  2658.  *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  2659.  *
  2660.  *   This file is available under both the GNU General Public License
  2661.  *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  2662.  *
  2663.  *   $Workfile:   phase.c  $
  2664.  *
  2665.  *   Description:  Functions to intially handle the SCSI bus phase when
  2666.  *                 the target asserts request (and the automation is not
  2667.  *                 enabled to handle the situation).
  2668.  *
  2669.  *   $Date: 1997/01/31 02:08:49 $
  2670.  *
  2671.  *   $Revision: 1.11 $
  2672.  *
  2673.  *----------------------------------------------------------------------*/
  2674. /*#include <globals.h>*/
  2675. #if (FW_TYPE==_UCB_MGR_)
  2676. /*#include <budi.h>*/
  2677. #endif
  2678. /*#include <sccbmgr.h>*/
  2679. /*#include <blx30.h>*/
  2680. /*#include <target.h>*/
  2681. /*#include <scsi2.h>*/
  2682. /*#include <harpoon.h>*/
  2683. /*
  2684. extern SCCBCARD BL_Card[MAX_CARDS];
  2685. extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  2686. #if defined(OS2)
  2687.    extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
  2688. #else
  2689.    #if defined(DOS)
  2690.       extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
  2691.    #else
  2692.       extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
  2693.    #endif
  2694. #endif
  2695. */
  2696. /*---------------------------------------------------------------------
  2697.  *
  2698.  * Function: Phase Decode
  2699.  *
  2700.  * Description: Determine the phase and call the appropriate function.
  2701.  *
  2702.  *---------------------------------------------------------------------*/
  2703. #if defined(DOS)
  2704. void phaseDecode(USHORT p_port, UCHAR p_card)
  2705. #else
  2706. void phaseDecode(ULONG p_port, UCHAR p_card)
  2707. #endif
  2708. {
  2709.    unsigned char phase_ref;
  2710. #if defined(OS2)
  2711.    void (far *phase) (ULONG, UCHAR);
  2712. #else
  2713.    #if defined(DOS)
  2714.       void (*phase) (USHORT, UCHAR);
  2715.    #else
  2716.       void (*phase) (ULONG, UCHAR);
  2717.    #endif
  2718. #endif
  2719.    DISABLE_AUTO(p_port);
  2720.    phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
  2721.    phase = s_PhaseTbl[phase_ref];
  2722.    (*phase)(p_port, p_card);           /* Call the correct phase func */
  2723. }
  2724. /*---------------------------------------------------------------------
  2725.  *
  2726.  * Function: Data Out Phase
  2727.  *
  2728.  * Description: Start up both the BusMaster and Xbow.
  2729.  *
  2730.  *---------------------------------------------------------------------*/
  2731. #if defined(OS2)
  2732. void far phaseDataOut(ULONG port, UCHAR p_card)
  2733. #else
  2734. #if defined(DOS)
  2735. void phaseDataOut(USHORT port, UCHAR p_card)
  2736. #else
  2737. void phaseDataOut(ULONG port, UCHAR p_card)
  2738. #endif
  2739. #endif
  2740. {
  2741.    PSCCB currSCCB;
  2742.    currSCCB = BL_Card[p_card].currentSCCB;
  2743.    if (currSCCB == NULL)
  2744.       {
  2745.       return;  /* Exit if No SCCB record */
  2746.       }
  2747.    currSCCB->Sccb_scsistat = DATA_OUT_ST;
  2748.    currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
  2749.    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
  2750.    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
  2751.    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
  2752.    dataXferProcessor(port, &BL_Card[p_card]);
  2753. #if defined(NOBUGBUG)
  2754.    if (RDW_HARPOON((port+hp_intstat)) & XFER_CNT_0)
  2755.       WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
  2756. #endif
  2757.    if (currSCCB->Sccb_XferCnt == 0) {
  2758.       if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
  2759.  (currSCCB->HostStatus == SCCB_COMPLETE))
  2760.  currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
  2761.       sxfrp(port,p_card);
  2762.       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
  2763.     phaseDecode(port,p_card);
  2764.       }
  2765. }
  2766. /*---------------------------------------------------------------------
  2767.  *
  2768.  * Function: Data In Phase
  2769.  *
  2770.  * Description: Startup the BusMaster and the XBOW.
  2771.  *
  2772.  *---------------------------------------------------------------------*/
  2773. #if defined(OS2)
  2774. void far phaseDataIn(ULONG port, UCHAR p_card)
  2775. #else
  2776. #if defined(DOS)
  2777. void phaseDataIn(USHORT port, UCHAR p_card)
  2778. #else
  2779. void phaseDataIn(ULONG port, UCHAR p_card)
  2780. #endif
  2781. #endif
  2782. {
  2783.    PSCCB currSCCB;
  2784.    currSCCB = BL_Card[p_card].currentSCCB;
  2785.    if (currSCCB == NULL)
  2786.       {
  2787.       return;  /* Exit if No SCCB record */
  2788.       }
  2789.    currSCCB->Sccb_scsistat = DATA_IN_ST;
  2790.    currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
  2791.    currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
  2792.    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
  2793.    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
  2794.    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
  2795.    dataXferProcessor(port, &BL_Card[p_card]);
  2796.    if (currSCCB->Sccb_XferCnt == 0) {
  2797.       if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
  2798.  (currSCCB->HostStatus == SCCB_COMPLETE))
  2799.  currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
  2800.       sxfrp(port,p_card);
  2801.       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
  2802.     phaseDecode(port,p_card);
  2803.       }
  2804. }
  2805. /*---------------------------------------------------------------------
  2806.  *
  2807.  * Function: Command Phase
  2808.  *
  2809.  * Description: Load the CDB into the automation and start it up.
  2810.  *
  2811.  *---------------------------------------------------------------------*/
  2812. #if defined(OS2)
  2813. void far phaseCommand(ULONG p_port, UCHAR p_card)
  2814. #else
  2815. #if defined(DOS)
  2816. void phaseCommand(USHORT p_port, UCHAR p_card)
  2817. #else
  2818. void phaseCommand(ULONG p_port, UCHAR p_card)
  2819. #endif
  2820. #endif
  2821. {
  2822.    PSCCB currSCCB;
  2823. #if defined(DOS)
  2824.    USHORT cdb_reg;
  2825. #else
  2826.    ULONG cdb_reg;
  2827. #endif
  2828.    UCHAR i;
  2829.    currSCCB = BL_Card[p_card].currentSCCB;
  2830.    if (currSCCB->OperationCode == RESET_COMMAND) {
  2831.       currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
  2832.       currSCCB->CdbLength = SIX_BYTE_CMD;
  2833.       }
  2834.    WR_HARPOON(p_port+hp_scsisig, 0x00);
  2835.    ARAM_ACCESS(p_port);
  2836.    cdb_reg = p_port + CMD_STRT;
  2837.    for (i=0; i < currSCCB->CdbLength; i++) {
  2838.       if (currSCCB->OperationCode == RESET_COMMAND)
  2839.  WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
  2840.       else
  2841.  WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
  2842.       cdb_reg +=2;
  2843.       }
  2844.    if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
  2845.       WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+    NP));
  2846.    WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
  2847.    currSCCB->Sccb_scsistat = COMMAND_ST;
  2848.    WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
  2849.    SGRAM_ACCESS(p_port);
  2850. }
  2851. /*---------------------------------------------------------------------
  2852.  *
  2853.  * Function: Status phase
  2854.  *
  2855.  * Description: Bring in the status and command complete message bytes
  2856.  *
  2857.  *---------------------------------------------------------------------*/
  2858. #if defined(OS2)
  2859. void far phaseStatus(ULONG port, UCHAR p_card)
  2860. #else
  2861. #if defined(DOS)
  2862. void phaseStatus(USHORT port, UCHAR p_card)
  2863. #else
  2864. void phaseStatus(ULONG port, UCHAR p_card)
  2865. #endif
  2866. #endif
  2867. {
  2868.    /* Start-up the automation to finish off this command and let the
  2869.       isr handle the interrupt for command complete when it comes in.
  2870.       We could wait here for the interrupt to be generated?
  2871.     */
  2872.    WR_HARPOON(port+hp_scsisig, 0x00);
  2873.    WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
  2874. }
  2875. /*---------------------------------------------------------------------
  2876.  *
  2877.  * Function: Phase Message Out
  2878.  *
  2879.  * Description: Send out our message (if we have one) and handle whatever
  2880.  *              else is involed.
  2881.  *
  2882.  *---------------------------------------------------------------------*/
  2883. #if defined(OS2)
  2884. void far phaseMsgOut(ULONG port, UCHAR p_card)
  2885. #else
  2886. #if defined(DOS)
  2887. void phaseMsgOut(USHORT port, UCHAR p_card)
  2888. #else
  2889. void phaseMsgOut(ULONG port, UCHAR p_card)
  2890. #endif
  2891. #endif
  2892. {
  2893. UCHAR message,scsiID;
  2894. PSCCB currSCCB;
  2895. PSCCBMgr_tar_info currTar_Info;
  2896. currSCCB = BL_Card[p_card].currentSCCB;
  2897. if (currSCCB != NULL) {
  2898. message = currSCCB->Sccb_scsimsg;
  2899. scsiID = currSCCB->TargID;
  2900. if (message == SMDEV_RESET) 
  2901. {
  2902. currTar_Info = &sccbMgrTbl[p_card][scsiID];
  2903. currTar_Info->TarSyncCtrl = 0;
  2904. sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
  2905. if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK) 
  2906. {
  2907. sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
  2908. }
  2909. if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI) 
  2910. {
  2911. sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
  2912. }
  2913. queueFlushSccb(p_card,SCCB_COMPLETE);
  2914. SccbMgrTableInitTarget(p_card,scsiID);
  2915. }
  2916. else if (currSCCB->Sccb_scsistat == ABORT_ST)
  2917. {
  2918. currSCCB->HostStatus = SCCB_COMPLETE;
  2919. if(BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
  2920. {
  2921. BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
  2922. sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
  2923. }
  2924. }
  2925. else if (currSCCB->Sccb_scsistat < COMMAND_ST) 
  2926. {
  2927. if(message == SMNO_OP)
  2928. {
  2929. currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
  2930. ssel(port,p_card);
  2931. return;
  2932. }
  2933. }
  2934. else 
  2935. {
  2936. if (message == SMABORT)
  2937. queueFlushSccb(p_card,SCCB_COMPLETE);
  2938. }
  2939. }
  2940. else 
  2941. {
  2942. message = SMABORT;
  2943. }
  2944. WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
  2945. WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
  2946. WR_HARPOON(port+hp_scsidata_0,message);
  2947. WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
  2948. ACCEPT_MSG(port);
  2949. WR_HARPOON(port+hp_portctrl_0, 0x00);
  2950. if ((message == SMABORT) || (message == SMDEV_RESET) || 
  2951. (message == SMABORT_TAG) ) 
  2952. {
  2953. while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
  2954. if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) 
  2955. {
  2956. WRW_HARPOON((port+hp_intstat), BUS_FREE);
  2957. if (currSCCB != NULL) 
  2958. {
  2959. if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
  2960. ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
  2961. sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
  2962. else
  2963. sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
  2964. queueCmdComplete(&BL_Card[p_card],currSCCB, p_card);
  2965. }
  2966. else 
  2967. {
  2968. BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
  2969. }
  2970. }
  2971. else 
  2972. {
  2973. sxfrp(port,p_card);
  2974. }
  2975. }
  2976. else 
  2977. {
  2978. if(message == SMPARITY)
  2979. {
  2980. currSCCB->Sccb_scsimsg = SMNO_OP;
  2981. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  2982. }
  2983. else
  2984. {
  2985. sxfrp(port,p_card);
  2986. }
  2987. }
  2988. }
  2989. /*---------------------------------------------------------------------
  2990.  *
  2991.  * Function: Message In phase
  2992.  *
  2993.  * Description: Bring in the message and determine what to do with it.
  2994.  *
  2995.  *---------------------------------------------------------------------*/
  2996. #if defined(OS2)
  2997. void far phaseMsgIn(ULONG port, UCHAR p_card)
  2998. #else
  2999. #if defined(DOS)
  3000. void phaseMsgIn(USHORT port, UCHAR p_card)
  3001. #else
  3002. void phaseMsgIn(ULONG port, UCHAR p_card)
  3003. #endif
  3004. #endif
  3005. {
  3006. UCHAR message;
  3007. PSCCB currSCCB;
  3008. currSCCB = BL_Card[p_card].currentSCCB;
  3009. if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) 
  3010. {
  3011. phaseChkFifo(port, p_card);
  3012. }
  3013. message = RD_HARPOON(port+hp_scsidata_0);
  3014. if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) 
  3015. {
  3016. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
  3017. }
  3018. else 
  3019. {
  3020. message = sfm(port,currSCCB);
  3021. if (message) 
  3022. {
  3023. sdecm(message,port,p_card);
  3024. }
  3025. else
  3026. {
  3027. if(currSCCB->Sccb_scsimsg != SMPARITY)
  3028. ACCEPT_MSG(port);
  3029. WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
  3030. }
  3031. }
  3032. }
  3033. /*---------------------------------------------------------------------
  3034.  *
  3035.  * Function: Illegal phase
  3036.  *
  3037.  * Description: Target switched to some illegal phase, so all we can do
  3038.  *              is report an error back to the host (if that is possible)
  3039.  *              and send an ABORT message to the misbehaving target.
  3040.  *
  3041.  *---------------------------------------------------------------------*/
  3042. #if defined(OS2)
  3043. void far phaseIllegal(ULONG port, UCHAR p_card)
  3044. #else
  3045. #if defined(DOS)
  3046. void phaseIllegal(USHORT port, UCHAR p_card)
  3047. #else
  3048. void phaseIllegal(ULONG port, UCHAR p_card)
  3049. #endif
  3050. #endif
  3051. {
  3052.    PSCCB currSCCB;
  3053.    currSCCB = BL_Card[p_card].currentSCCB;
  3054.    WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
  3055.    if (currSCCB != NULL) {
  3056.       currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
  3057.       currSCCB->Sccb_scsistat = ABORT_ST;
  3058.       currSCCB->Sccb_scsimsg = SMABORT;
  3059.       }
  3060.    ACCEPT_MSG_ATN(port);
  3061. }
  3062. /*---------------------------------------------------------------------
  3063.  *
  3064.  * Function: Phase Check FIFO
  3065.  *
  3066.  * Description: Make sure data has been flushed from both FIFOs and abort
  3067.  *              the operations if necessary.
  3068.  *
  3069.  *---------------------------------------------------------------------*/
  3070. #if defined(DOS)
  3071. void phaseChkFifo(USHORT port, UCHAR p_card)
  3072. #else
  3073. void phaseChkFifo(ULONG port, UCHAR p_card)
  3074. #endif
  3075. {
  3076.    ULONG xfercnt;
  3077.    PSCCB currSCCB;
  3078.    currSCCB = BL_Card[p_card].currentSCCB;
  3079.    if (currSCCB->Sccb_scsistat == DATA_IN_ST)
  3080.       {
  3081.       while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
  3082.       (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
  3083.       if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
  3084.          {
  3085.       currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
  3086.       currSCCB->Sccb_XferCnt = 0;
  3087.       if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
  3088.             (currSCCB->HostStatus == SCCB_COMPLETE))
  3089.             {
  3090.          currSCCB->HostStatus = SCCB_PARITY_ERR;
  3091.          WRW_HARPOON((port+hp_intstat), PARITY);
  3092.          }
  3093.       hostDataXferAbort(port,p_card,currSCCB);