- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / scsi / FlashPoint.c
blob7c0232fa91d64a6842860c968c78ec8cb491bef5
1 /*
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
19 #include <linux/config.h>
22 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
25 #define UNIX
26 #define FW_TYPE _SCCB_MGR_
27 #define MAX_CARDS 8
28 #undef BUSTYPE_PCI
31 #define OS_InPortByte(port) inb(port)
32 #define OS_InPortWord(port) inw(port)
33 #define OS_InPortLong(port) inl(port)
34 #define OS_OutPortByte(port, value) outb(value, port)
35 #define OS_OutPortWord(port, value) outw(value, port)
36 #define OS_OutPortLong(port, value) outl(value, port)
37 #define OS_Lock(x)
38 #define OS_UnLock(x)
42 Define name replacements for compatibility with the Linux BusLogic Driver.
45 #define SccbMgr_sense_adapter FlashPoint_ProbeHostAdapter
46 #define SccbMgr_config_adapter FlashPoint_HardwareResetHostAdapter
47 #define SccbMgr_unload_card FlashPoint_ReleaseHostAdapter
48 #define SccbMgr_start_sccb FlashPoint_StartCCB
49 #define SccbMgr_abort_sccb FlashPoint_AbortCCB
50 #define SccbMgr_my_int FlashPoint_InterruptPending
51 #define SccbMgr_isr FlashPoint_HandleInterrupt
55 Define name replacements to avoid kernel namespace pollution.
58 #define BL_Card FPT_BL_Card
59 #define BusMasterInit FPT_BusMasterInit
60 #define CalcCrc16 FPT_CalcCrc16
61 #define CalcLrc FPT_CalcLrc
62 #define ChkIfChipInitialized FPT_ChkIfChipInitialized
63 #define DiagBusMaster FPT_DiagBusMaster
64 #define DiagEEPROM FPT_DiagEEPROM
65 #define DiagXbow FPT_DiagXbow
66 #define GetTarLun FPT_GetTarLun
67 #define RNVRamData FPT_RNVRamData
68 #define RdStack FPT_RdStack
69 #define SccbMgrTableInitAll FPT_SccbMgrTableInitAll
70 #define SccbMgrTableInitCard FPT_SccbMgrTableInitCard
71 #define SccbMgrTableInitTarget FPT_SccbMgrTableInitTarget
72 #define SccbMgr_bad_isr FPT_SccbMgr_bad_isr
73 #define SccbMgr_scsi_reset FPT_SccbMgr_scsi_reset
74 #define SccbMgr_timer_expired FPT_SccbMgr_timer_expired
75 #define SendMsg FPT_SendMsg
76 #define Wait FPT_Wait
77 #define Wait1Second FPT_Wait1Second
78 #define WrStack FPT_WrStack
79 #define XbowInit FPT_XbowInit
80 #define autoCmdCmplt FPT_autoCmdCmplt
81 #define autoLoadDefaultMap FPT_autoLoadDefaultMap
82 #define busMstrDataXferStart FPT_busMstrDataXferStart
83 #define busMstrSGDataXferStart FPT_busMstrSGDataXferStart
84 #define busMstrTimeOut FPT_busMstrTimeOut
85 #define dataXferProcessor FPT_dataXferProcessor
86 #define default_intena FPT_default_intena
87 #define hostDataXferAbort FPT_hostDataXferAbort
88 #define hostDataXferRestart FPT_hostDataXferRestart
89 #define inisci FPT_inisci
90 #define mbCards FPT_mbCards
91 #define nvRamInfo FPT_nvRamInfo
92 #define phaseBusFree FPT_phaseBusFree
93 #define phaseChkFifo FPT_phaseChkFifo
94 #define phaseCommand FPT_phaseCommand
95 #define phaseDataIn FPT_phaseDataIn
96 #define phaseDataOut FPT_phaseDataOut
97 #define phaseDecode FPT_phaseDecode
98 #define phaseIllegal FPT_phaseIllegal
99 #define phaseMsgIn FPT_phaseMsgIn
100 #define phaseMsgOut FPT_phaseMsgOut
101 #define phaseStatus FPT_phaseStatus
102 #define queueAddSccb FPT_queueAddSccb
103 #define queueCmdComplete FPT_queueCmdComplete
104 #define queueDisconnect FPT_queueDisconnect
105 #define queueFindSccb FPT_queueFindSccb
106 #define queueFlushSccb FPT_queueFlushSccb
107 #define queueFlushTargSccb FPT_queueFlushTargSccb
108 #define queueSearchSelect FPT_queueSearchSelect
109 #define queueSelectFail FPT_queueSelectFail
110 #define s_PhaseTbl FPT_s_PhaseTbl
111 #define scamHAString FPT_scamHAString
112 #define scamInfo FPT_scamInfo
113 #define scarb FPT_scarb
114 #define scasid FPT_scasid
115 #define scbusf FPT_scbusf
116 #define sccbMgrTbl FPT_sccbMgrTbl
117 #define schkdd FPT_schkdd
118 #define scini FPT_scini
119 #define sciso FPT_sciso
120 #define scmachid FPT_scmachid
121 #define scsavdi FPT_scsavdi
122 #define scsel FPT_scsel
123 #define scsell FPT_scsell
124 #define scsendi FPT_scsendi
125 #define scvalq FPT_scvalq
126 #define scwirod FPT_scwirod
127 #define scwiros FPT_scwiros
128 #define scwtsel FPT_scwtsel
129 #define scxferc FPT_scxferc
130 #define sdecm FPT_sdecm
131 #define sfm FPT_sfm
132 #define shandem FPT_shandem
133 #define sinits FPT_sinits
134 #define sisyncn FPT_sisyncn
135 #define sisyncr FPT_sisyncr
136 #define siwidn FPT_siwidn
137 #define siwidr FPT_siwidr
138 #define sres FPT_sres
139 #define sresb FPT_sresb
140 #define ssel FPT_ssel
141 #define ssenss FPT_ssenss
142 #define sssyncv FPT_sssyncv
143 #define stsyncn FPT_stsyncn
144 #define stwidn FPT_stwidn
145 #define sxfrp FPT_sxfrp
146 #define utilEERead FPT_utilEERead
147 #define utilEEReadOrg FPT_utilEEReadOrg
148 #define utilEESendCmdAddr FPT_utilEESendCmdAddr
149 #define utilEEWrite FPT_utilEEWrite
150 #define utilEEWriteOnOff FPT_utilEEWriteOnOff
151 #define utilUpdateResidual FPT_utilUpdateResidual
154 /*----------------------------------------------------------------------
157 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
159 * This file is available under both the GNU General Public License
160 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
162 * $Workfile: globals.h $
164 * Description: Common shared global defines.
166 * $Date: 1996/09/04 01:26:13 $
168 * $Revision: 1.11 $
170 *----------------------------------------------------------------------*/
171 #ifndef __GLOBALS_H__
172 #define __GLOBALS_H__
174 #define _UCB_MGR_ 1
175 #define _SCCB_MGR_ 2
177 /*#include <osflags.h>*/
179 #define MAX_CDBLEN 12
181 #define SCAM_LEV_2 1
183 #define CRCMASK 0xA001
185 /* In your osflags.h file, please ENSURE that only ONE OS FLAG
186 is on at a time !!! Also, please make sure you turn set the
187 variable FW_TYPE to either _UCB_MGR_ or _SCCB_MGR_ !!! */
189 #if defined(DOS) || defined(WIN95_16) || defined(OS2) || defined(OTHER_16)
190 #define COMPILER_16_BIT 1
191 #elif defined(NETWARE) || defined(NT) || defined(WIN95_32) || defined(UNIX) || defined(OTHER_32) || defined(SOLARIS_REAL_MODE)
192 #define COMPILER_32_BIT 1
193 #endif
196 #define BL_VENDOR_ID 0x104B
197 #define FP_DEVICE_ID 0x8130
198 #define MM_DEVICE_ID 0x1040
201 #ifndef FALSE
202 #define FALSE 0
203 #endif
204 #ifndef TRUE
205 #define TRUE (!(FALSE))
206 #endif
208 #ifndef NULL
209 #define NULL 0
210 #endif
212 #define FAILURE 0xFFFFFFFFL
215 typedef unsigned char UCHAR;
216 typedef unsigned short USHORT;
217 typedef unsigned int UINT;
218 typedef unsigned long ULONG;
219 typedef unsigned char * PUCHAR;
220 typedef unsigned short* PUSHORT;
221 typedef unsigned long * PULONG;
222 typedef void * PVOID;
225 #if defined(COMPILER_16_BIT)
226 typedef unsigned char far * uchar_ptr;
227 typedef unsigned short far * ushort_ptr;
228 typedef unsigned long far * ulong_ptr;
229 #endif /* 16_BIT_COMPILER */
231 #if defined(COMPILER_32_BIT)
232 typedef unsigned char * uchar_ptr;
233 typedef unsigned short * ushort_ptr;
234 typedef unsigned long * ulong_ptr;
235 #endif /* 32_BIT_COMPILER */
238 /* NEW TYPE DEFINITIONS (shared with Mylex North)
240 ** Use following type defines to avoid confusion in 16 and 32-bit
241 ** environments. Avoid using 'int' as it denotes 16 bits in 16-bit
242 ** environment and 32 in 32-bit environments.
246 #define s08bits char
247 #define s16bits short
248 #define s32bits long
250 #define u08bits unsigned s08bits
251 #define u16bits unsigned s16bits
252 #define u32bits unsigned s32bits
254 #if defined(COMPILER_16_BIT)
256 typedef u08bits far * pu08bits;
257 typedef u16bits far * pu16bits;
258 typedef u32bits far * pu32bits;
260 #endif /* COMPILER_16_BIT */
262 #if defined(COMPILER_32_BIT)
264 typedef u08bits * pu08bits;
265 typedef u16bits * pu16bits;
266 typedef u32bits * pu32bits;
268 #endif /* COMPILER_32_BIT */
271 #define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */
272 #define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
276 #if defined(DOS)
277 /*#include <dos.h>*/
278 #undef inportb /* undefine for Borland Lib */
279 #undef inport /* they may have define I/O function in LIB */
280 #undef outportb
281 #undef outport
283 #define OS_InPortByte(ioport) inportb(ioport)
284 #define OS_InPortWord(ioport) inport(ioport)
285 #define OS_InPortLong(ioport) inportq(ioport, val)
286 #define OS_OutPortByte(ioport, val) outportb(ioport, val)
287 #define OS_OutPortWord(ioport, val) outport(ioport, val)
288 #define OS_OutPortLong(ioport) outportq(ioport, val)
289 #endif /* DOS */
291 #if defined(NETWARE) || defined(OTHER_32) || defined(OTHER_16)
292 extern u08bits OS_InPortByte(u32bits ioport);
293 extern u16bits OS_InPortWord(u32bits ioport);
294 extern u32bits OS_InPortLong(u32bits ioport);
296 extern OS_InPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count);
297 extern OS_InPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count);
298 extern OS_OutPortByte(u32bits ioport, u08bits val);
299 extern OS_OutPortWord(u32bits ioport, u16bits val);
300 extern OS_OutPortLong(u32bits ioport, u32bits val);
301 extern OS_OutPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count);
302 extern OS_OutPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count);
303 #endif /* NETWARE || OTHER_32 || OTHER_16 */
305 #if defined (NT) || defined(WIN95_32) || defined(WIN95_16)
306 #if defined(NT)
308 extern __declspec(dllimport) u08bits ScsiPortReadPortUchar(pu08bits ioport);
309 extern __declspec(dllimport) u16bits ScsiPortReadPortUshort(pu16bits ioport);
310 extern __declspec(dllimport) u32bits ScsiPortReadPortUlong(pu32bits ioport);
311 extern __declspec(dllimport) void ScsiPortWritePortUchar(pu08bits ioport, u08bits val);
312 extern __declspec(dllimport) void ScsiPortWritePortUshort(pu16bits port, u16bits val);
313 extern __declspec(dllimport) void ScsiPortWritePortUlong(pu32bits port, u32bits val);
315 #else
317 extern u08bits ScsiPortReadPortUchar(pu08bits ioport);
318 extern u16bits ScsiPortReadPortUshort(pu16bits ioport);
319 extern u32bits ScsiPortReadPortUlong(pu32bits ioport);
320 extern void ScsiPortWritePortUchar(pu08bits ioport, u08bits val);
321 extern void ScsiPortWritePortUshort(pu16bits port, u16bits val);
322 extern void ScsiPortWritePortUlong(pu32bits port, u32bits val);
323 #endif
326 #define OS_InPortByte(ioport) ScsiPortReadPortUchar((pu08bits) ioport)
327 #define OS_InPortWord(ioport) ScsiPortReadPortUshort((pu16bits) ioport)
328 #define OS_InPortLong(ioport) ScsiPortReadPortUlong((pu32bits) ioport)
330 #define OS_OutPortByte(ioport, val) ScsiPortWritePortUchar((pu08bits) ioport, (u08bits) val)
331 #define OS_OutPortWord(ioport, val) ScsiPortWritePortUshort((pu16bits) ioport, (u16bits) val)
332 #define OS_OutPortLong(ioport, val) ScsiPortWritePortUlong((pu32bits) ioport, (u32bits) val)
333 #define OS_OutPortByteBuffer(ioport, buffer, count) \
334 ScsiPortWritePortBufferUchar((pu08bits)&port, (pu08bits) buffer, (u32bits) count)
335 #define OS_OutPortWordBuffer(ioport, buffer, count) \
336 ScsiPortWritePortBufferUshort((pu16bits)&port, (pu16bits) buffer, (u32bits) count)
338 #define OS_Lock(x)
339 #define OS_UnLock(x)
340 #endif /* NT || WIN95_32 || WIN95_16 */
342 #if defined (UNIX) && !defined(OS_InPortByte)
343 #define OS_InPortByte(ioport) inb((u16bits)ioport)
344 #define OS_InPortWord(ioport) inw((u16bits)ioport)
345 #define OS_InPortLong(ioport) inl((u16bits)ioport)
346 #define OS_OutPortByte(ioport,val) outb((u16bits)ioport, (u08bits)val)
347 #define OS_OutPortWord(ioport,val) outw((u16bits)ioport, (u16bits)val)
348 #define OS_OutPortLong(ioport,val) outl((u16bits)ioport, (u32bits)val)
350 #define OS_Lock(x)
351 #define OS_UnLock(x)
352 #endif /* UNIX */
355 #if defined(OS2)
356 extern u08bits inb(u32bits ioport);
357 extern u16bits inw(u32bits ioport);
358 extern void outb(u32bits ioport, u08bits val);
359 extern void outw(u32bits ioport, u16bits val);
361 #define OS_InPortByte(ioport) inb(ioport)
362 #define OS_InPortWord(ioport) inw(ioport)
363 #define OS_OutPortByte(ioport, val) outb(ioport, val)
364 #define OS_OutPortWord(ioport, val) outw(ioport, val)
365 extern u32bits OS_InPortLong(u32bits ioport);
366 extern void OS_OutPortLong(u32bits ioport, u32bits val);
368 #define OS_Lock(x)
369 #define OS_UnLock(x)
370 #endif /* OS2 */
372 #if defined(SOLARIS_REAL_MODE)
374 extern unsigned char inb(unsigned long ioport);
375 extern unsigned short inw(unsigned long ioport);
377 #define OS_InPortByte(ioport) inb(ioport)
378 #define OS_InPortWord(ioport) inw(ioport)
380 extern void OS_OutPortByte(unsigned long ioport, unsigned char val);
381 extern void OS_OutPortWord(unsigned long ioport, unsigned short val);
382 extern unsigned long OS_InPortLong(unsigned long ioport);
383 extern void OS_OutPortLong(unsigned long ioport, unsigned long val);
385 #define OS_Lock(x)
386 #define OS_UnLock(x)
388 #endif /* SOLARIS_REAL_MODE */
390 #endif /* __GLOBALS_H__ */
392 /*----------------------------------------------------------------------
395 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
397 * This file is available under both the GNU General Public License
398 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
400 * $Workfile: sccbmgr.h $
402 * Description: Common shared SCCB Interface defines and SCCB
403 * Manager specifics defines.
405 * $Date: 1996/10/24 23:09:33 $
407 * $Revision: 1.14 $
409 *----------------------------------------------------------------------*/
411 #ifndef __SCCB_H__
412 #define __SCCB_H__
414 /*#include <osflags.h>*/
415 /*#include <globals.h>*/
417 #if defined(BUGBUG)
418 #define debug_size 32
419 #endif
421 #if defined(DOS)
423 typedef struct _SCCB near *PSCCB;
424 #if (FW_TYPE == _SCCB_MGR_)
425 typedef void (*CALL_BK_FN)(PSCCB);
426 #endif
428 #elif defined(OS2)
430 typedef struct _SCCB far *PSCCB;
431 #if (FW_TYPE == _SCCB_MGR_)
432 typedef void (far *CALL_BK_FN)(PSCCB);
433 #endif
435 #else
437 typedef struct _SCCB *PSCCB;
438 #if (FW_TYPE == _SCCB_MGR_)
439 typedef void (*CALL_BK_FN)(PSCCB);
440 #endif
442 #endif
445 typedef struct SCCBMgr_info {
446 ULONG si_baseaddr;
447 UCHAR si_present;
448 UCHAR si_intvect;
449 UCHAR si_id;
450 UCHAR si_lun;
451 USHORT si_fw_revision;
452 USHORT si_per_targ_init_sync;
453 USHORT si_per_targ_fast_nego;
454 USHORT si_per_targ_ultra_nego;
455 USHORT si_per_targ_no_disc;
456 USHORT si_per_targ_wide_nego;
457 USHORT si_flags;
458 UCHAR si_card_family;
459 UCHAR si_bustype;
460 UCHAR si_card_model[3];
461 UCHAR si_relative_cardnum;
462 UCHAR si_reserved[4];
463 ULONG si_OS_reserved;
464 UCHAR si_XlatInfo[4];
465 ULONG si_reserved2[5];
466 ULONG si_secondary_range;
467 } SCCBMGR_INFO;
469 #if defined(DOS)
470 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
471 #else
472 #if defined (COMPILER_16_BIT)
473 typedef SCCBMGR_INFO far * PSCCBMGR_INFO;
474 #else
475 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
476 #endif
477 #endif // defined(DOS)
482 #if (FW_TYPE==_SCCB_MGR_)
483 #define SCSI_PARITY_ENA 0x0001
484 #define LOW_BYTE_TERM 0x0010
485 #define HIGH_BYTE_TERM 0x0020
486 #define BUSTYPE_PCI 0x3
487 #endif
489 #define SUPPORT_16TAR_32LUN 0x0002
490 #define SOFT_RESET 0x0004
491 #define EXTENDED_TRANSLATION 0x0008
492 #define POST_ALL_UNDERRRUNS 0x0040
493 #define FLAG_SCAM_ENABLED 0x0080
494 #define FLAG_SCAM_LEVEL2 0x0100
499 #define HARPOON_FAMILY 0x02
502 #define ISA_BUS_CARD 0x01
503 #define EISA_BUS_CARD 0x02
504 #define PCI_BUS_CARD 0x03
505 #define VESA_BUS_CARD 0x04
507 /* SCCB struc used for both SCCB and UCB manager compiles!
508 * The UCB Manager treats the SCCB as it's 'native hardware structure'
512 #pragma pack(1)
513 typedef struct _SCCB {
514 UCHAR OperationCode;
515 UCHAR ControlByte;
516 UCHAR CdbLength;
517 UCHAR RequestSenseLength;
518 ULONG DataLength;
519 ULONG DataPointer;
520 UCHAR CcbRes[2];
521 UCHAR HostStatus;
522 UCHAR TargetStatus;
523 UCHAR TargID;
524 UCHAR Lun;
525 UCHAR Cdb[12];
526 UCHAR CcbRes1;
527 UCHAR Reserved1;
528 ULONG Reserved2;
529 ULONG SensePointer;
532 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
533 ULONG SccbIOPort; /* Identifies board base port */
534 UCHAR SccbStatus;
535 UCHAR SCCBRes2;
536 USHORT SccbOSFlags;
539 ULONG Sccb_XferCnt; /* actual transfer count */
540 ULONG Sccb_ATC;
541 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
542 ULONG Sccb_res1;
543 USHORT Sccb_MGRFlags;
544 USHORT Sccb_sgseg;
545 UCHAR Sccb_scsimsg; /* identify msg for selection */
546 UCHAR Sccb_tag;
547 UCHAR Sccb_scsistat;
548 UCHAR Sccb_idmsg; /* image of last msg in */
549 PSCCB Sccb_forwardlink;
550 PSCCB Sccb_backlink;
551 ULONG Sccb_savedATC;
552 UCHAR Save_Cdb[6];
553 UCHAR Save_CdbLen;
554 UCHAR Sccb_XferState;
555 ULONG Sccb_SGoffset;
556 #if (FW_TYPE == _UCB_MGR_)
557 PUCB Sccb_ucb_ptr;
558 #endif
559 } SCCB;
561 #define SCCB_SIZE sizeof(SCCB)
563 #pragma pack()
567 #define SCSI_INITIATOR_COMMAND 0x00
568 #define TARGET_MODE_COMMAND 0x01
569 #define SCATTER_GATHER_COMMAND 0x02
570 #define RESIDUAL_COMMAND 0x03
571 #define RESIDUAL_SG_COMMAND 0x04
572 #define RESET_COMMAND 0x81
575 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
576 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
577 #define TAG_Q_MASK 0xE0
578 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
579 #define SCCB_DATA_XFER_IN 0x08 /* Read */
582 #define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */
583 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
586 #define BUS_FREE_ST 0
587 #define SELECT_ST 1
588 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
589 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
590 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
591 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
592 #define COMMAND_ST 6
593 #define DATA_OUT_ST 7
594 #define DATA_IN_ST 8
595 #define DISCONNECT_ST 9
596 #define STATUS_ST 10
597 #define ABORT_ST 11
598 #define MESSAGE_ST 12
601 #define F_HOST_XFER_DIR 0x01
602 #define F_ALL_XFERRED 0x02
603 #define F_SG_XFER 0x04
604 #define F_AUTO_SENSE 0x08
605 #define F_ODD_BALL_CNT 0x10
606 #define F_NO_DATA_YET 0x80
609 #define F_STATUSLOADED 0x01
610 #define F_MSGLOADED 0x02
611 #define F_DEV_SELECTED 0x04
614 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
615 #define SCCB_DATA_UNDER_RUN 0x0C
616 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
617 #define SCCB_DATA_OVER_RUN 0x12
618 #define SCCB_UNEXPECTED_BUS_FREE 0x13 /* Target dropped SCSI BSY */
619 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
621 #define SCCB_INVALID_OP_CODE 0x16 /* SCCB invalid operation code */
622 #define SCCB_INVALID_SCCB 0x1A /* Invalid SCCB - bad parameter */
623 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
624 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
625 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
629 #if (FW_TYPE==_UCB_MGR_)
630 #define HBA_AUTO_SENSE_FAIL 0x1B
631 #define HBA_TQ_REJECTED 0x1C
632 #define HBA_UNSUPORTED_MSG 0x1D
633 #define HBA_HW_ERROR 0x20
634 #define HBA_ATN_NOT_RESPONDED 0x21
635 #define HBA_SCSI_RESET_BY_ADAPTER 0x22
636 #define HBA_SCSI_RESET_BY_TARGET 0x23
637 #define HBA_WRONG_CONNECTION 0x24
638 #define HBA_BUS_DEVICE_RESET 0x25
639 #define HBA_ABORT_QUEUE 0x26
641 #else // these are not defined in BUDI/UCB
643 #define SCCB_INVALID_DIRECTION 0x18 /* Invalid target direction */
644 #define SCCB_DUPLICATE_SCCB 0x19 /* Duplicate SCCB */
645 #define SCCB_SCSI_RST 0x35 /* SCSI RESET detected. */
647 #endif // (FW_TYPE==_UCB_MGR_)
650 #define SCCB_IN_PROCESS 0x00
651 #define SCCB_SUCCESS 0x01
652 #define SCCB_ABORT 0x02
653 #define SCCB_NOT_FOUND 0x03
654 #define SCCB_ERROR 0x04
655 #define SCCB_INVALID 0x05
657 #define SCCB_SIZE sizeof(SCCB)
662 #if (FW_TYPE == _UCB_MGR_)
663 void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb);
664 s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb);
665 u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard);
666 s32bits SccbMgr_isr(CARD_HANDLE pCurrCard);
667 void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard);
668 void SccbMgr_timer_expired(CARD_HANDLE pCurrCard);
669 void SccbMgr_unload_card(CARD_HANDLE pCurrCard);
670 void SccbMgr_restore_foreign_state(CARD_HANDLE pCurrCard);
671 void SccbMgr_restore_native_state(CARD_HANDLE pCurrCard);
672 void SccbMgr_save_foreign_state(PADAPTER_INFO pAdapterInfo);
674 #endif
677 #if (FW_TYPE == _SCCB_MGR_)
679 #if defined (DOS)
680 int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo);
681 USHORT SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo);
682 void SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_SCCB);
683 int SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_SCCB);
684 UCHAR SccbMgr_my_int(USHORT pCurrCard);
685 int SccbMgr_isr(USHORT pCurrCard);
686 void SccbMgr_scsi_reset(USHORT pCurrCard);
687 void SccbMgr_timer_expired(USHORT pCurrCard);
688 USHORT SccbMgr_status(USHORT pCurrCard);
689 void SccbMgr_unload_card(USHORT pCurrCard);
691 #else //non-DOS
693 int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo);
694 ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo);
695 void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_SCCB);
696 int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_SCCB);
697 UCHAR SccbMgr_my_int(ULONG pCurrCard);
698 int SccbMgr_isr(ULONG pCurrCard);
699 void SccbMgr_scsi_reset(ULONG pCurrCard);
700 void SccbMgr_enable_int(ULONG pCurrCard);
701 void SccbMgr_disable_int(ULONG pCurrCard);
702 void SccbMgr_timer_expired(ULONG pCurrCard);
703 void SccbMgr_unload_card(ULONG pCurrCard);
705 #endif
706 #endif // (FW_TYPE == _SCCB_MGR_)
708 #endif /* __SCCB_H__ */
710 /*----------------------------------------------------------------------
713 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
715 * This file is available under both the GNU General Public License
716 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
718 * $Workfile: blx30.h $
720 * Description: This module contains SCCB/UCB Manager implementation
721 * specific stuff.
723 * $Date: 1996/11/13 18:34:22 $
725 * $Revision: 1.10 $
727 *----------------------------------------------------------------------*/
730 #ifndef __blx30_H__
731 #define __blx30_H__
733 /*#include <globals.h>*/
735 #define ORION_FW_REV 3110
740 #define HARP_REVD 1
743 #if defined(DOS)
744 #define QUEUE_DEPTH 8+1 /*1 for Normal disconnect 0 for Q'ing. */
745 #else
746 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
747 #endif // defined(DOS)
749 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
751 #define WIDE_SCSI 1
753 #if defined(WIDE_SCSI)
754 #if defined(DOS)
755 #define MAX_SCSI_TAR 16
756 #define MAX_LUN 8
757 #define LUN_MASK 0x07
758 #else
759 #define MAX_SCSI_TAR 16
760 #define MAX_LUN 32
761 #define LUN_MASK 0x1f
763 #endif
764 #else
765 #define MAX_SCSI_TAR 8
766 #define MAX_LUN 8
767 #define LUN_MASK 0x07
768 #endif
770 #if defined(HARP_REVA)
771 #define SG_BUF_CNT 15 /*Number of prefetched elements. */
772 #else
773 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
774 #endif
776 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
777 #define SG_LOCAL_MASK 0x00000000L
778 #define SG_ELEMENT_MASK 0xFFFFFFFFL
781 #if (FW_TYPE == _UCB_MGR_)
782 #define OPC_DECODE_NORMAL 0x0f7f
783 #endif // _UCB_MGR_
787 #if defined(DOS)
789 /*#include <dos.h>*/
790 #define RD_HARPOON(ioport) (OS_InPortByte(ioport))
791 #define RDW_HARPOON(ioport) (OS_InPortWord(ioport))
792 #define WR_HARPOON(ioport,val) (OS_OutPortByte(ioport,val))
793 #define WRW_HARPOON(ioport,val) (OS_OutPortWord(ioport,val))
795 #define RD_HARP32(port,offset,data) asm{db 66h; \
796 push ax; \
797 mov dx,port; \
798 add dx, offset; \
799 db 66h; \
800 in ax,dx; \
801 db 66h; \
802 mov word ptr data,ax;\
803 db 66h; \
804 pop ax}
806 #define WR_HARP32(port,offset,data) asm{db 66h; \
807 push ax; \
808 mov dx,port; \
809 add dx, offset; \
810 db 66h; \
811 mov ax,word ptr data;\
812 db 66h; \
813 out dx,ax; \
814 db 66h; \
815 pop ax}
816 #endif /* DOS */
818 #if defined(NETWARE) || defined(OTHER_32) || defined(OTHER_16)
819 #define RD_HARPOON(ioport) OS_InPortByte((unsigned long)ioport)
820 #define RDW_HARPOON(ioport) OS_InPortWord((unsigned long)ioport)
821 #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong(ioport + offset))
822 #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val)
823 #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val)
824 #define WR_HARP32(ioport,offset,data) OS_OutPortLong((ioport + offset), data)
825 #endif /* NETWARE || OTHER_32 || OTHER_16 */
827 #if defined(NT) || defined(WIN95_32) || defined(WIN95_16)
828 #define RD_HARPOON(ioport) OS_InPortByte((ULONG)ioport)
829 #define RDW_HARPOON(ioport) OS_InPortWord((ULONG)ioport)
830 #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
831 #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val)
832 #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val)
833 #define WR_HARP32(ioport,offset,data) OS_OutPortLong((ULONG)(ioport + offset), data)
834 #endif /* NT || WIN95_32 || WIN95_16 */
836 #if defined (UNIX)
837 #define RD_HARPOON(ioport) OS_InPortByte((u32bits)ioport)
838 #define RDW_HARPOON(ioport) OS_InPortWord((u32bits)ioport)
839 #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
840 #define WR_HARPOON(ioport,val) OS_OutPortByte((u32bits)ioport,(u08bits) val)
841 #define WRW_HARPOON(ioport,val) OS_OutPortWord((u32bits)ioport,(u16bits)val)
842 #define WR_HARP32(ioport,offset,data) OS_OutPortLong((u32bits)(ioport + offset), data)
843 #endif /* UNIX */
845 #if defined(OS2)
846 #define RD_HARPOON(ioport) OS_InPortByte((unsigned long)ioport)
847 #define RDW_HARPOON(ioport) OS_InPortWord((unsigned long)ioport)
848 #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
849 #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val)
850 #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val)
851 #define WR_HARP32(ioport,offset,data) OS_OutPortLong(((ULONG)(ioport + offset)), data)
852 #endif /* OS2 */
854 #if defined(SOLARIS_REAL_MODE)
856 #define RD_HARPOON(ioport) OS_InPortByte((unsigned long)ioport)
857 #define RDW_HARPOON(ioport) OS_InPortWord((unsigned long)ioport)
858 #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
859 #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val)
860 #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val)
861 #define WR_HARP32(ioport,offset,data) OS_OutPortLong((ULONG)(ioport + offset), (ULONG)data)
863 #endif /* SOLARIS_REAL_MODE */
865 #endif /* __BLX30_H__ */
868 /*----------------------------------------------------------------------
871 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
873 * This file is available under both the GNU General Public License
874 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
876 * $Workfile: target.h $
878 * Description: Definitions for Target related structures
880 * $Date: 1996/12/11 22:06:20 $
882 * $Revision: 1.9 $
884 *----------------------------------------------------------------------*/
886 #ifndef __TARGET__
887 #define __TARGET__
889 /*#include <globals.h>*/
890 /*#include <blx30.h>*/
893 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
894 #define SYNC_UNKNOWN 0x00
895 #define SYNC_TRYING BIT(6)
896 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
898 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
899 #define WIDE_DISABLED 0x00
900 #define WIDE_ENABLED BIT(4)
901 #define WIDE_NEGOCIATED BIT(5)
903 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
904 #define TAG_Q_UNKNOWN 0x00
905 #define TAG_Q_TRYING BIT(2)
906 #define TAG_Q_REJECT BIT(3)
907 #define TAG_Q_SUPPORTED (BIT(3)+BIT(2))
909 #define TAR_ALLOW_DISC BIT(0)
912 #define EE_SYNC_MASK (BIT(0)+BIT(1))
913 #define EE_SYNC_ASYNC 0x00
914 #define EE_SYNC_5MB BIT(0)
915 #define EE_SYNC_10MB BIT(1)
916 #define EE_SYNC_20MB (BIT(0)+BIT(1))
918 #define EE_ALLOW_DISC BIT(6)
919 #define EE_WIDE_SCSI BIT(7)
922 #if defined(DOS)
923 typedef struct SCCBMgr_tar_info near *PSCCBMgr_tar_info;
925 #elif defined(OS2)
926 typedef struct SCCBMgr_tar_info far *PSCCBMgr_tar_info;
928 #else
929 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
931 #endif
934 typedef struct SCCBMgr_tar_info {
936 PSCCB TarSelQ_Head;
937 PSCCB TarSelQ_Tail;
938 UCHAR TarLUN_CA; /*Contingent Allgiance */
939 UCHAR TarTagQ_Cnt;
940 UCHAR TarSelQ_Cnt;
941 UCHAR TarStatus;
942 UCHAR TarEEValue;
943 UCHAR TarSyncCtrl;
944 UCHAR TarReserved[2]; /* for alignment */
945 UCHAR LunDiscQ_Idx[MAX_LUN];
946 UCHAR TarLUNBusy[MAX_LUN];
947 } SCCBMGR_TAR_INFO;
949 typedef struct NVRAMInfo {
950 UCHAR niModel; /* Model No. of card */
951 UCHAR niCardNo; /* Card no. */
952 #if defined(DOS)
953 USHORT niBaseAddr; /* Port Address of card */
954 #else
955 ULONG niBaseAddr; /* Port Address of card */
956 #endif
957 UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
958 UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
959 UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
960 UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
961 UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
962 UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
963 }NVRAMINFO;
965 #if defined(DOS)
966 typedef NVRAMINFO near *PNVRamInfo;
967 #elif defined (OS2)
968 typedef NVRAMINFO far *PNVRamInfo;
969 #else
970 typedef NVRAMINFO *PNVRamInfo;
971 #endif
973 #define MODEL_LT 1
974 #define MODEL_DL 2
975 #define MODEL_LW 3
976 #define MODEL_DW 4
979 typedef struct SCCBcard {
980 PSCCB currentSCCB;
981 #if (FW_TYPE==_SCCB_MGR_)
982 PSCCBMGR_INFO cardInfo;
983 #else
984 PADAPTER_INFO cardInfo;
985 #endif
987 #if defined(DOS)
988 USHORT ioPort;
989 #else
990 ULONG ioPort;
991 #endif
993 USHORT cmdCounter;
994 UCHAR discQCount;
995 UCHAR tagQ_Lst;
996 UCHAR cardIndex;
997 UCHAR scanIndex;
998 UCHAR globalFlags;
999 UCHAR ourId;
1000 PNVRamInfo pNvRamInfo;
1001 PSCCB discQ_Tbl[QUEUE_DEPTH];
1003 }SCCBCARD;
1005 #if defined(DOS)
1006 typedef struct SCCBcard near *PSCCBcard;
1007 #elif defined (OS2)
1008 typedef struct SCCBcard far *PSCCBcard;
1009 #else
1010 typedef struct SCCBcard *PSCCBcard;
1011 #endif
1014 #define F_TAG_STARTED 0x01
1015 #define F_CONLUN_IO 0x02
1016 #define F_DO_RENEGO 0x04
1017 #define F_NO_FILTER 0x08
1018 #define F_GREEN_PC 0x10
1019 #define F_HOST_XFER_ACT 0x20
1020 #define F_NEW_SCCB_CMD 0x40
1021 #define F_UPDATE_EEPROM 0x80
1024 #define ID_STRING_LENGTH 32
1025 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
1027 #define TYPE_CODE1 00 /*No ID yet */
1029 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
1031 #define ASSIGN_ID 0x00
1032 #define SET_P_FLAG 0x01
1033 #define CFG_CMPLT 0x03
1034 #define DOM_MSTR 0x0F
1035 #define SYNC_PTRN 0x1F
1037 #define ID_0_7 0x18
1038 #define ID_8_F 0x11
1039 #define ID_10_17 0x12
1040 #define ID_18_1F 0x0B
1041 #define MISC_CODE 0x14
1042 #define CLR_P_FLAG 0x18
1043 #define LOCATE_ON 0x12
1044 #define LOCATE_OFF 0x0B
1046 #define LVL_1_MST 0x00
1047 #define LVL_2_MST 0x40
1048 #define DOM_LVL_2 0xC0
1051 #define INIT_SELTD 0x01
1052 #define LEVEL2_TAR 0x02
1055 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
1056 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
1057 CLR_PRIORITY,NO_ID_AVAIL };
1059 typedef struct SCCBscam_info {
1061 UCHAR id_string[ID_STRING_LENGTH];
1062 enum scam_id_st state;
1064 } SCCBSCAM_INFO, *PSCCBSCAM_INFO;
1066 #endif
1067 /*----------------------------------------------------------------------
1070 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
1072 * This file is available under both the GNU General Public License
1073 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
1075 * $Workfile: scsi2.h $
1077 * Description: Register definitions for HARPOON ASIC.
1079 * $Date: 1996/11/13 18:32:57 $
1081 * $Revision: 1.4 $
1083 *----------------------------------------------------------------------*/
1085 #ifndef __SCSI_H__
1086 #define __SCSI_H__
1090 #define SCSI_TEST_UNIT_READY 0x00
1091 #define SCSI_REZERO_UNIT 0x01
1092 #define SCSI_REQUEST_SENSE 0x03
1093 #define SCSI_FORMAT_UNIT 0x04
1094 #define SCSI_REASSIGN 0x07
1095 #define SCSI_READ 0x08
1096 #define SCSI_WRITE 0x0A
1097 #define SCSI_SEEK 0x0B
1098 #define SCSI_INQUIRY 0x12
1099 #define SCSI_MODE_SELECT 0x15
1100 #define SCSI_RESERVE_UNIT 0x16
1101 #define SCSI_RELEASE_UNIT 0x17
1102 #define SCSI_MODE_SENSE 0x1A
1103 #define SCSI_START_STOP_UNIT 0x1B
1104 #define SCSI_SEND_DIAGNOSTIC 0x1D
1105 #define SCSI_READ_CAPACITY 0x25
1106 #define SCSI_READ_EXTENDED 0x28
1107 #define SCSI_WRITE_EXTENDED 0x2A
1108 #define SCSI_SEEK_EXTENDED 0x2B
1109 #define SCSI_WRITE_AND_VERIFY 0x2E
1110 #define SCSI_VERIFY 0x2F
1111 #define SCSI_READ_DEFECT_DATA 0x37
1112 #define SCSI_WRITE_BUFFER 0x3B
1113 #define SCSI_READ_BUFFER 0x3C
1114 #define SCSI_RECV_DIAGNOSTIC 0x1C
1115 #define SCSI_READ_LONG 0x3E
1116 #define SCSI_WRITE_LONG 0x3F
1117 #define SCSI_LAST_SCSI_CMND SCSI_WRITE_LONG
1118 #define SCSI_INVALID_CMND 0xFF
1122 #define SSGOOD 0x00
1123 #define SSCHECK 0x02
1124 #define SSCOND_MET 0x04
1125 #define SSBUSY 0x08
1126 #define SSRESERVATION_CONFLICT 0x18
1127 #define SSCMD_TERM 0x22
1128 #define SSQ_FULL 0x28
1131 #define SKNO_SEN 0x00
1132 #define SKRECOV_ERR 0x01
1133 #define SKNOT_RDY 0x02
1134 #define SKMED_ERR 0x03
1135 #define SKHW_ERR 0x04
1136 #define SKILL_REQ 0x05
1137 #define SKUNIT_ATTN 0x06
1138 #define SKDATA_PROTECT 0x07
1139 #define SKBLNK_CHK 0x08
1140 #define SKCPY_ABORT 0x0A
1141 #define SKABORT_CMD 0x0B
1142 #define SKEQUAL 0x0C
1143 #define SKVOL_OVF 0x0D
1144 #define SKMIS_CMP 0x0E
1147 #define SMCMD_COMP 0x00
1148 #define SMEXT 0x01
1149 #define SMSAVE_DATA_PTR 0x02
1150 #define SMREST_DATA_PTR 0x03
1151 #define SMDISC 0x04
1152 #define SMINIT_DETEC_ERR 0x05
1153 #define SMABORT 0x06
1154 #define SMREJECT 0x07
1155 #define SMNO_OP 0x08
1156 #define SMPARITY 0x09
1157 #define SMDEV_RESET 0x0C
1158 #define SMABORT_TAG 0x0D
1159 #define SMINIT_RECOVERY 0x0F
1160 #define SMREL_RECOVERY 0x10
1162 #define SMIDENT 0x80
1163 #define DISC_PRIV 0x40
1166 #define SMSYNC 0x01
1167 #define SM10MBS 0x19 /* 100ns */
1168 #define SM5MBS 0x32 /* 200ns */
1169 #define SMOFFSET 0x0F /* Maxoffset value */
1170 #define SMWDTR 0x03
1171 #define SM8BIT 0x00
1172 #define SM16BIT 0x01
1173 #define SM32BIT 0x02
1174 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
1177 #define ARBITRATION_DELAY 0x01 /* 2.4us using a 40Mhz clock */
1178 #define BUS_SETTLE_DELAY 0x01 /* 400ns */
1179 #define BUS_CLEAR_DELAY 0x01 /* 800ns */
1183 #define SPHASE_TO 0x0A /* 10 second timeout waiting for */
1184 #define SCMD_TO 0x0F /* Overall command timeout */
1188 #define SIX_BYTE_CMD 0x06
1189 #define TEN_BYTE_CMD 0x0A
1190 #define TWELVE_BYTE_CMD 0x0C
1192 #define ASYNC 0x00
1193 #define PERI25NS 0x06 /* 25/4ns to next clock for xbow. */
1194 #define SYNC10MBS 0x19
1195 #define SYNC5MBS 0x32
1196 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
1198 #endif
1199 /*----------------------------------------------------------------------
1202 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
1204 * This file is available under both the GNU General Public License
1205 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
1207 * $Workfile: eeprom.h $
1209 * Description: Definitions for EEPROM related structures
1211 * $Date: 1996/11/13 18:28:39 $
1213 * $Revision: 1.4 $
1215 *----------------------------------------------------------------------*/
1217 #ifndef __EEPROM__
1218 #define __EEPROM__
1220 /*#include <globals.h>*/
1222 #define EEPROM_WD_CNT 256
1224 #define EEPROM_CHECK_SUM 0
1225 #define FW_SIGNATURE 2
1226 #define MODEL_NUMB_0 4
1227 #define MODEL_NUMB_1 5
1228 #define MODEL_NUMB_2 6
1229 #define MODEL_NUMB_3 7
1230 #define MODEL_NUMB_4 8
1231 #define MODEL_NUMB_5 9
1232 #define IO_BASE_ADDR 10
1233 #define IRQ_NUMBER 12
1234 #define PCI_INT_PIN 13
1235 #define BUS_DELAY 14 /*On time in byte 14 off delay in 15 */
1236 #define SYSTEM_CONFIG 16
1237 #define SCSI_CONFIG 17
1238 #define BIOS_CONFIG 18
1239 #define SPIN_UP_DELAY 19
1240 #define SCAM_CONFIG 20
1241 #define ADAPTER_SCSI_ID 24
1244 #define IGNORE_B_SCAN 32
1245 #define SEND_START_ENA 34
1246 #define DEVICE_ENABLE 36
1248 #define SYNC_RATE_TBL 38
1249 #define SYNC_RATE_TBL01 38
1250 #define SYNC_RATE_TBL23 40
1251 #define SYNC_RATE_TBL45 42
1252 #define SYNC_RATE_TBL67 44
1253 #define SYNC_RATE_TBL89 46
1254 #define SYNC_RATE_TBLab 48
1255 #define SYNC_RATE_TBLcd 50
1256 #define SYNC_RATE_TBLef 52
1260 #define EE_SCAMBASE 256
1264 #define DOM_MASTER (BIT(0) + BIT(1))
1265 #define SCAM_ENABLED BIT(2)
1266 #define SCAM_LEVEL2 BIT(3)
1269 #define RENEGO_ENA BITW(10)
1270 #define CONNIO_ENA BITW(11)
1271 #define GREEN_PC_ENA BITW(12)
1274 #define AUTO_RATE_00 00
1275 #define AUTO_RATE_05 01
1276 #define AUTO_RATE_10 02
1277 #define AUTO_RATE_20 03
1279 #define WIDE_NEGO_BIT BIT(7)
1280 #define DISC_ENABLE_BIT BIT(6)
1283 #endif
1284 /*----------------------------------------------------------------------
1287 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
1289 * This file is available under both the GNU General Public License
1290 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
1292 * $Workfile: harpoon.h $
1294 * Description: Register definitions for HARPOON ASIC.
1296 * $Date: 1997/07/09 21:44:36 $
1298 * $Revision: 1.9 $
1300 *----------------------------------------------------------------------*/
1303 /*#include <globals.h>*/
1305 #ifndef __HARPOON__
1306 #define __HARPOON__
1309 #define hp_vendor_id_0 0x00 /* LSB */
1310 #define ORION_VEND_0 0x4B
1312 #define hp_vendor_id_1 0x01 /* MSB */
1313 #define ORION_VEND_1 0x10
1315 #define hp_device_id_0 0x02 /* LSB */
1316 #define ORION_DEV_0 0x30
1318 #define hp_device_id_1 0x03 /* MSB */
1319 #define ORION_DEV_1 0x81
1321 /* Sub Vendor ID and Sub Device ID only available in
1322 Harpoon Version 2 and higher */
1324 #define hp_sub_vendor_id_0 0x04 /* LSB */
1325 #define hp_sub_vendor_id_1 0x05 /* MSB */
1326 #define hp_sub_device_id_0 0x06 /* LSB */
1327 #define hp_sub_device_id_1 0x07 /* MSB */
1330 #define hp_dual_addr_lo 0x08
1331 #define hp_dual_addr_lmi 0x09
1332 #define hp_dual_addr_hmi 0x0A
1333 #define hp_dual_addr_hi 0x0B
1335 #define hp_semaphore 0x0C
1336 #define SCCB_MGR_ACTIVE BIT(0)
1337 #define TICKLE_ME BIT(1)
1338 #define SCCB_MGR_PRESENT BIT(3)
1339 #define BIOS_IN_USE BIT(4)
1341 #define hp_user_defined_D 0x0D
1343 #define hp_reserved_E 0x0E
1345 #define hp_sys_ctrl 0x0F
1347 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
1348 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
1349 #define HALT_MACH BIT(3) /*Halt State Machine */
1350 #define HARD_ABORT BIT(4) /*Hard Abort */
1351 #define DIAG_MODE BIT(5) /*Diagnostic Mode */
1353 #define BM_ABORT_TMOUT 0x50 /*Halt State machine time out */
1355 #define hp_sys_cfg 0x10
1357 #define DONT_RST_FIFO BIT(7) /*Don't reset FIFO */
1360 #define hp_host_ctrl0 0x11
1362 #define DUAL_ADDR_MODE BIT(0) /*Enable 64-bit addresses */
1363 #define IO_MEM_SPACE BIT(1) /*I/O Memory Space */
1364 #define RESOURCE_LOCK BIT(2) /*Enable Resource Lock */
1365 #define IGNOR_ACCESS_ERR BIT(3) /*Ignore Access Error */
1366 #define HOST_INT_EDGE BIT(4) /*Host interrupt level/edge mode sel */
1367 #define SIX_CLOCKS BIT(5) /*6 Clocks between Strobe */
1368 #define DMA_EVEN_PARITY BIT(6) /*Enable DMA Enen Parity */
1371 #define BURST_MODE BIT(0)
1374 #define hp_reserved_12 0x12
1376 #define hp_host_blk_cnt 0x13
1378 #define XFER_BLK1 0x00 /* 0 0 0 1 byte per block*/
1379 #define XFER_BLK2 0x01 /* 0 0 1 2 byte per block*/
1380 #define XFER_BLK4 0x02 /* 0 1 0 4 byte per block*/
1381 #define XFER_BLK8 0x03 /* 0 1 1 8 byte per block*/
1382 #define XFER_BLK16 0x04 /* 1 0 0 16 byte per block*/
1383 #define XFER_BLK32 0x05 /* 1 0 1 32 byte per block*/
1384 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
1386 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
1389 #define hp_reserved_14 0x14
1390 #define hp_reserved_15 0x15
1391 #define hp_reserved_16 0x16
1393 #define hp_int_mask 0x17
1395 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
1396 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
1397 #define INT_SCSI BIT(2) /* Scsi block interrupt */
1398 #define INT_FIFO_RDY BIT(4) /* FIFO data ready */
1401 #define hp_xfer_cnt_lo 0x18
1402 #define hp_xfer_cnt_mi 0x19
1403 #define hp_xfer_cnt_hi 0x1A
1404 #define hp_xfer_cmd 0x1B
1406 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
1407 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
1408 #define XFER_HOST_MPU 0x02 /* 0 1 0 Transfer Host -> MPU */
1409 #define XFER_MPU_HOST 0x03 /* 0 1 1 Transfer MPU -> Host */
1410 #define XFER_DMA_MPU 0x04 /* 1 0 0 Transfer DMA -> MPU */
1411 #define XFER_MPU_DMA 0x05 /* 1 0 1 Transfer MPU -> DMA */
1412 #define SET_SEMAPHORE 0x06 /* 1 1 0 Set Semaphore */
1413 #define XFER_NOP 0x07 /* 1 1 1 Transfer NOP */
1414 #define XFER_MB_MPU 0x06 /* 1 1 0 Transfer MB -> MPU */
1415 #define XFER_MB_DMA 0x07 /* 1 1 1 Transfer MB -> DMA */
1418 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
1419 #define XFER_HOST_8BIT 0x08 /* 0 1 8 BIT Transfer Size */
1420 #define XFER_HOST_16BIT 0x10 /* 1 0 16 BIT Transfer Size */
1421 #define XFER_HOST_32BIT 0x18 /* 1 1 32 BIT Transfer Size */
1423 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
1424 #define XFER_DMA_16BIT 0x40 /* 1 0 16 BIT Transfer Size */
1426 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
1428 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
1429 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
1430 #define WIDE_HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_16BIT))
1431 #define WIDE_HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_16BIT))
1433 #define hp_host_addr_lo 0x1C
1434 #define hp_host_addr_lmi 0x1D
1435 #define hp_host_addr_hmi 0x1E
1436 #define hp_host_addr_hi 0x1F
1438 #define hp_pio_data 0x20
1439 #define hp_reserved_21 0x21
1440 #define hp_ee_ctrl 0x22
1442 #define EXT_ARB_ACK BIT(7)
1443 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
1444 #define SEE_MS BIT(5)
1445 #define SEE_CS BIT(3)
1446 #define SEE_CLK BIT(2)
1447 #define SEE_DO BIT(1)
1448 #define SEE_DI BIT(0)
1450 #define EE_READ 0x06
1451 #define EE_WRITE 0x05
1452 #define EWEN 0x04
1453 #define EWEN_ADDR 0x03C0
1454 #define EWDS 0x04
1455 #define EWDS_ADDR 0x0000
1457 #define hp_brdctl 0x23
1459 #define DAT_7 BIT(7)
1460 #define DAT_6 BIT(6)
1461 #define DAT_5 BIT(5)
1462 #define BRD_STB BIT(4)
1463 #define BRD_CS BIT(3)
1464 #define BRD_WR BIT(2)
1466 #define hp_reserved_24 0x24
1467 #define hp_reserved_25 0x25
1472 #define hp_bm_ctrl 0x26
1474 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
1475 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
1476 #define BM_XFER_MIN_8 BIT(2) /*Enable bus master transfer of 9 */
1477 #define BIOS_ENA BIT(3) /*Enable BIOS/FLASH Enable */
1478 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
1479 #define FAST_SINGLE BIT(6) /*?? */
1481 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
1483 #define hp_reserved_27 0x27
1485 #define hp_sg_addr 0x28
1486 #define hp_page_ctrl 0x29
1488 #define SCATTER_EN BIT(0)
1489 #define SGRAM_ARAM BIT(1)
1490 #define BIOS_SHADOW BIT(2)
1491 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
1492 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
1494 #define hp_reserved_2A 0x2A
1495 #define hp_pci_cmd_cfg 0x2B
1497 #define IO_SPACE_ENA BIT(0) /*enable I/O space */
1498 #define MEM_SPACE_ENA BIT(1) /*enable memory space */
1499 #define BUS_MSTR_ENA BIT(2) /*enable bus master operation */
1500 #define MEM_WI_ENA BIT(4) /*enable Write and Invalidate */
1501 #define PAR_ERR_RESP BIT(6) /*enable parity error responce. */
1503 #define hp_reserved_2C 0x2C
1505 #define hp_pci_stat_cfg 0x2D
1507 #define DATA_PARITY_ERR BIT(0)
1508 #define REC_TARGET_ABORT BIT(4) /*received Target abort */
1509 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
1510 #define SIG_SYSTEM_ERR BIT(6)
1511 #define DETECTED_PAR_ERR BIT(7)
1513 #define hp_reserved_2E 0x2E
1515 #define hp_sys_status 0x2F
1517 #define SLV_DATA_RDY BIT(0) /*Slave data ready */
1518 #define XFER_CNT_ZERO BIT(1) /*Transfer counter = 0 */
1519 #define BM_FIFO_EMPTY BIT(2) /*FIFO empty */
1520 #define BM_FIFO_FULL BIT(3) /*FIFO full */
1521 #define HOST_OP_DONE BIT(4) /*host operation done */
1522 #define DMA_OP_DONE BIT(5) /*DMA operation done */
1523 #define SLV_OP_DONE BIT(6) /*Slave operation done */
1524 #define PWR_ON_FLAG BIT(7) /*Power on flag */
1526 #define hp_reserved_30 0x30
1528 #define hp_host_status0 0x31
1530 #define HOST_TERM BIT(5) /*Host Terminal Count */
1531 #define HOST_TRSHLD BIT(6) /*Host Threshold */
1532 #define CONNECTED_2_HOST BIT(7) /*Connected to Host */
1534 #define hp_reserved_32 0x32
1536 #define hp_rev_num 0x33
1538 #define REV_A_CONST 0x0E
1539 #define REV_B_CONST 0x0E
1541 #define hp_stack_data 0x34
1542 #define hp_stack_addr 0x35
1544 #define hp_ext_status 0x36
1546 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
1547 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
1548 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
1549 #define FIFO_TC_NOT_ZERO BIT(2) /*FIFO or transfer counter not zero */
1550 #define CHIP_RST_OCCUR BIT(3) /*Chip reset occurs */
1551 #define CMD_ABORTED BIT(4) /*Command aborted */
1552 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
1553 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
1554 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
1555 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
1556 BM_PARITY_ERR | PIO_OVERRUN)
1558 #define hp_int_status 0x37
1560 #define BM_CMD_CMPL BIT(0) /*Bus Master command complete */
1561 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
1562 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
1563 #define BM_FIFO_RDY BIT(4)
1564 #define INT_ASSERTED BIT(5) /* */
1565 #define SRAM_BUSY BIT(6) /*Scatter/Gather RAM busy */
1566 #define CMD_REG_BUSY BIT(7)
1569 #define hp_fifo_cnt 0x38
1570 #define hp_curr_host_cnt 0x39
1571 #define hp_reserved_3A 0x3A
1572 #define hp_fifo_in_addr 0x3B
1574 #define hp_fifo_out_addr 0x3C
1575 #define hp_reserved_3D 0x3D
1576 #define hp_reserved_3E 0x3E
1577 #define hp_reserved_3F 0x3F
1581 extern USHORT default_intena;
1583 #define hp_intena 0x40
1585 #define RESET BITW(7)
1586 #define PROG_HLT BITW(6)
1587 #define PARITY BITW(5)
1588 #define FIFO BITW(4)
1589 #define SEL BITW(3)
1590 #define SCAM_SEL BITW(2)
1591 #define RSEL BITW(1)
1592 #define TIMEOUT BITW(0)
1593 #define BUS_FREE BITW(15)
1594 #define XFER_CNT_0 BITW(14)
1595 #define PHASE BITW(13)
1596 #define IUNKWN BITW(12)
1597 #define ICMD_COMP BITW(11)
1598 #define ITICKLE BITW(10)
1599 #define IDO_STRT BITW(9)
1600 #define ITAR_DISC BITW(8)
1601 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
1602 #define CLR_ALL_INT 0xFFFF
1603 #define CLR_ALL_INT_1 0xFF00
1605 #define hp_intstat 0x42
1607 #define hp_scsisig 0x44
1609 #define SCSI_SEL BIT(7)
1610 #define SCSI_BSY BIT(6)
1611 #define SCSI_REQ BIT(5)
1612 #define SCSI_ACK BIT(4)
1613 #define SCSI_ATN BIT(3)
1614 #define SCSI_CD BIT(2)
1615 #define SCSI_MSG BIT(1)
1616 #define SCSI_IOBIT BIT(0)
1618 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
1619 #define S_CMD_PH (BIT(2) )
1620 #define S_MSGO_PH (BIT(2)+BIT(1) )
1621 #define S_STAT_PH (BIT(2) +BIT(0))
1622 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
1623 #define S_DATAI_PH ( BIT(0))
1624 #define S_DATAO_PH 0x00
1625 #define S_ILL_PH ( BIT(1) )
1627 #define hp_scsictrl_0 0x45
1629 #define NO_ARB BIT(7)
1630 #define SEL_TAR BIT(6)
1631 #define ENA_ATN BIT(4)
1632 #define ENA_RESEL BIT(2)
1633 #define SCSI_RST BIT(1)
1634 #define ENA_SCAM_SEL BIT(0)
1638 #define hp_portctrl_0 0x46
1640 #define SCSI_PORT BIT(7)
1641 #define SCSI_INBIT BIT(6)
1642 #define DMA_PORT BIT(5)
1643 #define DMA_RD BIT(4)
1644 #define HOST_PORT BIT(3)
1645 #define HOST_WRT BIT(2)
1646 #define SCSI_BUS_EN BIT(1)
1647 #define START_TO BIT(0)
1649 #define hp_scsireset 0x47
1651 #define SCSI_TAR BIT(7)
1652 #define SCSI_INI BIT(6)
1653 #define SCAM_EN BIT(5)
1654 #define ACK_HOLD BIT(4)
1655 #define DMA_RESET BIT(3)
1656 #define HPSCSI_RESET BIT(2)
1657 #define PROG_RESET BIT(1)
1658 #define FIFO_CLR BIT(0)
1660 #define hp_xfercnt_0 0x48
1661 #define hp_xfercnt_1 0x49
1662 #define hp_xfercnt_2 0x4A
1663 #define hp_xfercnt_3 0x4B
1665 #define hp_fifodata_0 0x4C
1666 #define hp_fifodata_1 0x4D
1667 #define hp_addstat 0x4E
1669 #define SCAM_TIMER BIT(7)
1670 #define AUTO_RUNNING BIT(6)
1671 #define FAST_SYNC BIT(5)
1672 #define SCSI_MODE8 BIT(3)
1673 #define SCSI_PAR_ERR BIT(0)
1675 #define hp_prgmcnt_0 0x4F
1677 #define AUTO_PC_MASK 0x3F
1679 #define hp_selfid_0 0x50
1680 #define hp_selfid_1 0x51
1681 #define hp_arb_id 0x52
1683 #define ARB_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0))
1685 #define hp_select_id 0x53
1687 #define RESEL_ID (BIT(7) + BIT(6) + BIT(5) + BIT(4))
1688 #define SELECT_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0))
1690 #define hp_synctarg_base 0x54
1691 #define hp_synctarg_12 0x54
1692 #define hp_synctarg_13 0x55
1693 #define hp_synctarg_14 0x56
1694 #define hp_synctarg_15 0x57
1696 #define hp_synctarg_8 0x58
1697 #define hp_synctarg_9 0x59
1698 #define hp_synctarg_10 0x5A
1699 #define hp_synctarg_11 0x5B
1701 #define hp_synctarg_4 0x5C
1702 #define hp_synctarg_5 0x5D
1703 #define hp_synctarg_6 0x5E
1704 #define hp_synctarg_7 0x5F
1706 #define hp_synctarg_0 0x60
1707 #define hp_synctarg_1 0x61
1708 #define hp_synctarg_2 0x62
1709 #define hp_synctarg_3 0x63
1711 #define RATE_20MB 0x00
1712 #define RATE_10MB ( BIT(5))
1713 #define RATE_6_6MB ( BIT(6) )
1714 #define RATE_5MB ( BIT(6)+BIT(5))
1715 #define RATE_4MB (BIT(7) )
1716 #define RATE_3_33MB (BIT(7) +BIT(5))
1717 #define RATE_2_85MB (BIT(7)+BIT(6) )
1718 #define RATE_2_5MB (BIT(7)+BIT(5)+BIT(6))
1719 #define NEXT_CLK BIT(5)
1720 #define SLOWEST_SYNC (BIT(7)+BIT(6)+BIT(5))
1721 #define NARROW_SCSI BIT(4)
1722 #define SYNC_OFFSET (BIT(3) + BIT(2) + BIT(1) + BIT(0))
1723 #define DEFAULT_ASYNC 0x00
1724 #define DEFAULT_OFFSET 0x0F
1726 #define hp_autostart_0 0x64
1727 #define hp_autostart_1 0x65
1728 #define hp_autostart_2 0x66
1729 #define hp_autostart_3 0x67
1733 #define DISABLE 0x00
1734 #define AUTO_IMMED BIT(5)
1735 #define SELECT BIT(6)
1736 #define RESELECT (BIT(6)+BIT(5))
1737 #define BUSFREE BIT(7)
1738 #define XFER_0 (BIT(7)+BIT(5))
1739 #define END_DATA (BIT(7)+BIT(6))
1740 #define MSG_PHZ (BIT(7)+BIT(6)+BIT(5))
1742 #define hp_gp_reg_0 0x68
1743 #define hp_gp_reg_1 0x69
1744 #define hp_gp_reg_2 0x6A
1745 #define hp_gp_reg_3 0x6B
1747 #define hp_seltimeout 0x6C
1750 #define TO_2ms 0x54 /* 2.0503ms */
1751 #define TO_4ms 0x67 /* 3.9959ms */
1753 #define TO_5ms 0x03 /* 4.9152ms */
1754 #define TO_10ms 0x07 /* 11.xxxms */
1755 #define TO_250ms 0x99 /* 250.68ms */
1756 #define TO_290ms 0xB1 /* 289.99ms */
1757 #define TO_350ms 0xD6 /* 350.62ms */
1758 #define TO_417ms 0xFF /* 417.79ms */
1760 #define hp_clkctrl_0 0x6D
1762 #define PWR_DWN BIT(6)
1763 #define ACTdeassert BIT(4)
1764 #define ATNonErr BIT(3)
1765 #define CLK_30MHZ BIT(1)
1766 #define CLK_40MHZ (BIT(1) + BIT(0))
1767 #define CLK_50MHZ BIT(2)
1769 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
1771 #define hp_fiforead 0x6E
1772 #define hp_fifowrite 0x6F
1774 #define hp_offsetctr 0x70
1775 #define hp_xferstat 0x71
1777 #define FIFO_FULL BIT(7)
1778 #define FIFO_EMPTY BIT(6)
1779 #define FIFO_MASK 0x3F /* Mask for the FIFO count value. */
1780 #define FIFO_LEN 0x20
1782 #define hp_portctrl_1 0x72
1784 #define EVEN_HOST_P BIT(5)
1785 #define INVT_SCSI BIT(4)
1786 #define CHK_SCSI_P BIT(3)
1787 #define HOST_MODE8 BIT(0)
1788 #define HOST_MODE16 0x00
1790 #define hp_xfer_pad 0x73
1792 #define ID_UNLOCK BIT(3)
1793 #define XFER_PAD BIT(2)
1795 #define hp_scsidata_0 0x74
1796 #define hp_scsidata_1 0x75
1797 #define hp_timer_0 0x76
1798 #define hp_timer_1 0x77
1800 #define hp_reserved_78 0x78
1801 #define hp_reserved_79 0x79
1802 #define hp_reserved_7A 0x7A
1803 #define hp_reserved_7B 0x7B
1805 #define hp_reserved_7C 0x7C
1806 #define hp_reserved_7D 0x7D
1807 #define hp_reserved_7E 0x7E
1808 #define hp_reserved_7F 0x7F
1810 #define hp_aramBase 0x80
1811 #define BIOS_DATA_OFFSET 0x60
1812 #define BIOS_RELATIVE_CARD 0x64
1817 #define AUTO_LEN 0x80
1818 #define AR0 0x00
1819 #define AR1 BITW(8)
1820 #define AR2 BITW(9)
1821 #define AR3 (BITW(9) + BITW(8))
1822 #define SDATA BITW(10)
1824 #define NOP_OP 0x00 /* Nop command */
1826 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
1828 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
1830 #define CBE_OP (BITW(14)+BITW(12)+BITW(11)) /* Cmp SCSI cmd class & Branch EQ */
1832 #define CBN_OP (BITW(14)+BITW(13)) /* Cmp SCSI cmd class & Branch NOT EQ */
1834 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
1836 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
1839 #define ADATA_OUT 0x00
1840 #define ADATA_IN BITW(8)
1841 #define ACOMMAND BITW(10)
1842 #define ASTATUS (BITW(10)+BITW(8))
1843 #define AMSG_OUT (BITW(10)+BITW(9))
1844 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
1845 #define AILLEGAL (BITW(9)+BITW(8))
1848 #define BRH_OP BITW(13) /* Branch */
1851 #define ALWAYS 0x00
1852 #define EQUAL BITW(8)
1853 #define NOT_EQ BITW(9)
1855 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
1858 #define ATN_SET BITW(8)
1859 #define ATN_RESET BITW(9)
1860 #define XFER_CNT (BITW(9)+BITW(8))
1861 #define FIFO_0 BITW(10)
1862 #define FIFO_NOT0 (BITW(10)+BITW(8))
1863 #define T_USE_SYNC0 (BITW(10)+BITW(9))
1866 #define MPM_OP BITW(15) /* Match phase and move data */
1868 #define MDR_OP (BITW(12)+BITW(11)) /* Move data to Reg. */
1870 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
1873 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
1876 #define D_AR0 0x00
1877 #define D_AR1 BIT(0)
1878 #define D_AR2 BIT(1)
1879 #define D_AR3 (BIT(1) + BIT(0))
1880 #define D_SDATA BIT(2)
1881 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
1884 #define ADR_OP (BITW(13)+BITW(12)) /* Logical AND Reg. w. Data */
1886 #define ADS_OP (BITW(14)+BITW(13)+BITW(12))
1888 #define ODR_OP (BITW(13)+BITW(12)+BITW(11))
1890 #define ODS_OP (BITW(14)+BITW(13)+BITW(12)+BITW(11))
1892 #define STR_OP (BITW(15)+BITW(14)) /* Store to A_Reg. */
1894 #define AINT_ENA1 0x00
1895 #define AINT_STAT1 BITW(8)
1896 #define ASCSI_SIG BITW(9)
1897 #define ASCSI_CNTL (BITW(9)+BITW(8))
1898 #define APORT_CNTL BITW(10)
1899 #define ARST_CNTL (BITW(10)+BITW(8))
1900 #define AXFERCNT0 (BITW(10)+BITW(9))
1901 #define AXFERCNT1 (BITW(10)+BITW(9)+BITW(8))
1902 #define AXFERCNT2 BITW(11)
1903 #define AFIFO_DATA (BITW(11)+BITW(8))
1904 #define ASCSISELID (BITW(11)+BITW(9))
1905 #define ASCSISYNC0 (BITW(11)+BITW(9)+BITW(8))
1908 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
1910 #define SSI_OP (BITW(15)+BITW(11))
1913 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
1914 #define SSI_IDO_STRT (IDO_STRT >> 8)
1915 #define SSI_IDI_STRT (IDO_STRT >> 8)
1917 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
1918 #define SSI_ITICKLE (ITICKLE >> 8)
1920 #define SSI_IUNKWN (IUNKWN >> 8)
1921 #define SSI_INO_CC (IUNKWN >> 8)
1922 #define SSI_IRFAIL (IUNKWN >> 8)
1925 #define NP 0x10 /*Next Phase */
1926 #define NTCMD 0x02 /*Non- Tagged Command start */
1927 #define CMDPZ 0x04 /*Command phase */
1928 #define DINT 0x12 /*Data Out/In interrupt */
1929 #define DI 0x13 /*Data Out */
1930 #define MI 0x14 /*Message In */
1931 #define DC 0x19 /*Disconnect Message */
1932 #define ST 0x1D /*Status Phase */
1933 #define UNKNWN 0x24 /*Unknown bus action */
1934 #define CC 0x25 /*Command Completion failure */
1935 #define TICK 0x26 /*New target reselected us. */
1936 #define RFAIL 0x27 /*Reselection failed */
1937 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
1940 #define ID_MSG_STRT hp_aramBase + 0x00
1941 #define NON_TAG_ID_MSG hp_aramBase + 0x06
1942 #define CMD_STRT hp_aramBase + 0x08
1943 #define SYNC_MSGS hp_aramBase + 0x08
1949 #define TAG_STRT 0x00
1950 #define SELECTION_START 0x00
1951 #define DISCONNECT_START 0x10/2
1952 #define END_DATA_START 0x14/2
1953 #define NONTAG_STRT 0x02/2
1954 #define CMD_ONLY_STRT CMDPZ/2
1955 #define TICKLE_STRT TICK/2
1956 #define SELCHK_STRT SELCHK/2
1961 #define mEEPROM_CLK_DELAY(port) (RD_HARPOON(port+hp_intstat_1))
1963 #define mWAIT_10MS(port) (RD_HARPOON(port+hp_intstat_1))
1966 #define CLR_XFER_CNT(port) (WR_HARPOON(port+hp_xfercnt_0, 0x00))
1968 #define SET_XFER_CNT(port, data) (WR_HARP32(port,hp_xfercnt_0,data))
1970 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
1971 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
1972 xfercnt <<= 16,\
1973 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
1975 #if defined(DOS)
1976 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((USHORT)(port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
1977 addr >>= 16,\
1978 WRW_HARPOON((USHORT)(port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
1979 WR_HARP32(port,hp_xfercnt_0,count),\
1980 WRW_HARPOON((USHORT)(port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
1981 count >>= 16,\
1982 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
1983 #else
1984 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
1985 addr >>= 16,\
1986 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
1987 WR_HARP32(port,hp_xfercnt_0,count),\
1988 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
1989 count >>= 16,\
1990 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
1991 #endif
1993 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
1994 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
1997 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
1998 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
2000 #define ACCEPT_STAT(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
2001 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
2003 #define ACCEPT_STAT_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
2004 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
2006 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
2007 WR_HARPOON(port+hp_scsireset, 0x00))
2009 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
2010 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
2012 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
2013 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
2015 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
2016 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
2018 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
2019 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
2023 #endif
2026 #if (FW_TYPE==_UCB_MGR_)
2027 void ReadNVRam(PSCCBcard pCurrCard,PUCB p_ucb);
2028 void WriteNVRam(PSCCBcard pCurrCard,PUCB p_ucb);
2029 void UpdateCheckSum(u32bits baseport);
2030 #endif // (FW_TYPE==_UCB_MGR_)
2032 #if defined(DOS)
2033 UCHAR sfm(USHORT port, PSCCB pcurrSCCB);
2034 void scsiStartAuto(USHORT port);
2035 UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag);
2036 void ssel(USHORT port, UCHAR p_card);
2037 void sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard);
2038 void sdecm(UCHAR message, USHORT port, UCHAR p_card);
2039 void shandem(USHORT port, UCHAR p_card,PSCCB pCurrSCCB);
2040 void stsyncn(USHORT port, UCHAR p_card);
2041 void sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset);
2042 void sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info);
2043 void sresb(USHORT port, UCHAR p_card);
2044 void sxfrp(USHORT p_port, UCHAR p_card);
2045 void schkdd(USHORT port, UCHAR p_card);
2046 UCHAR RdStack(USHORT port, UCHAR index);
2047 void WrStack(USHORT portBase, UCHAR index, UCHAR data);
2048 UCHAR ChkIfChipInitialized(USHORT ioPort);
2050 #if defined(V302)
2051 UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun);
2052 #endif
2054 void SendMsg(USHORT port, UCHAR message);
2055 void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code);
2056 UCHAR scsellDOS(USHORT p_port, UCHAR targ_id);
2057 #else
2058 UCHAR sfm(ULONG port, PSCCB pcurrSCCB);
2059 void scsiStartAuto(ULONG port);
2060 UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
2061 void ssel(ULONG port, UCHAR p_card);
2062 void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
2063 void sdecm(UCHAR message, ULONG port, UCHAR p_card);
2064 void shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
2065 void stsyncn(ULONG port, UCHAR p_card);
2066 void sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
2067 void sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info);
2068 void sresb(ULONG port, UCHAR p_card);
2069 void sxfrp(ULONG p_port, UCHAR p_card);
2070 void schkdd(ULONG port, UCHAR p_card);
2071 UCHAR RdStack(ULONG port, UCHAR index);
2072 void WrStack(ULONG portBase, UCHAR index, UCHAR data);
2073 UCHAR ChkIfChipInitialized(ULONG ioPort);
2075 #if defined(V302)
2076 UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tar, PUCHAR lun);
2077 #endif
2079 void SendMsg(ULONG port, UCHAR message);
2080 void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code);
2081 #endif
2083 void ssenss(PSCCBcard pCurrCard);
2084 void sinits(PSCCB p_sccb, UCHAR p_card);
2085 void RNVRamData(PNVRamInfo pNvRamInfo);
2087 #if defined(WIDE_SCSI)
2088 #if defined(DOS)
2089 UCHAR siwidn(USHORT port, UCHAR p_card);
2090 void stwidn(USHORT port, UCHAR p_card);
2091 void siwidr(USHORT port, UCHAR width);
2092 #else
2093 UCHAR siwidn(ULONG port, UCHAR p_card);
2094 void stwidn(ULONG port, UCHAR p_card);
2095 void siwidr(ULONG port, UCHAR width);
2096 #endif
2097 #endif
2100 void queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
2101 void queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
2102 void queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB, UCHAR p_card);
2103 void queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
2104 void queueFlushSccb(UCHAR p_card, UCHAR error_code);
2105 void queueAddSccb(PSCCB p_SCCB, UCHAR card);
2106 UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
2107 void utilUpdateResidual(PSCCB p_SCCB);
2108 USHORT CalcCrc16(UCHAR buffer[]);
2109 UCHAR CalcLrc(UCHAR buffer[]);
2112 #if defined(DOS)
2113 void Wait1Second(USHORT p_port);
2114 void Wait(USHORT p_port, UCHAR p_delay);
2115 void utilEEWriteOnOff(USHORT p_port,UCHAR p_mode);
2116 void utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr);
2117 USHORT utilEERead(USHORT p_port, USHORT ee_addr);
2118 USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr);
2119 void utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr);
2120 #else
2121 void Wait1Second(ULONG p_port);
2122 void Wait(ULONG p_port, UCHAR p_delay);
2123 void utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
2124 void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
2125 USHORT utilEERead(ULONG p_port, USHORT ee_addr);
2126 USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr);
2127 void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
2128 #endif
2132 #if defined(OS2)
2133 void far phaseDataOut(ULONG port, UCHAR p_card);
2134 void far phaseDataIn(ULONG port, UCHAR p_card);
2135 void far phaseCommand(ULONG port, UCHAR p_card);
2136 void far phaseStatus(ULONG port, UCHAR p_card);
2137 void far phaseMsgOut(ULONG port, UCHAR p_card);
2138 void far phaseMsgIn(ULONG port, UCHAR p_card);
2139 void far phaseIllegal(ULONG port, UCHAR p_card);
2140 #else
2141 #if defined(DOS)
2142 void phaseDataOut(USHORT port, UCHAR p_card);
2143 void phaseDataIn(USHORT port, UCHAR p_card);
2144 void phaseCommand(USHORT port, UCHAR p_card);
2145 void phaseStatus(USHORT port, UCHAR p_card);
2146 void phaseMsgOut(USHORT port, UCHAR p_card);
2147 void phaseMsgIn(USHORT port, UCHAR p_card);
2148 void phaseIllegal(USHORT port, UCHAR p_card);
2149 #else
2150 void phaseDataOut(ULONG port, UCHAR p_card);
2151 void phaseDataIn(ULONG port, UCHAR p_card);
2152 void phaseCommand(ULONG port, UCHAR p_card);
2153 void phaseStatus(ULONG port, UCHAR p_card);
2154 void phaseMsgOut(ULONG port, UCHAR p_card);
2155 void phaseMsgIn(ULONG port, UCHAR p_card);
2156 void phaseIllegal(ULONG port, UCHAR p_card);
2157 #endif
2158 #endif
2160 #if defined(DOS)
2161 void phaseDecode(USHORT port, UCHAR p_card);
2162 void phaseChkFifo(USHORT port, UCHAR p_card);
2163 void phaseBusFree(USHORT p_port, UCHAR p_card);
2164 #else
2165 void phaseDecode(ULONG port, UCHAR p_card);
2166 void phaseChkFifo(ULONG port, UCHAR p_card);
2167 void phaseBusFree(ULONG p_port, UCHAR p_card);
2168 #endif
2173 #if defined(DOS)
2174 void XbowInit(USHORT port, UCHAR scamFlg);
2175 void BusMasterInit(USHORT p_port);
2176 int DiagXbow(USHORT port);
2177 int DiagBusMaster(USHORT port);
2178 void DiagEEPROM(USHORT p_port);
2179 #else
2180 void XbowInit(ULONG port, UCHAR scamFlg);
2181 void BusMasterInit(ULONG p_port);
2182 int DiagXbow(ULONG port);
2183 int DiagBusMaster(ULONG port);
2184 void DiagEEPROM(ULONG p_port);
2185 #endif
2190 #if defined(DOS)
2191 void busMstrAbort(USHORT port);
2192 UCHAR busMstrTimeOut(USHORT port);
2193 void dataXferProcessor(USHORT port, PSCCBcard pCurrCard);
2194 void busMstrSGDataXferStart(USHORT port, PSCCB pCurrSCCB);
2195 void busMstrDataXferStart(USHORT port, PSCCB pCurrSCCB);
2196 void hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB);
2197 #else
2198 void busMstrAbort(ULONG port);
2199 UCHAR busMstrTimeOut(ULONG port);
2200 void dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
2201 void busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
2202 void busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
2203 void hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
2204 #endif
2205 void hostDataXferRestart(PSCCB currSCCB);
2208 #if defined (DOS)
2209 UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int);
2210 #else
2211 UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int);
2213 #endif
2215 void SccbMgrTableInitAll(void);
2216 void SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
2217 void SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
2221 void scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
2223 #if defined(DOS)
2224 int scarb(USHORT p_port, UCHAR p_sel_type);
2225 void scbusf(USHORT p_port);
2226 void scsel(USHORT p_port);
2227 void scasid(UCHAR p_card, USHORT p_port);
2228 UCHAR scxferc(USHORT p_port, UCHAR p_data);
2229 UCHAR scsendi(USHORT p_port, UCHAR p_id_string[]);
2230 UCHAR sciso(USHORT p_port, UCHAR p_id_string[]);
2231 void scwirod(USHORT p_port, UCHAR p_data_bit);
2232 void scwiros(USHORT p_port, UCHAR p_data_bit);
2233 UCHAR scvalq(UCHAR p_quintet);
2234 UCHAR scsell(USHORT p_port, UCHAR targ_id);
2235 void scwtsel(USHORT p_port);
2236 void inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id);
2237 void scsavdi(UCHAR p_card, USHORT p_port);
2238 #else
2239 int scarb(ULONG p_port, UCHAR p_sel_type);
2240 void scbusf(ULONG p_port);
2241 void scsel(ULONG p_port);
2242 void scasid(UCHAR p_card, ULONG p_port);
2243 UCHAR scxferc(ULONG p_port, UCHAR p_data);
2244 UCHAR scsendi(ULONG p_port, UCHAR p_id_string[]);
2245 UCHAR sciso(ULONG p_port, UCHAR p_id_string[]);
2246 void scwirod(ULONG p_port, UCHAR p_data_bit);
2247 void scwiros(ULONG p_port, UCHAR p_data_bit);
2248 UCHAR scvalq(UCHAR p_quintet);
2249 UCHAR scsell(ULONG p_port, UCHAR targ_id);
2250 void scwtsel(ULONG p_port);
2251 void inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
2252 void scsavdi(UCHAR p_card, ULONG p_port);
2253 #endif
2254 UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[]);
2257 #if defined(DOS)
2258 void autoCmdCmplt(USHORT p_port, UCHAR p_card);
2259 void autoLoadDefaultMap(USHORT p_port);
2260 #else
2261 void autoCmdCmplt(ULONG p_port, UCHAR p_card);
2262 void autoLoadDefaultMap(ULONG p_port);
2263 #endif
2267 #if (FW_TYPE==_SCCB_MGR_)
2268 void OS_start_timer(unsigned long ioport, unsigned long timeout);
2269 void OS_stop_timer(unsigned long ioport, unsigned long timeout);
2270 void OS_disable_int(unsigned char intvec);
2271 void OS_enable_int(unsigned char intvec);
2272 void OS_delay(unsigned long count);
2273 int OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr);
2274 #if !(defined(UNIX) || defined(OS2) || defined(SOLARIS_REAL_MODE))
2275 void OS_Lock(PSCCBMGR_INFO pCardInfo);
2276 void OS_UnLock(PSCCBMGR_INFO pCardInfo);
2277 #endif // if FW_TYPE == ...
2279 #endif
2281 extern SCCBCARD BL_Card[MAX_CARDS];
2282 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
2285 #if defined(OS2)
2286 extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
2287 #else
2288 #if defined(DOS)
2289 extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
2290 #else
2291 extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
2292 #endif
2293 #endif
2295 extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR];
2296 extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
2297 #if defined(DOS) || defined(OS2)
2298 extern UCHAR temp_id_string[ID_STRING_LENGTH];
2299 #endif
2300 extern UCHAR scamHAString[];
2303 extern UCHAR mbCards;
2304 #if defined(BUGBUG)
2305 extern UCHAR debug_int[MAX_CARDS][debug_size];
2306 extern UCHAR debug_index[MAX_CARDS];
2307 void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
2308 #endif
2310 #if (FW_TYPE==_SCCB_MGR_)
2311 #if defined(DOS)
2312 extern UCHAR first_time;
2313 #endif
2314 #endif /* (FW_TYPE==_SCCB_MGR_) */
2316 #if (FW_TYPE==_UCB_MGR_)
2317 #if defined(DOS)
2318 extern u08bits first_time;
2319 #endif
2320 #endif /* (FW_TYPE==_UCB_MGR_) */
2322 #if defined(BUGBUG)
2323 void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
2324 #endif
2326 extern unsigned int SccbGlobalFlags;
2329 #ident "$Id: sccb.c 1.18 1997/06/10 16:47:04 mohan Exp $"
2330 /*----------------------------------------------------------------------
2333 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
2335 * This file is available under both the GNU General Public License
2336 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
2338 * $Workfile: sccb.c $
2340 * Description: Functions relating to handling of the SCCB interface
2341 * between the device driver and the HARPOON.
2343 * $Date: 1997/06/10 16:47:04 $
2345 * $Revision: 1.18 $
2347 *----------------------------------------------------------------------*/
2349 /*#include <globals.h>*/
2351 #if (FW_TYPE==_UCB_MGR_)
2352 /*#include <budi.h>*/
2353 /*#include <budioctl.h>*/
2354 #endif
2356 /*#include <sccbmgr.h>*/
2357 /*#include <blx30.h>*/
2358 /*#include <target.h>*/
2359 /*#include <eeprom.h>*/
2360 /*#include <scsi2.h>*/
2361 /*#include <harpoon.h>*/
2365 #if (FW_TYPE==_SCCB_MGR_)
2366 #define mOS_Lock(card) OS_Lock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo))
2367 #define mOS_UnLock(card) OS_UnLock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo))
2368 #else /* FW_TYPE==_UCB_MGR_ */
2369 #define mOS_Lock(card) OS_Lock((u32bits)(((PSCCBcard)card)->ioPort))
2370 #define mOS_UnLock(card) OS_UnLock((u32bits)(((PSCCBcard)card)->ioPort))
2371 #endif
2375 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
2376 extern SCCBCARD BL_Card[MAX_CARDS];
2378 extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
2379 extern UCHAR mbCards;
2381 #if defined (OS2)
2382 extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
2383 #else
2384 #if defined(DOS)
2385 extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
2386 #else
2387 extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
2388 #endif
2389 #endif
2392 #if defined(BUGBUG)
2393 extern UCHAR debug_int[MAX_CARDS][debug_size];
2394 extern UCHAR debug_index[MAX_CARDS];
2395 void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
2396 #endif
2399 #if (FW_TYPE==_SCCB_MGR_)
2401 /*---------------------------------------------------------------------
2403 * Function: SccbMgr_sense_adapter
2405 * Description: Setup and/or Search for cards and return info to caller.
2407 *---------------------------------------------------------------------*/
2409 int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
2411 #if defined(DOS)
2412 #else
2413 static UCHAR first_time = 1;
2414 #endif
2416 UCHAR i,j,id,ScamFlg;
2417 USHORT temp,temp2,temp3,temp4,temp5,temp6;
2418 #if defined(DOS)
2419 USHORT ioport;
2420 #else
2421 ULONG ioport;
2422 #endif
2423 PNVRamInfo pCurrNvRam;
2425 #if defined(DOS)
2426 ioport = (USHORT)pCardInfo->si_baseaddr;
2427 #else
2428 ioport = pCardInfo->si_baseaddr;
2429 #endif
2432 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
2433 return((int)FAILURE);
2435 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
2436 return((int)FAILURE);
2438 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
2439 return((int)FAILURE);
2441 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
2442 return((int)FAILURE);
2445 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
2447 /* For new Harpoon then check for sub_device ID LSB
2448 the bits(0-3) must be all ZERO for compatible with
2449 current version of SCCBMgr, else skip this Harpoon
2450 device. */
2452 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
2453 return((int)FAILURE);
2456 if (first_time)
2458 SccbMgrTableInitAll();
2459 first_time = 0;
2460 mbCards = 0;
2463 if(RdStack(ioport, 0) != 0x00) {
2464 if(ChkIfChipInitialized(ioport) == FALSE)
2466 pCurrNvRam = NULL;
2467 WR_HARPOON(ioport+hp_semaphore, 0x00);
2468 XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
2469 DiagEEPROM(ioport);
2471 else
2473 if(mbCards < MAX_MB_CARDS) {
2474 pCurrNvRam = &nvRamInfo[mbCards];
2475 mbCards++;
2476 pCurrNvRam->niBaseAddr = ioport;
2477 RNVRamData(pCurrNvRam);
2478 }else
2479 return((int) FAILURE);
2481 }else
2482 pCurrNvRam = NULL;
2483 #if defined (NO_BIOS_OPTION)
2484 pCurrNvRam = NULL;
2485 XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
2486 DiagEEPROM(ioport);
2487 #endif /* No BIOS Option */
2489 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
2490 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
2492 if(pCurrNvRam)
2493 pCardInfo->si_id = pCurrNvRam->niAdapId;
2494 else
2495 pCardInfo->si_id = (UCHAR)(utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
2496 (UCHAR)0x0FF);
2498 pCardInfo->si_lun = 0x00;
2499 pCardInfo->si_fw_revision = ORION_FW_REV;
2500 temp2 = 0x0000;
2501 temp3 = 0x0000;
2502 temp4 = 0x0000;
2503 temp5 = 0x0000;
2504 temp6 = 0x0000;
2506 for (id = 0; id < (16/2); id++) {
2508 if(pCurrNvRam){
2509 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
2510 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
2511 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
2512 }else
2513 temp = utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
2515 for (i = 0; i < 2; temp >>=8,i++) {
2517 temp2 >>= 1;
2518 temp3 >>= 1;
2519 temp4 >>= 1;
2520 temp5 >>= 1;
2521 temp6 >>= 1;
2522 switch (temp & 0x3)
2524 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
2525 temp6 |= 0x8000; /* Fall through */
2526 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
2527 temp5 |= 0x8000; /* Fall through */
2528 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
2529 temp2 |= 0x8000; /* Fall through */
2530 case AUTO_RATE_00: /* Asynchronous */
2531 break;
2534 if (temp & DISC_ENABLE_BIT)
2535 temp3 |= 0x8000;
2537 if (temp & WIDE_NEGO_BIT)
2538 temp4 |= 0x8000;
2543 pCardInfo->si_per_targ_init_sync = temp2;
2544 pCardInfo->si_per_targ_no_disc = temp3;
2545 pCardInfo->si_per_targ_wide_nego = temp4;
2546 pCardInfo->si_per_targ_fast_nego = temp5;
2547 pCardInfo->si_per_targ_ultra_nego = temp6;
2549 if(pCurrNvRam)
2550 i = pCurrNvRam->niSysConf;
2551 else
2552 i = (UCHAR)(utilEERead(ioport, (SYSTEM_CONFIG/2)));
2554 if(pCurrNvRam)
2555 ScamFlg = pCurrNvRam->niScamConf;
2556 else
2557 ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2);
2559 pCardInfo->si_flags = 0x0000;
2561 if (i & 0x01)
2562 pCardInfo->si_flags |= SCSI_PARITY_ENA;
2564 if (!(i & 0x02))
2565 pCardInfo->si_flags |= SOFT_RESET;
2567 if (i & 0x10)
2568 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
2570 if (ScamFlg & SCAM_ENABLED)
2571 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
2573 if (ScamFlg & SCAM_LEVEL2)
2574 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
2576 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
2577 if (i & 0x04) {
2578 j |= SCSI_TERM_ENA_L;
2580 WR_HARPOON(ioport+hp_bm_ctrl, j );
2582 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
2583 if (i & 0x08) {
2584 j |= SCSI_TERM_ENA_H;
2586 WR_HARPOON(ioport+hp_ee_ctrl, j );
2588 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
2590 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
2592 pCardInfo->si_card_family = HARPOON_FAMILY;
2593 pCardInfo->si_bustype = BUSTYPE_PCI;
2595 if(pCurrNvRam){
2596 pCardInfo->si_card_model[0] = '9';
2597 switch(pCurrNvRam->niModel & 0x0f){
2598 case MODEL_LT:
2599 pCardInfo->si_card_model[1] = '3';
2600 pCardInfo->si_card_model[2] = '0';
2601 break;
2602 case MODEL_LW:
2603 pCardInfo->si_card_model[1] = '5';
2604 pCardInfo->si_card_model[2] = '0';
2605 break;
2606 case MODEL_DL:
2607 pCardInfo->si_card_model[1] = '3';
2608 pCardInfo->si_card_model[2] = '2';
2609 break;
2610 case MODEL_DW:
2611 pCardInfo->si_card_model[1] = '5';
2612 pCardInfo->si_card_model[2] = '2';
2613 break;
2615 }else{
2616 temp = utilEERead(ioport, (MODEL_NUMB_0/2));
2617 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
2618 temp = utilEERead(ioport, (MODEL_NUMB_2/2));
2620 pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
2621 pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
2624 if (pCardInfo->si_card_model[1] == '3')
2626 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
2627 pCardInfo->si_flags |= LOW_BYTE_TERM;
2629 else if (pCardInfo->si_card_model[2] == '0')
2631 temp = RD_HARPOON(ioport+hp_xfer_pad);
2632 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
2633 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
2634 pCardInfo->si_flags |= LOW_BYTE_TERM;
2635 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
2636 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
2637 pCardInfo->si_flags |= HIGH_BYTE_TERM;
2638 WR_HARPOON(ioport+hp_xfer_pad, temp);
2640 else
2642 temp = RD_HARPOON(ioport+hp_ee_ctrl);
2643 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
2644 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
2645 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
2646 temp3 = 0;
2647 for (i = 0; i < 8; i++)
2649 temp3 <<= 1;
2650 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
2651 temp3 |= 1;
2652 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
2653 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
2655 WR_HARPOON(ioport+hp_ee_ctrl, temp);
2656 WR_HARPOON(ioport+hp_xfer_pad, temp2);
2657 if (!(temp3 & BIT(7)))
2658 pCardInfo->si_flags |= LOW_BYTE_TERM;
2659 if (!(temp3 & BIT(6)))
2660 pCardInfo->si_flags |= HIGH_BYTE_TERM;
2664 ARAM_ACCESS(ioport);
2666 for ( i = 0; i < 4; i++ ) {
2668 pCardInfo->si_XlatInfo[i] =
2669 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
2672 /* return with -1 if no sort, else return with
2673 logical card number sorted by BIOS (zero-based) */
2675 pCardInfo->si_relative_cardnum =
2676 (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
2678 SGRAM_ACCESS(ioport);
2680 s_PhaseTbl[0] = phaseDataOut;
2681 s_PhaseTbl[1] = phaseDataIn;
2682 s_PhaseTbl[2] = phaseIllegal;
2683 s_PhaseTbl[3] = phaseIllegal;
2684 s_PhaseTbl[4] = phaseCommand;
2685 s_PhaseTbl[5] = phaseStatus;
2686 s_PhaseTbl[6] = phaseMsgOut;
2687 s_PhaseTbl[7] = phaseMsgIn;
2689 pCardInfo->si_present = 0x01;
2691 #if defined(BUGBUG)
2694 for (i = 0; i < MAX_CARDS; i++) {
2696 for (id=0; id<debug_size; id++)
2697 debug_int[i][id] = (UCHAR)0x00;
2698 debug_index[i] = 0;
2701 #endif
2703 return(0);
2707 /*---------------------------------------------------------------------
2709 * Function: SccbMgr_config_adapter
2711 * Description: Setup adapter for normal operation (hard reset).
2713 *---------------------------------------------------------------------*/
2715 #if defined(DOS)
2716 USHORT SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
2717 #else
2718 ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
2719 #endif
2721 PSCCBcard CurrCard = NULL;
2722 PNVRamInfo pCurrNvRam;
2723 UCHAR i,j,thisCard, ScamFlg;
2724 USHORT temp,sync_bit_map,id;
2725 #if defined(DOS)
2726 USHORT ioport;
2727 #else
2728 ULONG ioport;
2729 #endif
2731 #if defined(DOS)
2732 ioport = (USHORT)pCardInfo->si_baseaddr;
2733 #else
2734 ioport = pCardInfo->si_baseaddr;
2735 #endif
2737 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
2739 if (thisCard == MAX_CARDS) {
2741 return(FAILURE);
2744 if (BL_Card[thisCard].ioPort == ioport) {
2746 CurrCard = &BL_Card[thisCard];
2747 SccbMgrTableInitCard(CurrCard,thisCard);
2748 break;
2751 else if (BL_Card[thisCard].ioPort == 0x00) {
2753 BL_Card[thisCard].ioPort = ioport;
2754 CurrCard = &BL_Card[thisCard];
2756 if(mbCards)
2757 for(i = 0; i < mbCards; i++){
2758 if(CurrCard->ioPort == nvRamInfo[i].niBaseAddr)
2759 CurrCard->pNvRamInfo = &nvRamInfo[i];
2761 SccbMgrTableInitCard(CurrCard,thisCard);
2762 CurrCard->cardIndex = thisCard;
2763 CurrCard->cardInfo = pCardInfo;
2765 break;
2769 pCurrNvRam = CurrCard->pNvRamInfo;
2771 if(pCurrNvRam){
2772 ScamFlg = pCurrNvRam->niScamConf;
2774 else{
2775 ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2);
2779 BusMasterInit(ioport);
2780 XbowInit(ioport, ScamFlg);
2782 #if defined (NO_BIOS_OPTION)
2785 if (DiagXbow(ioport)) return(FAILURE);
2786 if (DiagBusMaster(ioport)) return(FAILURE);
2788 #endif /* No BIOS Option */
2790 autoLoadDefaultMap(ioport);
2793 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
2795 WR_HARPOON(ioport+hp_selfid_0, id);
2796 WR_HARPOON(ioport+hp_selfid_1, 0x00);
2797 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
2798 CurrCard->ourId = pCardInfo->si_id;
2800 i = (UCHAR) pCardInfo->si_flags;
2801 if (i & SCSI_PARITY_ENA)
2802 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
2804 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
2805 if (i & LOW_BYTE_TERM)
2806 j |= SCSI_TERM_ENA_L;
2807 WR_HARPOON(ioport+hp_bm_ctrl, j);
2809 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
2810 if (i & HIGH_BYTE_TERM)
2811 j |= SCSI_TERM_ENA_H;
2812 WR_HARPOON(ioport+hp_ee_ctrl, j );
2815 if (!(pCardInfo->si_flags & SOFT_RESET)) {
2817 sresb(ioport,thisCard);
2819 scini(thisCard, pCardInfo->si_id, 0);
2824 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
2825 CurrCard->globalFlags |= F_NO_FILTER;
2827 if(pCurrNvRam){
2828 if(pCurrNvRam->niSysConf & 0x10)
2829 CurrCard->globalFlags |= F_GREEN_PC;
2831 else{
2832 if (utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
2833 CurrCard->globalFlags |= F_GREEN_PC;
2836 /* Set global flag to indicate Re-Negotiation to be done on all
2837 ckeck condition */
2838 if(pCurrNvRam){
2839 if(pCurrNvRam->niScsiConf & 0x04)
2840 CurrCard->globalFlags |= F_DO_RENEGO;
2842 else{
2843 if (utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
2844 CurrCard->globalFlags |= F_DO_RENEGO;
2847 if(pCurrNvRam){
2848 if(pCurrNvRam->niScsiConf & 0x08)
2849 CurrCard->globalFlags |= F_CONLUN_IO;
2851 else{
2852 if (utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
2853 CurrCard->globalFlags |= F_CONLUN_IO;
2857 temp = pCardInfo->si_per_targ_no_disc;
2859 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
2861 if (temp & id)
2862 sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
2865 sync_bit_map = 0x0001;
2867 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
2869 if(pCurrNvRam){
2870 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
2871 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
2872 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
2873 }else
2874 temp = utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
2876 for (i = 0; i < 2; temp >>=8,i++) {
2878 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
2880 sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
2883 else {
2884 sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
2885 sccbMgrTbl[thisCard][id*2+i].TarEEValue =
2886 (UCHAR)(temp & ~EE_SYNC_MASK);
2889 #if defined(WIDE_SCSI)
2890 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
2891 (id*2+i >= 8)){
2893 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
2895 sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
2899 else { /* NARROW SCSI */
2900 sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
2903 #else
2904 sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
2905 #endif
2908 sync_bit_map <<= 1;
2915 WR_HARPOON((ioport+hp_semaphore),
2916 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
2918 #if defined(DOS)
2919 return((USHORT)CurrCard);
2920 #else
2921 return((ULONG)CurrCard);
2922 #endif
2925 #else /* end (FW_TYPE==_SCCB_MGR_) */
2929 STATIC s16bits FP_PresenceCheck(PMGR_INFO pMgrInfo)
2931 PMGR_ENTRYPNTS pMgr_EntryPnts = &pMgrInfo->mi_Functions;
2933 pMgr_EntryPnts->UCBMgr_probe_adapter = probe_adapter;
2934 pMgr_EntryPnts->UCBMgr_init_adapter = init_adapter;
2935 pMgr_EntryPnts->UCBMgr_start_UCB = SccbMgr_start_sccb;
2936 pMgr_EntryPnts->UCBMgr_build_UCB = build_UCB;
2937 pMgr_EntryPnts->UCBMgr_abort_UCB = SccbMgr_abort_sccb;
2938 pMgr_EntryPnts->UCBMgr_my_int = SccbMgr_my_int;
2939 pMgr_EntryPnts->UCBMgr_isr = SccbMgr_isr;
2940 pMgr_EntryPnts->UCBMgr_scsi_reset = SccbMgr_scsi_reset;
2941 pMgr_EntryPnts->UCBMgr_timer_expired = SccbMgr_timer_expired;
2942 #ifndef NO_IOCTLS
2943 pMgr_EntryPnts->UCBMgr_unload_card = SccbMgr_unload_card;
2944 pMgr_EntryPnts->UCBMgr_save_foreign_state =
2945 SccbMgr_save_foreign_state;
2946 pMgr_EntryPnts->UCBMgr_restore_foreign_state =
2947 SccbMgr_restore_foreign_state;
2948 pMgr_EntryPnts->UCBMgr_restore_native_state =
2949 SccbMgr_restore_native_state;
2950 #endif /*NO_IOCTLS*/
2952 pMgrInfo->mi_SGListFormat=0x01;
2953 pMgrInfo->mi_DataPtrFormat=0x01;
2954 pMgrInfo->mi_MaxSGElements= (u16bits) 0xffffffff;
2955 pMgrInfo->mi_MgrPrivateLen=sizeof(SCCB);
2956 pMgrInfo->mi_PCIVendorID=BL_VENDOR_ID;
2957 pMgrInfo->mi_PCIDeviceID=FP_DEVICE_ID;
2958 pMgrInfo->mi_MgrAttributes= ATTR_IO_MAPPED +
2959 ATTR_PHYSICAL_ADDRESS +
2960 ATTR_VIRTUAL_ADDRESS +
2961 ATTR_OVERLAPPED_IO_IOCTLS_OK;
2962 pMgrInfo->mi_IoRangeLen = 256;
2963 return(0);
2968 /*---------------------------------------------------------------------
2970 * Function: probe_adapter
2972 * Description: Setup and/or Search for cards and return info to caller.
2974 *---------------------------------------------------------------------*/
2975 STATIC s32bits probe_adapter(PADAPTER_INFO pAdapterInfo)
2977 u16bits temp,temp2,temp3,temp4;
2978 u08bits i,j,id;
2980 #if defined(DOS)
2981 #else
2982 static u08bits first_time = 1;
2983 #endif
2984 BASE_PORT ioport;
2985 PNVRamInfo pCurrNvRam;
2987 ioport = (BASE_PORT)pAdapterInfo->ai_baseaddr;
2991 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
2992 return(1);
2994 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
2995 return(2);
2997 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
2998 return(3);
3000 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
3001 return(4);
3004 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
3007 /* For new Harpoon then check for sub_device ID LSB
3008 the bits(0-3) must be all ZERO for compatible with
3009 current version of SCCBMgr, else skip this Harpoon
3010 device. */
3012 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
3013 return(5);
3016 if (first_time) {
3018 SccbMgrTableInitAll();
3019 first_time = 0;
3020 mbCards = 0;
3023 if(RdStack(ioport, 0) != 0x00) {
3024 if(ChkIfChipInitialized(ioport) == FALSE)
3026 pCurrNvRam = NULL;
3027 WR_HARPOON(ioport+hp_semaphore, 0x00);
3028 XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
3029 DiagEEPROM(ioport);
3031 else
3033 if(mbCards < MAX_MB_CARDS) {
3034 pCurrNvRam = &nvRamInfo[mbCards];
3035 mbCards++;
3036 pCurrNvRam->niBaseAddr = ioport;
3037 RNVRamData(pCurrNvRam);
3038 }else
3039 return((int) FAILURE);
3041 }else
3042 pCurrNvRam = NULL;
3044 #if defined (NO_BIOS_OPTION)
3045 pCurrNvRam = NULL;
3046 XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
3047 DiagEEPROM(ioport);
3048 #endif /* No BIOS Option */
3050 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
3051 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
3053 if(pCurrNvRam)
3054 pAdapterInfo->ai_id = pCurrNvRam->niAdapId;
3055 else
3056 pAdapterInfo->ai_id = (u08bits)(utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
3057 (u08bits)0x0FF);
3059 pAdapterInfo->ai_lun = 0x00;
3060 pAdapterInfo->ai_fw_revision[0] = '3';
3061 pAdapterInfo->ai_fw_revision[1] = '1';
3062 pAdapterInfo->ai_fw_revision[2] = '1';
3063 pAdapterInfo->ai_fw_revision[3] = ' ';
3064 pAdapterInfo->ai_NumChannels = 1;
3066 temp2 = 0x0000;
3067 temp3 = 0x0000;
3068 temp4 = 0x0000;
3070 for (id = 0; id < (16/2); id++) {
3072 if(pCurrNvRam){
3073 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
3074 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
3075 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
3076 }else
3077 temp = utilEERead(ioport, (u16bits)((SYNC_RATE_TBL/2)+id));
3079 for (i = 0; i < 2; temp >>=8,i++) {
3081 if ((temp & 0x03) != AUTO_RATE_00) {
3083 temp2 >>= 0x01;
3084 temp2 |= 0x8000;
3087 else {
3088 temp2 >>= 0x01;
3091 if (temp & DISC_ENABLE_BIT) {
3093 temp3 >>= 0x01;
3094 temp3 |= 0x8000;
3097 else {
3098 temp3 >>= 0x01;
3101 if (temp & WIDE_NEGO_BIT) {
3103 temp4 >>= 0x01;
3104 temp4 |= 0x8000;
3107 else {
3108 temp4 >>= 0x01;
3114 pAdapterInfo->ai_per_targ_init_sync = temp2;
3115 pAdapterInfo->ai_per_targ_no_disc = temp3;
3116 pAdapterInfo->ai_per_targ_wide_nego = temp4;
3117 if(pCurrNvRam)
3118 i = pCurrNvRam->niSysConf;
3119 else
3120 i = (u08bits)(utilEERead(ioport, (SYSTEM_CONFIG/2)));
3123 ** interrupts always level-triggered for FlashPoint
3125 pAdapterInfo->ai_stateinfo |= LEVEL_TRIG;
3127 if (i & 0x01)
3128 pAdapterInfo->ai_stateinfo |= SCSI_PARITY_ENA;
3130 if (i & 0x02) /* SCSI Bus reset in AutoSCSI Set ? */
3132 if(pCurrNvRam)
3134 j = pCurrNvRam->niScamConf;
3136 else
3138 j = (u08bits) utilEERead(ioport, SCAM_CONFIG/2);
3140 if(j & SCAM_ENABLED)
3142 if(j & SCAM_LEVEL2)
3144 pAdapterInfo->ai_stateinfo |= SCAM2_ENA;
3146 else
3148 pAdapterInfo->ai_stateinfo |= SCAM1_ENA;
3152 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
3153 if (i & 0x04) {
3154 j |= SCSI_TERM_ENA_L;
3155 pAdapterInfo->ai_stateinfo |= LOW_BYTE_TERM_ENA;
3157 WR_HARPOON(ioport+hp_bm_ctrl, j );
3159 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
3160 if (i & 0x08) {
3161 j |= SCSI_TERM_ENA_H;
3162 pAdapterInfo->ai_stateinfo |= HIGH_BYTE_TERM_ENA;
3164 WR_HARPOON(ioport+hp_ee_ctrl, j );
3166 if(RD_HARPOON(ioport + hp_page_ctrl) & BIOS_SHADOW)
3168 pAdapterInfo->ai_FlashRomSize = 64 * 1024; /* 64k ROM */
3170 else
3172 pAdapterInfo->ai_FlashRomSize = 32 * 1024; /* 32k ROM */
3175 pAdapterInfo->ai_stateinfo |= (FAST20_ENA | TAG_QUEUE_ENA);
3176 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
3178 pAdapterInfo->ai_attributes |= (WIDE_CAPABLE | FAST20_CAPABLE
3179 | SCAM2_CAPABLE
3180 | TAG_QUEUE_CAPABLE
3181 | SUPRESS_UNDERRRUNS_CAPABLE
3182 | SCSI_PARITY_CAPABLE);
3183 pAdapterInfo->ai_MaxTarg = 16;
3184 pAdapterInfo->ai_MaxLun = 32;
3186 else
3188 pAdapterInfo->ai_attributes |= (FAST20_CAPABLE | SCAM2_CAPABLE
3189 | TAG_QUEUE_CAPABLE
3190 | SUPRESS_UNDERRRUNS_CAPABLE
3191 | SCSI_PARITY_CAPABLE);
3192 pAdapterInfo->ai_MaxTarg = 8;
3193 pAdapterInfo->ai_MaxLun = 8;
3196 pAdapterInfo->ai_product_family = HARPOON_FAMILY;
3197 pAdapterInfo->ai_HBAbustype = BUSTYPE_PCI;
3199 for (i=0;i<CARD_MODEL_NAMELEN;i++)
3201 pAdapterInfo->ai_card_model[i]=' '; /* initialize the ai_card_model */
3204 if(pCurrNvRam){
3205 pAdapterInfo->ai_card_model[0] = '9';
3206 switch(pCurrNvRam->niModel & 0x0f){
3207 case MODEL_LT:
3208 pAdapterInfo->ai_card_model[1] = '3';
3209 pAdapterInfo->ai_card_model[2] = '0';
3210 break;
3211 case MODEL_LW:
3212 pAdapterInfo->ai_card_model[1] = '5';
3213 pAdapterInfo->ai_card_model[2] = '0';
3214 break;
3215 case MODEL_DL:
3216 pAdapterInfo->ai_card_model[1] = '3';
3217 pAdapterInfo->ai_card_model[2] = '2';
3218 break;
3219 case MODEL_DW:
3220 pAdapterInfo->ai_card_model[1] = '5';
3221 pAdapterInfo->ai_card_model[2] = '2';
3222 break;
3224 }else{
3225 temp = utilEERead(ioport, (MODEL_NUMB_0/2));
3226 pAdapterInfo->ai_card_model[0] = (u08bits)(temp >> 8);
3227 temp = utilEERead(ioport, (MODEL_NUMB_2/2));
3229 pAdapterInfo->ai_card_model[1] = (u08bits)(temp & 0x00FF);
3230 pAdapterInfo->ai_card_model[2] = (u08bits)(temp >> 8);
3235 pAdapterInfo->ai_FiberProductType = 0;
3237 pAdapterInfo->ai_secondary_range = 0;
3239 for (i=0;i<WORLD_WIDE_NAMELEN;i++)
3241 pAdapterInfo->ai_worldwidename[i]='\0';
3244 for (i=0;i<VENDOR_NAMELEN;i++)
3246 pAdapterInfo->ai_vendorstring[i]='\0';
3248 pAdapterInfo->ai_vendorstring[0]='B';
3249 pAdapterInfo->ai_vendorstring[1]='U';
3250 pAdapterInfo->ai_vendorstring[2]='S';
3251 pAdapterInfo->ai_vendorstring[3]='L';
3252 pAdapterInfo->ai_vendorstring[4]='O';
3253 pAdapterInfo->ai_vendorstring[5]='G';
3254 pAdapterInfo->ai_vendorstring[6]='I';
3255 pAdapterInfo->ai_vendorstring[7]='C';
3257 for (i=0;i<FAMILY_NAMELEN;i++)
3259 pAdapterInfo->ai_AdapterFamilyString[i]='\0';
3261 pAdapterInfo->ai_AdapterFamilyString[0]='F';
3262 pAdapterInfo->ai_AdapterFamilyString[1]='L';
3263 pAdapterInfo->ai_AdapterFamilyString[2]='A';
3264 pAdapterInfo->ai_AdapterFamilyString[3]='S';
3265 pAdapterInfo->ai_AdapterFamilyString[4]='H';
3266 pAdapterInfo->ai_AdapterFamilyString[5]='P';
3267 pAdapterInfo->ai_AdapterFamilyString[6]='O';
3268 pAdapterInfo->ai_AdapterFamilyString[7]='I';
3269 pAdapterInfo->ai_AdapterFamilyString[8]='N';
3270 pAdapterInfo->ai_AdapterFamilyString[9]='T';
3272 ARAM_ACCESS(ioport);
3274 for ( i = 0; i < 4; i++ ) {
3276 pAdapterInfo->ai_XlatInfo[i] =
3277 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
3280 /* return with -1 if no sort, else return with
3281 logical card number sorted by BIOS (zero-based) */
3284 pAdapterInfo->ai_relative_cardnum =
3285 (u08bits)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
3287 SGRAM_ACCESS(ioport);
3289 s_PhaseTbl[0] = phaseDataOut;
3290 s_PhaseTbl[1] = phaseDataIn;
3291 s_PhaseTbl[2] = phaseIllegal;
3292 s_PhaseTbl[3] = phaseIllegal;
3293 s_PhaseTbl[4] = phaseCommand;
3294 s_PhaseTbl[5] = phaseStatus;
3295 s_PhaseTbl[6] = phaseMsgOut;
3296 s_PhaseTbl[7] = phaseMsgIn;
3298 pAdapterInfo->ai_present = 0x01;
3300 #if defined(BUGBUG)
3303 for (i = 0; i < MAX_CARDS; i++) {
3305 for (id=0; id<debug_size; id++)
3306 debug_int[i][id] = (u08bits)0x00;
3307 debug_index[i] = 0;
3310 #endif
3312 return(0);
3319 /*---------------------------------------------------------------------
3321 * Function: init_adapter, exported to BUDI via UCBMgr_init_adapter entry
3324 * Description: Setup adapter for normal operation (hard reset).
3326 *---------------------------------------------------------------------*/
3327 STATIC CARD_HANDLE init_adapter(PADAPTER_INFO pCardInfo)
3329 PSCCBcard CurrCard;
3330 PNVRamInfo pCurrNvRam;
3331 u08bits i,j,thisCard, ScamFlg;
3332 u16bits temp,sync_bit_map,id;
3333 BASE_PORT ioport;
3335 ioport = (BASE_PORT)pCardInfo->ai_baseaddr;
3337 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
3339 if (thisCard == MAX_CARDS) {
3341 return(FAILURE);
3344 if (BL_Card[thisCard].ioPort == ioport) {
3346 CurrCard = &BL_Card[thisCard];
3347 SccbMgrTableInitCard(CurrCard,thisCard);
3348 break;
3351 else if (BL_Card[thisCard].ioPort == 0x00) {
3353 BL_Card[thisCard].ioPort = ioport;
3354 CurrCard = &BL_Card[thisCard];
3356 if(mbCards)
3357 for(i = 0; i < mbCards; i++){
3358 if(CurrCard->ioPort == nvRamInfo[i].niBaseAddr)
3359 CurrCard->pNvRamInfo = &nvRamInfo[i];
3361 SccbMgrTableInitCard(CurrCard,thisCard);
3362 CurrCard->cardIndex = thisCard;
3363 CurrCard->cardInfo = pCardInfo;
3365 break;
3369 pCurrNvRam = CurrCard->pNvRamInfo;
3372 if(pCurrNvRam){
3373 ScamFlg = pCurrNvRam->niScamConf;
3375 else{
3376 ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2);
3380 BusMasterInit(ioport);
3381 XbowInit(ioport, ScamFlg);
3383 #if defined (NO_BIOS_OPTION)
3386 if (DiagXbow(ioport)) return(FAILURE);
3387 if (DiagBusMaster(ioport)) return(FAILURE);
3389 #endif /* No BIOS Option */
3391 autoLoadDefaultMap(ioport);
3394 for (i = 0,id = 0x01; i != pCardInfo->ai_id; i++,id <<= 1){}
3396 WR_HARPOON(ioport+hp_selfid_0, id);
3397 WR_HARPOON(ioport+hp_selfid_1, 0x00);
3398 WR_HARPOON(ioport+hp_arb_id, pCardInfo->ai_id);
3399 CurrCard->ourId = (unsigned char) pCardInfo->ai_id;
3401 i = (u08bits) pCardInfo->ai_stateinfo;
3402 if (i & SCSI_PARITY_ENA)
3403 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
3405 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
3406 if (i & LOW_BYTE_TERM_ENA)
3407 j |= SCSI_TERM_ENA_L;
3408 WR_HARPOON(ioport+hp_bm_ctrl, j);
3410 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
3411 if (i & HIGH_BYTE_TERM_ENA)
3412 j |= SCSI_TERM_ENA_H;
3413 WR_HARPOON(ioport+hp_ee_ctrl, j );
3416 if (!(pCardInfo->ai_stateinfo & NO_RESET_IN_INIT)) {
3418 sresb(ioport,thisCard);
3420 scini(thisCard, (u08bits) pCardInfo->ai_id, 0);
3425 if (pCardInfo->ai_stateinfo & SUPRESS_UNDERRRUNS_ENA)
3426 CurrCard->globalFlags |= F_NO_FILTER;
3428 if(pCurrNvRam){
3429 if(pCurrNvRam->niSysConf & 0x10)
3430 CurrCard->globalFlags |= F_GREEN_PC;
3432 else{
3433 if (utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
3434 CurrCard->globalFlags |= F_GREEN_PC;
3437 /* Set global flag to indicate Re-Negotiation to be done on all
3438 ckeck condition */
3439 if(pCurrNvRam){
3440 if(pCurrNvRam->niScsiConf & 0x04)
3441 CurrCard->globalFlags |= F_DO_RENEGO;
3443 else{
3444 if (utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
3445 CurrCard->globalFlags |= F_DO_RENEGO;
3448 if(pCurrNvRam){
3449 if(pCurrNvRam->niScsiConf & 0x08)
3450 CurrCard->globalFlags |= F_CONLUN_IO;
3452 else{
3453 if (utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
3454 CurrCard->globalFlags |= F_CONLUN_IO;
3457 temp = pCardInfo->ai_per_targ_no_disc;
3459 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
3461 if (temp & id)
3462 sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
3465 sync_bit_map = 0x0001;
3467 for (id = 0; id < (MAX_SCSI_TAR/2); id++){
3469 if(pCurrNvRam){
3470 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
3471 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
3472 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
3473 }else
3474 temp = utilEERead(ioport, (u16bits)((SYNC_RATE_TBL/2)+id));
3476 for (i = 0; i < 2; temp >>=8,i++){
3478 if (pCardInfo->ai_per_targ_init_sync & sync_bit_map){
3480 sccbMgrTbl[thisCard][id*2+i].TarEEValue = (u08bits)temp;
3483 else {
3484 sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
3485 sccbMgrTbl[thisCard][id*2+i].TarEEValue =
3486 (u08bits)(temp & ~EE_SYNC_MASK);
3489 #if defined(WIDE_SCSI)
3490 /* if ((pCardInfo->ai_per_targ_wide_nego & sync_bit_map) ||
3491 (id*2+i >= 8)){
3493 if (pCardInfo->ai_per_targ_wide_nego & sync_bit_map){
3495 sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
3499 else { /* NARROW SCSI */
3500 sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
3503 #else
3504 sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
3505 #endif
3508 sync_bit_map <<= 1;
3513 pCardInfo->ai_SGListFormat=0x01;
3514 pCardInfo->ai_DataPtrFormat=0x01;
3515 pCardInfo->ai_AEN_mask &= SCSI_RESET_COMPLETE;
3517 WR_HARPOON((ioport+hp_semaphore),
3518 (u08bits)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
3520 return((u32bits)CurrCard);
3525 /*---------------------------------------------------------------------
3527 * Function: build_ucb, exported to BUDI via UCBMgr_build_ucb entry
3529 * Description: prepare fw portion of ucb. do not start, resource not guaranteed
3530 * so don't manipulate anything that's derived from states which
3531 * may change
3533 *---------------------------------------------------------------------*/
3534 void build_UCB(CARD_HANDLE pCurrCard, PUCB p_ucb)
3537 u08bits thisCard;
3538 u08bits i,j;
3540 PSCCB p_sccb;
3543 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
3546 p_sccb=(PSCCB)p_ucb->UCB_MgrPrivatePtr;
3549 p_sccb->Sccb_ucb_ptr=p_ucb;
3551 switch (p_ucb->UCB_opcode & (OPC_DEVICE_RESET+OPC_XFER_SG+OPC_CHK_RESIDUAL))
3553 case OPC_DEVICE_RESET:
3554 p_sccb->OperationCode=RESET_COMMAND;
3555 break;
3556 case OPC_XFER_SG:
3557 p_sccb->OperationCode=SCATTER_GATHER_COMMAND;
3558 break;
3559 case OPC_XFER_SG+OPC_CHK_RESIDUAL:
3560 p_sccb->OperationCode=RESIDUAL_SG_COMMAND;
3561 break;
3562 case OPC_CHK_RESIDUAL:
3564 p_sccb->OperationCode=RESIDUAL_COMMAND;
3565 break;
3566 default:
3567 p_sccb->OperationCode=SCSI_INITIATOR_COMMAND;
3568 break;
3571 if (p_ucb->UCB_opcode & OPC_TQ_ENABLE)
3573 p_sccb->ControlByte = (u08bits)((p_ucb->UCB_opcode & OPC_TQ_MASK)>>2) | F_USE_CMD_Q;
3575 else
3577 p_sccb->ControlByte = 0;
3581 p_sccb->CdbLength = (u08bits)p_ucb->UCB_cdblen;
3583 if (p_ucb->UCB_opcode & OPC_NO_AUTO_SENSE)
3585 p_sccb->RequestSenseLength = 0;
3587 else
3589 p_sccb->RequestSenseLength = (unsigned char) p_ucb->UCB_senselen;
3593 if (p_ucb->UCB_opcode & OPC_XFER_SG)
3595 p_sccb->DataPointer=p_ucb->UCB_virt_dataptr;
3596 p_sccb->DataLength = (((u32bits)p_ucb->UCB_NumSgElements)<<3);
3598 else
3600 p_sccb->DataPointer=p_ucb->UCB_phys_dataptr;
3601 p_sccb->DataLength=p_ucb->UCB_datalen;
3604 p_sccb->HostStatus=0;
3605 p_sccb->TargetStatus=0;
3606 p_sccb->TargID=(unsigned char)p_ucb->UCB_targid;
3607 p_sccb->Lun=(unsigned char) p_ucb->UCB_lun;
3608 p_sccb->SccbIOPort=((PSCCBcard)pCurrCard)->ioPort;
3610 j=p_ucb->UCB_cdblen;
3611 for (i=0;i<j;i++)
3613 p_sccb->Cdb[i] = p_ucb->UCB_cdb[i];
3616 p_sccb->SensePointer=p_ucb->UCB_phys_senseptr;
3618 sinits(p_sccb,thisCard);
3621 #ifndef NO_IOCTLS
3623 /*---------------------------------------------------------------------
3625 * Function: GetDevSyncRate
3627 *---------------------------------------------------------------------*/
3628 STATIC int GetDevSyncRate(PSCCBcard pCurrCard,PUCB p_ucb)
3630 struct _SYNC_RATE_INFO * pSyncStr;
3631 PSCCBMgr_tar_info currTar_Info;
3632 BASE_PORT ioport;
3633 u08bits scsiID, j;
3635 #if (FW_TYPE != _SCCB_MGR_)
3636 if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg )
3638 return(1);
3640 #endif
3642 ioport = pCurrCard->ioPort;
3643 pSyncStr = (struct _SYNC_RATE_INFO *) p_ucb->UCB_virt_dataptr;
3644 scsiID = (u08bits) p_ucb->UCB_targid;
3645 currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID];
3646 j = currTar_Info->TarSyncCtrl;
3648 switch (currTar_Info->TarEEValue & EE_SYNC_MASK)
3650 case EE_SYNC_ASYNC:
3651 pSyncStr->RequestMegaXferRate = 0x00;
3652 break;
3653 case EE_SYNC_5MB:
3654 pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 50 : 100;
3655 break;
3656 case EE_SYNC_10MB:
3657 pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 100 : 200;
3658 break;
3659 case EE_SYNC_20MB:
3660 pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 200 : 400;
3661 break;
3664 switch ((j >> 5) & 0x07)
3666 case 0x00:
3667 if((j & 0x07) == 0x00)
3669 pSyncStr->ActualMegaXferRate = 0x00; /* Async Mode */
3671 else
3673 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 200 : 400;
3675 break;
3676 case 0x01:
3677 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 100 : 200;
3678 break;
3679 case 0x02:
3680 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 66 : 122;
3681 break;
3682 case 0x03:
3683 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 50 : 100;
3684 break;
3685 case 0x04:
3686 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 40 : 80;
3687 break;
3688 case 0x05:
3689 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 33 : 66;
3690 break;
3691 case 0x06:
3692 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 28 : 56;
3693 break;
3694 case 0x07:
3695 pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 25 : 50;
3696 break;
3698 pSyncStr->NegotiatedOffset = j & 0x0f;
3700 return(0);
3703 /*---------------------------------------------------------------------
3705 * Function: SetDevSyncRate
3707 *---------------------------------------------------------------------*/
3708 STATIC int SetDevSyncRate(PSCCBcard pCurrCard, PUCB p_ucb)
3710 struct _SYNC_RATE_INFO * pSyncStr;
3711 PSCCBMgr_tar_info currTar_Info;
3712 BASE_PORT ioPort;
3713 u08bits scsiID, i, j, syncVal;
3714 u16bits syncOffset, actualXferRate;
3715 union {
3716 u08bits tempb[2];
3717 u16bits tempw;
3718 }temp2;
3720 #if (FW_TYPE != _SCCB_MGR_)
3721 if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg )
3723 return(1);
3725 #endif
3727 ioPort = pCurrCard->ioPort;
3728 pSyncStr = (struct _SYNC_RATE_INFO *) p_ucb->UCB_virt_dataptr;
3729 scsiID = (u08bits) p_ucb->UCB_targid;
3730 currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID];
3731 i = RD_HARPOON(ioPort+hp_xfer_pad); /* Save current value */
3732 WR_HARPOON(ioPort+hp_xfer_pad, (i | ID_UNLOCK));
3733 WR_HARPOON(ioPort+hp_select_id, ((scsiID << 4) | scsiID));
3734 j = RD_HARPOON(ioPort+hp_synctarg_0);
3735 WR_HARPOON(ioPort+hp_xfer_pad, i); /* restore value */
3737 actualXferRate = pSyncStr->ActualMegaXferRate;
3738 if(!(j & NARROW_SCSI))
3740 actualXferRate <<= 1;
3742 if(actualXferRate == 0x00)
3744 syncVal = EE_SYNC_ASYNC; /* Async Mode */
3746 if(actualXferRate == 0x0200)
3748 syncVal = EE_SYNC_20MB; /* 20/40 MB Mode */
3750 if(actualXferRate > 0x0050 && actualXferRate < 0x0200 )
3752 syncVal = EE_SYNC_10MB; /* 10/20 MB Mode */
3754 else
3756 syncVal = EE_SYNC_5MB; /* 5/10 MB Mode */
3758 if(currTar_Info->TarEEValue && EE_SYNC_MASK == syncVal)
3759 return(0);
3760 currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_SYNC_MASK)
3761 | syncVal;
3762 syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
3763 temp2.tempw = utilEERead(ioPort, syncOffset);
3764 if(scsiID & 0x01)
3766 temp2.tempb[0] = (temp2.tempb[0] & !EE_SYNC_MASK) | syncVal;
3768 else
3770 temp2.tempb[1] = (temp2.tempb[1] & !EE_SYNC_MASK) | syncVal;
3772 utilEEWriteOnOff(ioPort, 1);
3773 utilEEWrite(ioPort, temp2.tempw, syncOffset);
3774 utilEEWriteOnOff(ioPort, 0);
3775 UpdateCheckSum(ioPort);
3777 return(0);
3779 /*---------------------------------------------------------------------
3781 * Function: GetDevWideMode
3783 *---------------------------------------------------------------------*/
3784 int GetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
3786 u08bits *pData;
3788 pData = (u08bits *)p_ucb->UCB_virt_dataptr;
3789 if(sccbMgrTbl[pCurrCard->cardIndex][p_ucb->UCB_targid].TarEEValue
3790 & EE_WIDE_SCSI)
3792 *pData = 1;
3794 else
3796 *pData = 0;
3799 return(0);
3802 /*---------------------------------------------------------------------
3804 * Function: SetDevWideMode
3806 *---------------------------------------------------------------------*/
3807 int SetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
3809 u08bits *pData;
3810 PSCCBMgr_tar_info currTar_Info;
3811 BASE_PORT ioPort;
3812 u08bits scsiID, scsiWideMode;
3813 u16bits syncOffset;
3814 union {
3815 u08bits tempb[2];
3816 u16bits tempw;
3817 }temp2;
3819 #if (FW_TYPE != _SCCB_MGR_)
3820 if( !(pCurrCard->cardInfo->ai_attributes & WIDE_CAPABLE) )
3822 return(1);
3825 if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg )
3827 return(1);
3829 #endif
3831 ioPort = pCurrCard->ioPort;
3832 pData = (u08bits *)p_ucb->UCB_virt_dataptr;
3833 scsiID = (u08bits) p_ucb->UCB_targid;
3834 currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID];
3836 if(*pData)
3838 if(currTar_Info->TarEEValue & EE_WIDE_SCSI)
3840 return(0);
3842 else
3844 scsiWideMode = EE_WIDE_SCSI;
3847 else
3849 if(!currTar_Info->TarEEValue & EE_WIDE_SCSI)
3851 return(0);
3853 else
3855 scsiWideMode = 0;
3858 currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_WIDE_SCSI)
3859 | scsiWideMode;
3861 syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
3862 temp2.tempw = utilEERead(ioPort, syncOffset);
3863 if(scsiID & 0x01)
3865 temp2.tempb[0] = (temp2.tempb[0] & !EE_WIDE_SCSI) | scsiWideMode;
3867 else
3869 temp2.tempb[1] = (temp2.tempb[1] & !EE_WIDE_SCSI) | scsiWideMode;
3871 utilEEWriteOnOff(ioPort, 1);
3872 utilEEWrite(ioPort, temp2.tempw, syncOffset);
3873 utilEEWriteOnOff(ioPort, 0);
3874 UpdateCheckSum(ioPort);
3876 return(0);
3879 /*---------------------------------------------------------------------
3881 * Function: ReadNVRam
3883 *---------------------------------------------------------------------*/
3884 void ReadNVRam(PSCCBcard pCurrCard,PUCB p_ucb)
3886 u08bits *pdata;
3887 u16bits i,numwrds,numbytes,offset,temp;
3888 u08bits OneMore = FALSE;
3889 #if defined(DOS)
3890 u16bits ioport;
3891 #else
3892 u32bits ioport;
3893 #endif
3895 numbytes = (u16bits) p_ucb->UCB_datalen;
3896 ioport = pCurrCard->ioPort;
3897 pdata = (u08bits *) p_ucb->UCB_virt_dataptr;
3898 offset = (u16bits) (p_ucb->UCB_IOCTLParams[0]);
3902 if (offset & 0x1)
3904 *((u16bits*) pdata) = utilEERead(ioport,(u16bits)((offset - 1) / 2)); /* 16 bit read */
3905 *pdata = *(pdata + 1);
3906 ++offset;
3907 ++pdata;
3908 --numbytes;
3911 numwrds = numbytes / 2;
3912 if (numbytes & 1)
3913 OneMore = TRUE;
3915 for (i = 0; i < numwrds; i++)
3917 *((u16bits*) pdata) = utilEERead(ioport,(u16bits)(offset / 2));
3918 pdata += 2;
3919 offset += 2;
3921 if (OneMore)
3923 --pdata;
3924 -- offset;
3925 temp = utilEERead(ioport,(u16bits)(offset / 2));
3926 *pdata = (u08bits) (temp);
3929 } /* end proc ReadNVRam */
3932 /*---------------------------------------------------------------------
3934 * Function: WriteNVRam
3936 *---------------------------------------------------------------------*/
3937 void WriteNVRam(PSCCBcard pCurrCard,PUCB p_ucb)
3939 u08bits *pdata;
3940 u16bits i,numwrds,numbytes,offset, eeprom_end;
3941 u08bits OneMore = FALSE;
3942 union {
3943 u08bits tempb[2];
3944 u16bits tempw;
3945 } temp2;
3947 #if defined(DOS)
3948 u16bits ioport;
3949 #else
3950 u32bits ioport;
3951 #endif
3953 numbytes = (u16bits) p_ucb->UCB_datalen;
3954 ioport = pCurrCard->ioPort;
3955 pdata = (u08bits *) p_ucb->UCB_virt_dataptr;
3956 offset = (u16bits) (p_ucb->UCB_IOCTLParams[0]);
3958 if (RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD)
3959 eeprom_end = 512;
3960 else
3961 eeprom_end = 768;
3963 if(offset > eeprom_end)
3964 return;
3966 if((offset + numbytes) > eeprom_end)
3967 numbytes = eeprom_end - offset;
3969 utilEEWriteOnOff(ioport,1); /* Enable write access to the EEPROM */
3973 if (offset & 0x1)
3975 temp2.tempw = utilEERead(ioport,(u16bits)((offset - 1) / 2)); /* 16 bit read */
3976 temp2.tempb[1] = *pdata;
3977 utilEEWrite(ioport, temp2.tempw, (u16bits)((offset -1) / 2));
3978 *pdata = *(pdata + 1);
3979 ++offset;
3980 ++pdata;
3981 --numbytes;
3984 numwrds = numbytes / 2;
3985 if (numbytes & 1)
3986 OneMore = TRUE;
3988 for (i = 0; i < numwrds; i++)
3990 utilEEWrite(ioport, *((pu16bits)pdata),(u16bits)(offset / 2));
3991 pdata += 2;
3992 offset += 2;
3994 if (OneMore)
3997 temp2.tempw = utilEERead(ioport,(u16bits)(offset / 2));
3998 temp2.tempb[0] = *pdata;
3999 utilEEWrite(ioport, temp2.tempw, (u16bits)(offset / 2));
4001 utilEEWriteOnOff(ioport,0); /* Turn off write access */
4002 UpdateCheckSum((u32bits)ioport);
4004 } /* end proc WriteNVRam */
4008 /*---------------------------------------------------------------------
4010 * Function: UpdateCheckSum
4012 * Description: Update Check Sum in EEPROM
4014 *---------------------------------------------------------------------*/
4017 void UpdateCheckSum(u32bits baseport)
4019 USHORT i,sum_data, eeprom_end;
4021 sum_data = 0x0000;
4024 if (RD_HARPOON(baseport+hp_page_ctrl) & NARROW_SCSI_CARD)
4025 eeprom_end = 512;
4026 else
4027 eeprom_end = 768;
4029 for (i = 1; i < eeprom_end/2; i++)
4031 sum_data += utilEERead(baseport, i);
4034 utilEEWriteOnOff(baseport,1); /* Enable write access to the EEPROM */
4036 utilEEWrite(baseport, sum_data, EEPROM_CHECK_SUM/2);
4037 utilEEWriteOnOff(baseport,0); /* Turn off write access */
4040 void SccbMgr_save_foreign_state(PADAPTER_INFO pAdapterInfo)
4045 void SccbMgr_restore_foreign_state(CARD_HANDLE pCurrCard)
4049 void SccbMgr_restore_native_state(CARD_HANDLE pCurrCard)
4053 #endif /* NO_IOCTLS */
4055 #endif /* (FW_TYPE==_UCB_MGR_) */
4057 #ifndef NO_IOCTLS
4058 #if (FW_TYPE==_UCB_MGR_)
4059 void SccbMgr_unload_card(CARD_HANDLE pCurrCard)
4060 #else
4061 #if defined(DOS)
4062 void SccbMgr_unload_card(USHORT pCurrCard)
4063 #else
4064 void SccbMgr_unload_card(ULONG pCurrCard)
4065 #endif
4066 #endif
4068 UCHAR i;
4069 #if defined(DOS)
4070 USHORT portBase;
4071 USHORT regOffset;
4072 #else
4073 ULONG portBase;
4074 ULONG regOffset;
4075 #endif
4076 ULONG scamData;
4077 #if defined(OS2)
4078 ULONG far *pScamTbl;
4079 #else
4080 ULONG *pScamTbl;
4081 #endif
4082 PNVRamInfo pCurrNvRam;
4084 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
4086 if(pCurrNvRam){
4087 WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
4088 WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
4089 WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
4090 WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
4091 WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
4093 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
4094 WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
4096 portBase = pCurrNvRam->niBaseAddr;
4098 for(i = 0; i < MAX_SCSI_TAR; i++){
4099 regOffset = hp_aramBase + 64 + i*4;
4100 #if defined(OS2)
4101 pScamTbl = (ULONG far *) &pCurrNvRam->niScamTbl[i];
4102 #else
4103 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
4104 #endif
4105 scamData = *pScamTbl;
4106 WR_HARP32(portBase, regOffset, scamData);
4109 }else{
4110 WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
4113 #endif /* NO_IOCTLS */
4116 void RNVRamData(PNVRamInfo pNvRamInfo)
4118 UCHAR i;
4119 #if defined(DOS)
4120 USHORT portBase;
4121 USHORT regOffset;
4122 #else
4123 ULONG portBase;
4124 ULONG regOffset;
4125 #endif
4126 ULONG scamData;
4127 #if defined (OS2)
4128 ULONG far *pScamTbl;
4129 #else
4130 ULONG *pScamTbl;
4131 #endif
4133 pNvRamInfo->niModel = RdStack(pNvRamInfo->niBaseAddr, 0);
4134 pNvRamInfo->niSysConf = RdStack(pNvRamInfo->niBaseAddr, 1);
4135 pNvRamInfo->niScsiConf = RdStack(pNvRamInfo->niBaseAddr, 2);
4136 pNvRamInfo->niScamConf = RdStack(pNvRamInfo->niBaseAddr, 3);
4137 pNvRamInfo->niAdapId = RdStack(pNvRamInfo->niBaseAddr, 4);
4139 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
4140 pNvRamInfo->niSyncTbl[i] = RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
4142 portBase = pNvRamInfo->niBaseAddr;
4144 for(i = 0; i < MAX_SCSI_TAR; i++){
4145 regOffset = hp_aramBase + 64 + i*4;
4146 RD_HARP32(portBase, regOffset, scamData);
4147 #if defined(OS2)
4148 pScamTbl = (ULONG far *) &pNvRamInfo->niScamTbl[i];
4149 #else
4150 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
4151 #endif
4152 *pScamTbl = scamData;
4157 #if defined(DOS)
4158 UCHAR RdStack(USHORT portBase, UCHAR index)
4159 #else
4160 UCHAR RdStack(ULONG portBase, UCHAR index)
4161 #endif
4163 WR_HARPOON(portBase + hp_stack_addr, index);
4164 return(RD_HARPOON(portBase + hp_stack_data));
4167 #if defined(DOS)
4168 void WrStack(USHORT portBase, UCHAR index, UCHAR data)
4169 #else
4170 void WrStack(ULONG portBase, UCHAR index, UCHAR data)
4171 #endif
4173 WR_HARPOON(portBase + hp_stack_addr, index);
4174 WR_HARPOON(portBase + hp_stack_data, data);
4178 #if (FW_TYPE==_UCB_MGR_)
4179 u08bits ChkIfChipInitialized(BASE_PORT ioPort)
4180 #else
4181 #if defined(DOS)
4182 UCHAR ChkIfChipInitialized(USHORT ioPort)
4183 #else
4184 UCHAR ChkIfChipInitialized(ULONG ioPort)
4185 #endif
4186 #endif
4188 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != RdStack(ioPort, 4))
4189 return(FALSE);
4190 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
4191 != CLKCTRL_DEFAULT)
4192 return(FALSE);
4193 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
4194 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
4195 return(TRUE);
4196 return(FALSE);
4199 /*---------------------------------------------------------------------
4201 * Function: SccbMgr_start_sccb
4203 * Description: Start a command pointed to by p_Sccb. When the
4204 * command is completed it will be returned via the
4205 * callback function.
4207 *---------------------------------------------------------------------*/
4208 #if (FW_TYPE==_UCB_MGR_)
4209 void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb)
4210 #else
4211 #if defined(DOS)
4212 void SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_Sccb)
4213 #else
4214 void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
4215 #endif
4216 #endif
4218 #if defined(DOS)
4219 USHORT ioport;
4220 #else
4221 ULONG ioport;
4222 #endif
4223 UCHAR thisCard, lun;
4224 PSCCB pSaveSccb;
4225 CALL_BK_FN callback;
4227 #if (FW_TYPE==_UCB_MGR_)
4228 PSCCB p_Sccb;
4229 #endif
4231 mOS_Lock((PSCCBcard)pCurrCard);
4232 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
4233 ioport = ((PSCCBcard) pCurrCard)->ioPort;
4235 #if (FW_TYPE==_UCB_MGR_)
4236 p_Sccb = (PSCCB)p_ucb->UCB_MgrPrivatePtr;
4237 #endif
4239 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
4242 #if (FW_TYPE==_UCB_MGR_)
4243 p_ucb->UCB_hbastat = SCCB_COMPLETE;
4244 p_ucb->UCB_status=SCCB_ERROR;
4245 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4246 if (callback)
4247 callback(p_ucb);
4248 #endif
4250 #if (FW_TYPE==_SCCB_MGR_)
4251 p_Sccb->HostStatus = SCCB_COMPLETE;
4252 p_Sccb->SccbStatus = SCCB_ERROR;
4253 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
4254 if (callback)
4255 callback(p_Sccb);
4256 #endif
4258 mOS_UnLock((PSCCBcard)pCurrCard);
4259 return;
4262 #if (FW_TYPE==_SCCB_MGR_)
4263 sinits(p_Sccb,thisCard);
4264 #endif
4267 #if (FW_TYPE==_UCB_MGR_)
4268 #ifndef NO_IOCTLS
4270 if (p_ucb->UCB_opcode & OPC_IOCTL)
4273 switch (p_ucb->UCB_IOCTLCommand)
4275 case READ_NVRAM:
4276 ReadNVRam((PSCCBcard)pCurrCard,p_ucb);
4277 p_ucb->UCB_status=UCB_SUCCESS;
4278 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4279 if (callback)
4280 callback(p_ucb);
4281 mOS_UnLock((PSCCBcard)pCurrCard);
4282 return;
4284 case WRITE_NVRAM:
4285 WriteNVRam((PSCCBcard)pCurrCard,p_ucb);
4286 p_ucb->UCB_status=UCB_SUCCESS;
4287 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4288 if (callback)
4289 callback(p_ucb);
4290 mOS_UnLock((PSCCBcard)pCurrCard);
4291 return;
4293 case SEND_SCSI_PASSTHRU:
4294 #if (FW_TYPE != _SCCB_MGR_)
4295 if( p_ucb->UCB_targid >=
4296 ((PSCCBcard)pCurrCard)->cardInfo->ai_MaxTarg )
4298 p_ucb->UCB_status = UCB_ERROR;
4299 p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
4300 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4301 if (callback)
4302 callback(p_ucb);
4303 mOS_UnLock((PSCCBcard)pCurrCard);
4304 return;
4306 #endif
4307 break;
4309 case HARD_RESET:
4310 p_ucb->UCB_status = UCB_INVALID;
4311 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4312 if (callback)
4313 callback(p_ucb);
4314 mOS_UnLock((PSCCBcard)pCurrCard);
4315 return;
4316 case GET_DEVICE_SYNCRATE:
4317 if( !GetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) )
4319 p_ucb->UCB_status = UCB_SUCCESS;
4321 else
4323 p_ucb->UCB_status = UCB_ERROR;
4324 p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
4326 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4327 if (callback)
4328 callback(p_ucb);
4329 mOS_UnLock((PSCCBcard)pCurrCard);
4330 return;
4331 case SET_DEVICE_SYNCRATE:
4332 if( !SetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) )
4334 p_ucb->UCB_status = UCB_SUCCESS;
4336 else
4338 p_ucb->UCB_status = UCB_ERROR;
4339 p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
4341 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4342 if (callback)
4343 callback(p_ucb);
4344 mOS_UnLock((PSCCBcard)pCurrCard);
4345 return;
4346 case GET_WIDE_MODE:
4347 if( !GetDevWideMode((PSCCBcard)pCurrCard,p_ucb) )
4349 p_ucb->UCB_status = UCB_SUCCESS;
4351 else
4353 p_ucb->UCB_status = UCB_ERROR;
4354 p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
4356 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4357 if (callback)
4358 callback(p_ucb);
4359 mOS_UnLock((PSCCBcard)pCurrCard);
4360 return;
4361 case SET_WIDE_MODE:
4362 if( !SetDevWideMode((PSCCBcard)pCurrCard,p_ucb) )
4364 p_ucb->UCB_status = UCB_SUCCESS;
4366 else
4368 p_ucb->UCB_status = UCB_ERROR;
4369 p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
4371 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4372 if (callback)
4373 callback(p_ucb);
4374 mOS_UnLock((PSCCBcard)pCurrCard);
4375 return;
4376 default:
4377 p_ucb->UCB_status=UCB_INVALID;
4378 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4379 if (callback)
4380 callback(p_ucb);
4381 mOS_UnLock((PSCCBcard)pCurrCard);
4382 return;
4385 #endif /* NO_IOCTLS */
4386 #endif /* (FW_TYPE==_UCB_MGR_) */
4389 if (!((PSCCBcard) pCurrCard)->cmdCounter)
4391 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
4392 | SCCB_MGR_ACTIVE));
4394 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
4396 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
4397 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
4401 ((PSCCBcard)pCurrCard)->cmdCounter++;
4403 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
4405 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
4406 | TICKLE_ME));
4407 if(p_Sccb->OperationCode == RESET_COMMAND)
4409 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
4410 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
4411 queueSelectFail(&BL_Card[thisCard], thisCard);
4412 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
4414 else
4416 queueAddSccb(p_Sccb,thisCard);
4420 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
4422 if(p_Sccb->OperationCode == RESET_COMMAND)
4424 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
4425 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
4426 queueSelectFail(&BL_Card[thisCard], thisCard);
4427 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
4429 else
4431 queueAddSccb(p_Sccb,thisCard);
4435 else {
4437 MDISABLE_INT(ioport);
4439 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
4440 ((sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4441 lun = p_Sccb->Lun;
4442 else
4443 lun = 0;
4444 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
4445 (sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
4446 (sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
4447 == FALSE)) {
4449 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
4450 mOS_UnLock((PSCCBcard)pCurrCard);
4451 #if defined(DOS)
4452 ssel((USHORT)p_Sccb->SccbIOPort,thisCard);
4453 #else
4454 ssel(p_Sccb->SccbIOPort,thisCard);
4455 #endif
4456 mOS_Lock((PSCCBcard)pCurrCard);
4459 else {
4461 if(p_Sccb->OperationCode == RESET_COMMAND)
4463 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
4464 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
4465 queueSelectFail(&BL_Card[thisCard], thisCard);
4466 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
4468 else
4470 queueAddSccb(p_Sccb,thisCard);
4475 MENABLE_INT(ioport);
4478 mOS_UnLock((PSCCBcard)pCurrCard);
4482 /*---------------------------------------------------------------------
4484 * Function: SccbMgr_abort_sccb
4486 * Description: Abort the command pointed to by p_Sccb. When the
4487 * command is completed it will be returned via the
4488 * callback function.
4490 *---------------------------------------------------------------------*/
4491 #if (FW_TYPE==_UCB_MGR_)
4492 s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb)
4493 #else
4494 #if defined(DOS)
4495 int SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_Sccb)
4496 #else
4497 int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
4498 #endif
4499 #endif
4502 #if defined(DOS)
4503 USHORT ioport;
4504 #else
4505 ULONG ioport;
4506 #endif
4508 UCHAR thisCard;
4509 CALL_BK_FN callback;
4510 UCHAR TID;
4511 PSCCB pSaveSCCB;
4512 PSCCBMgr_tar_info currTar_Info;
4515 #if (FW_TYPE==_UCB_MGR_)
4516 PSCCB p_Sccb;
4517 p_Sccb=(PSCCB)p_ucb->UCB_MgrPrivatePtr;
4518 #endif
4520 ioport = ((PSCCBcard) pCurrCard)->ioPort;
4522 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
4524 mOS_Lock((PSCCBcard)pCurrCard);
4526 if (RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)
4528 mOS_UnLock((PSCCBcard)pCurrCard);
4531 else
4534 if (queueFindSccb(p_Sccb,thisCard))
4537 mOS_UnLock((PSCCBcard)pCurrCard);
4539 ((PSCCBcard)pCurrCard)->cmdCounter--;
4541 if (!((PSCCBcard)pCurrCard)->cmdCounter)
4542 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
4543 & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
4545 #if (FW_TYPE==_SCCB_MGR_)
4546 p_Sccb->SccbStatus = SCCB_ABORT;
4547 callback = p_Sccb->SccbCallback;
4548 callback(p_Sccb);
4549 #else
4550 p_ucb->UCB_status=SCCB_ABORT;
4551 callback = (CALL_BK_FN)p_ucb->UCB_callback;
4552 callback(p_ucb);
4553 #endif
4555 return(0);
4558 else
4560 mOS_UnLock((PSCCBcard)pCurrCard);
4562 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
4564 p_Sccb->SccbStatus = SCCB_ABORT;
4565 return(0);
4569 else
4572 TID = p_Sccb->TargID;
4575 if(p_Sccb->Sccb_tag)
4577 MDISABLE_INT(ioport);
4578 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
4580 p_Sccb->SccbStatus = SCCB_ABORT;
4581 p_Sccb->Sccb_scsistat = ABORT_ST;
4582 #if (FW_TYPE==_UCB_MGR_)
4583 p_ucb->UCB_status=SCCB_ABORT;
4584 #endif
4585 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
4587 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
4589 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
4590 ssel(ioport, thisCard);
4592 else
4594 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
4595 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
4596 queueSelectFail((PSCCBcard) pCurrCard, thisCard);
4597 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
4600 MENABLE_INT(ioport);
4601 return(0);
4603 else
4605 currTar_Info = &sccbMgrTbl[thisCard][p_Sccb->TargID];
4607 if(BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
4608 == p_Sccb)
4610 p_Sccb->SccbStatus = SCCB_ABORT;
4611 return(0);
4617 return(-1);
4621 /*---------------------------------------------------------------------
4623 * Function: SccbMgr_my_int
4625 * Description: Do a quick check to determine if there is a pending
4626 * interrupt for this card and disable the IRQ Pin if so.
4628 *---------------------------------------------------------------------*/
4629 #if (FW_TYPE==_UCB_MGR_)
4630 u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard)
4631 #else
4632 #if defined(DOS)
4633 UCHAR SccbMgr_my_int(USHORT pCurrCard)
4634 #else
4635 UCHAR SccbMgr_my_int(ULONG pCurrCard)
4636 #endif
4637 #endif
4639 #if defined(DOS)
4640 USHORT ioport;
4641 #else
4642 ULONG ioport;
4643 #endif
4645 ioport = ((PSCCBcard)pCurrCard)->ioPort;
4647 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
4650 #if defined(DOS)
4651 MDISABLE_INT(ioport);
4652 #endif
4654 return(TRUE);
4657 else
4659 return(FALSE);
4664 /*---------------------------------------------------------------------
4666 * Function: SccbMgr_isr
4668 * Description: This is our entry point when an interrupt is generated
4669 * by the card and the upper level driver passes it on to
4670 * us.
4672 *---------------------------------------------------------------------*/
4673 #if (FW_TYPE==_UCB_MGR_)
4674 s32bits SccbMgr_isr(CARD_HANDLE pCurrCard)
4675 #else
4676 #if defined(DOS)
4677 int SccbMgr_isr(USHORT pCurrCard)
4678 #else
4679 int SccbMgr_isr(ULONG pCurrCard)
4680 #endif
4681 #endif
4683 PSCCB currSCCB;
4684 UCHAR thisCard,result,bm_status, bm_int_st;
4685 USHORT hp_int;
4686 UCHAR i, target;
4687 #if defined(DOS)
4688 USHORT ioport;
4689 #else
4690 ULONG ioport;
4691 #endif
4693 mOS_Lock((PSCCBcard)pCurrCard);
4695 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
4696 ioport = ((PSCCBcard)pCurrCard)->ioPort;
4698 MDISABLE_INT(ioport);
4700 #if defined(BUGBUG)
4701 WR_HARPOON(ioport+hp_user_defined_D, RD_HARPOON(ioport+hp_int_status));
4702 #endif
4704 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
4705 bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
4706 else
4707 bm_status = 0;
4709 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
4711 mOS_UnLock((PSCCBcard)pCurrCard);
4713 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & default_intena) |
4714 bm_status)
4717 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
4719 #if defined(BUGBUG)
4720 Debug_Load(thisCard,(UCHAR) 0XFF);
4721 Debug_Load(thisCard,bm_int_st);
4723 Debug_Load(thisCard,hp_int_0);
4724 Debug_Load(thisCard,hp_int_1);
4725 #endif
4728 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
4729 result = SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
4730 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
4731 bm_status = 0;
4733 if (result) {
4735 mOS_Lock((PSCCBcard)pCurrCard);
4736 MENABLE_INT(ioport);
4737 mOS_UnLock((PSCCBcard)pCurrCard);
4738 return(result);
4743 else if (hp_int & ICMD_COMP) {
4745 if ( !(hp_int & BUS_FREE) ) {
4746 /* Wait for the BusFree before starting a new command. We
4747 must also check for being reselected since the BusFree
4748 may not show up if another device reselects us in 1.5us or
4749 less. SRR Wednesday, 3/8/1995.
4751 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
4754 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
4756 phaseChkFifo(ioport, thisCard);
4758 /* WRW_HARPOON((ioport+hp_intstat),
4759 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
4762 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
4764 autoCmdCmplt(ioport,thisCard);
4769 else if (hp_int & ITAR_DISC)
4772 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
4774 phaseChkFifo(ioport, thisCard);
4778 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
4780 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
4781 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
4783 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
4786 currSCCB->Sccb_scsistat = DISCONNECT_ST;
4787 queueDisconnect(currSCCB,thisCard);
4789 /* Wait for the BusFree before starting a new command. We
4790 must also check for being reselected since the BusFree
4791 may not show up if another device reselects us in 1.5us or
4792 less. SRR Wednesday, 3/8/1995.
4794 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
4795 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
4796 RD_HARPOON((ioport+hp_scsisig)) ==
4797 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
4800 The additional loop exit condition above detects a timing problem
4801 with the revision D/E harpoon chips. The caller should reset the
4802 host adapter to recover when 0xFE is returned.
4804 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
4806 mOS_Lock((PSCCBcard)pCurrCard);
4807 MENABLE_INT(ioport);
4808 mOS_UnLock((PSCCBcard)pCurrCard);
4809 return 0xFE;
4812 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
4815 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
4820 else if (hp_int & RSEL) {
4822 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
4824 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
4826 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
4828 phaseChkFifo(ioport, thisCard);
4831 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
4833 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
4834 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
4835 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
4838 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
4839 currSCCB->Sccb_scsistat = DISCONNECT_ST;
4840 queueDisconnect(currSCCB,thisCard);
4843 sres(ioport,thisCard,((PSCCBcard)pCurrCard));
4844 phaseDecode(ioport,thisCard);
4849 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
4852 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
4853 phaseDecode(ioport,thisCard);
4858 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
4860 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
4861 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
4863 phaseDecode(ioport,thisCard);
4865 else
4867 /* Harpoon problem some SCSI target device respond to selection
4868 with short BUSY pulse (<400ns) this will make the Harpoon is not able
4869 to latch the correct Target ID into reg. x53.
4870 The work around require to correct this reg. But when write to this
4871 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
4872 need to read this reg first then restore it later. After update to 0x53 */
4874 i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
4875 target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
4876 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
4877 WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
4878 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
4879 WR_HARPOON(ioport+hp_fifowrite, i);
4880 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
4884 else if (hp_int & XFER_CNT_0) {
4886 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
4888 schkdd(ioport,thisCard);
4893 else if (hp_int & BUS_FREE) {
4895 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
4897 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
4899 hostDataXferAbort(ioport,thisCard,currSCCB);
4902 phaseBusFree(ioport,thisCard);
4906 else if (hp_int & ITICKLE) {
4908 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
4909 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
4914 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
4917 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
4920 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
4922 queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
4925 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
4926 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
4927 ssel(ioport,thisCard);
4930 break;
4934 } /*end while */
4936 mOS_Lock((PSCCBcard)pCurrCard);
4937 MENABLE_INT(ioport);
4938 mOS_UnLock((PSCCBcard)pCurrCard);
4940 return(0);
4943 /*---------------------------------------------------------------------
4945 * Function: Sccb_bad_isr
4947 * Description: Some type of interrupt has occurred which is slightly
4948 * out of the ordinary. We will now decode it fully, in
4949 * this routine. This is broken up in an attempt to save
4950 * processing time.
4952 *---------------------------------------------------------------------*/
4953 #if defined(DOS)
4954 UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int)
4955 #else
4956 UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int)
4957 #endif
4959 #if defined(HARP_REVX)
4960 ULONG timer;
4961 #endif
4962 UCHAR temp, ScamFlg;
4963 PSCCBMgr_tar_info currTar_Info;
4964 PNVRamInfo pCurrNvRam;
4967 if (RD_HARPOON(p_port+hp_ext_status) &
4968 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
4971 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4974 hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
4977 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
4980 WR_HARPOON(p_port+hp_pci_stat_cfg,
4981 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
4983 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
4987 if (pCurrCard->currentSCCB != NULL)
4990 if (!pCurrCard->currentSCCB->HostStatus)
4991 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
4993 sxfrp(p_port,p_card);
4995 temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
4996 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
4997 WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
4998 WR_HARPOON(p_port+hp_ee_ctrl, temp);
5000 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
5002 phaseDecode(p_port,p_card);
5008 else if (p_int & RESET)
5011 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
5012 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
5013 if (pCurrCard->currentSCCB != NULL) {
5015 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5017 hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
5021 DISABLE_AUTO(p_port);
5023 sresb(p_port,p_card);
5025 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
5027 pCurrNvRam = pCurrCard->pNvRamInfo;
5028 if(pCurrNvRam){
5029 ScamFlg = pCurrNvRam->niScamConf;
5031 else{
5032 ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2);
5035 XbowInit(p_port, ScamFlg);
5037 scini(p_card, pCurrCard->ourId, 0);
5039 return(0xFF);
5043 else if (p_int & FIFO) {
5045 WRW_HARPOON((p_port+hp_intstat), FIFO);
5047 #if defined(HARP_REVX)
5049 for (timer=0x00FFFFFFL; timer != 0x00000000L; timer--) {
5051 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
5052 break;
5054 if (RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)
5055 break;
5059 if ( (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY) &&
5060 (RD_HARPOON(p_port+hp_fiforead) !=
5061 RD_HARPOON(p_port+hp_fifowrite)) &&
5062 (RD_HARPOON(p_port+hp_xfercnt_0))
5065 WR_HARPOON((p_port+hp_xferstat), 0x01);
5067 /* else
5069 /* sxfrp(p_port,p_card);
5071 #else
5072 if (pCurrCard->currentSCCB != NULL)
5073 sxfrp(p_port,p_card);
5074 #endif
5077 else if (p_int & TIMEOUT)
5080 DISABLE_AUTO(p_port);
5082 WRW_HARPOON((p_port+hp_intstat),
5083 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
5085 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
5088 currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
5089 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
5090 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5091 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = FALSE;
5092 else
5093 currTar_Info->TarLUNBusy[0] = FALSE;
5096 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
5098 currTar_Info->TarSyncCtrl = 0;
5099 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
5102 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
5104 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
5107 sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
5109 queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
5113 #if defined(SCAM_LEV_2)
5115 else if (p_int & SCAM_SEL)
5118 scarb(p_port,LEVEL2_TAR);
5119 scsel(p_port);
5120 scasid(p_card, p_port);
5122 scbusf(p_port);
5124 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
5126 #endif
5128 return(0x00);
5132 /*---------------------------------------------------------------------
5134 * Function: SccbMgr_scsi_reset
5136 * Description: A SCSI bus reset will be generated and all outstanding
5137 * Sccbs will be returned via the callback.
5139 *---------------------------------------------------------------------*/
5140 #if (FW_TYPE==_UCB_MGR_)
5141 void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard)
5142 #else
5143 #if defined(DOS)
5144 void SccbMgr_scsi_reset(USHORT pCurrCard)
5145 #else
5146 void SccbMgr_scsi_reset(ULONG pCurrCard)
5147 #endif
5148 #endif
5150 UCHAR thisCard;
5152 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
5154 mOS_Lock((PSCCBcard)pCurrCard);
5156 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
5158 WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_clkctrl_0, CLKCTRL_DEFAULT);
5159 WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sys_ctrl, 0x00);
5162 sresb(((PSCCBcard)pCurrCard)->ioPort,thisCard);
5164 if (RD_HARPOON(((PSCCBcard)pCurrCard)->ioPort+hp_ext_status) & BM_CMD_BUSY)
5166 WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl,
5167 (RD_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl)
5168 & ~SCATTER_EN));
5170 WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sg_addr,0x00);
5172 ((PSCCBcard) pCurrCard)->globalFlags &= ~F_HOST_XFER_ACT;
5173 busMstrTimeOut(((PSCCBcard) pCurrCard)->ioPort);
5175 WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_int_mask,
5176 (INT_CMD_COMPL | SCSI_INTERRUPT));
5180 if (utilEERead(((PSCCBcard)pCurrCard)->ioPort, (SCAM_CONFIG/2))
5181 & SCAM_ENABLED)
5183 scini(thisCard, ((PSCCBcard)pCurrCard)->ourId, 0);
5185 #if (FW_TYPE==_UCB_MGR_)
5186 ((PSCCBcard)pCurrCard)->cardInfo->ai_AEN_routine(0x01,pCurrCard,0,0,0,0);
5187 #endif
5189 mOS_UnLock((PSCCBcard)pCurrCard);
5193 /*---------------------------------------------------------------------
5195 * Function: SccbMgr_timer_expired
5197 * Description: This function allow me to kill my own job that has not
5198 * yet completed, and has cause a timeout to occur. This
5199 * timeout has caused the upper level driver to call this
5200 * function.
5202 *---------------------------------------------------------------------*/
5204 #if (FW_TYPE==_UCB_MGR_)
5205 void SccbMgr_timer_expired(CARD_HANDLE pCurrCard)
5206 #else
5207 #if defined(DOS)
5208 void SccbMgr_timer_expired(USHORT pCurrCard)
5209 #else
5210 void SccbMgr_timer_expired(ULONG pCurrCard)
5211 #endif
5212 #endif
5216 #if defined(DOS)
5217 /*---------------------------------------------------------------------
5219 * Function: SccbMgr_status
5221 * Description: This function returns the number of outstanding SCCB's.
5222 * This is specific to the DOS enviroment, which needs this
5223 * to help them keep protected and real mode commands staight.
5225 *---------------------------------------------------------------------*/
5227 USHORT SccbMgr_status(USHORT pCurrCard)
5229 return(BL_Card[pCurrCard].cmdCounter);
5231 #endif
5233 /*---------------------------------------------------------------------
5235 * Function: SccbMgrTableInit
5237 * Description: Initialize all Sccb manager data structures.
5239 *---------------------------------------------------------------------*/
5241 void SccbMgrTableInitAll()
5243 UCHAR thisCard;
5245 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
5247 SccbMgrTableInitCard(&BL_Card[thisCard],thisCard);
5249 BL_Card[thisCard].ioPort = 0x00;
5250 BL_Card[thisCard].cardInfo = NULL;
5251 BL_Card[thisCard].cardIndex = 0xFF;
5252 BL_Card[thisCard].ourId = 0x00;
5253 BL_Card[thisCard].pNvRamInfo = NULL;
5258 /*---------------------------------------------------------------------
5260 * Function: SccbMgrTableInit
5262 * Description: Initialize all Sccb manager data structures.
5264 *---------------------------------------------------------------------*/
5266 void SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
5268 UCHAR scsiID, qtag;
5270 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
5272 BL_Card[p_card].discQ_Tbl[qtag] = NULL;
5275 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
5277 sccbMgrTbl[p_card][scsiID].TarStatus = 0;
5278 sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
5279 SccbMgrTableInitTarget(p_card, scsiID);
5282 pCurrCard->scanIndex = 0x00;
5283 pCurrCard->currentSCCB = NULL;
5284 pCurrCard->globalFlags = 0x00;
5285 pCurrCard->cmdCounter = 0x00;
5286 pCurrCard->tagQ_Lst = 0x01;
5287 pCurrCard->discQCount = 0;
5293 /*---------------------------------------------------------------------
5295 * Function: SccbMgrTableInit
5297 * Description: Initialize all Sccb manager data structures.
5299 *---------------------------------------------------------------------*/
5301 void SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
5304 UCHAR lun, qtag;
5305 PSCCBMgr_tar_info currTar_Info;
5307 currTar_Info = &sccbMgrTbl[p_card][target];
5309 currTar_Info->TarSelQ_Cnt = 0;
5310 currTar_Info->TarSyncCtrl = 0;
5312 currTar_Info->TarSelQ_Head = NULL;
5313 currTar_Info->TarSelQ_Tail = NULL;
5314 currTar_Info->TarTagQ_Cnt = 0;
5315 currTar_Info->TarLUN_CA = FALSE;
5318 for (lun = 0; lun < MAX_LUN; lun++)
5320 currTar_Info->TarLUNBusy[lun] = FALSE;
5321 currTar_Info->LunDiscQ_Idx[lun] = 0;
5324 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
5326 if(BL_Card[p_card].discQ_Tbl[qtag] != NULL)
5328 if(BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
5330 BL_Card[p_card].discQ_Tbl[qtag] = NULL;
5331 BL_Card[p_card].discQCount--;
5337 #if defined(BUGBUG)
5339 /*****************************************************************
5340 * Save the current byte in the debug array
5341 *****************************************************************/
5344 void Debug_Load(UCHAR p_card, UCHAR p_bug_data)
5346 debug_int[p_card][debug_index[p_card]] = p_bug_data;
5347 debug_index[p_card]++;
5349 if (debug_index[p_card] == debug_size)
5351 debug_index[p_card] = 0;
5354 #endif
5355 #ident "$Id: sccb_dat.c 1.10 1997/02/22 03:16:02 awin Exp $"
5356 /*----------------------------------------------------------------------
5359 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
5361 * This file is available under both the GNU General Public License
5362 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
5364 * $Workfile: sccb_dat.c $
5366 * Description: Functions relating to handling of the SCCB interface
5367 * between the device driver and the HARPOON.
5369 * $Date: 1997/02/22 03:16:02 $
5371 * $Revision: 1.10 $
5373 *----------------------------------------------------------------------*/
5375 /*#include <globals.h>*/
5377 #if (FW_TYPE==_UCB_MGR_)
5378 /*#include <budi.h>*/
5379 #endif
5381 /*#include <sccbmgr.h>*/
5382 /*#include <blx30.h>*/
5383 /*#include <target.h>*/
5384 /*#include <harpoon.h>*/
5387 ** IMPORTANT NOTE!!!
5389 ** You MUST preassign all data to a valid value or zero. This is
5390 ** required due to the MS compiler bug under OS/2 and Solaris Real-Mode
5391 ** driver environment.
5395 SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
5396 SCCBCARD BL_Card[MAX_CARDS] = { { 0 } };
5397 SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
5398 NVRAMINFO nvRamInfo[MAX_MB_CARDS] = { { 0 } };
5401 #if defined(OS2)
5402 void (far *s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 };
5403 UCHAR temp_id_string[ID_STRING_LENGTH] = { 0 };
5404 #elif defined(SOLARIS_REAL_MODE) || defined(__STDC__)
5405 void (*s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 };
5406 #else
5407 void (*s_PhaseTbl[8]) ();
5408 #endif
5410 #if defined(DOS)
5411 UCHAR first_time = 0;
5412 #endif
5414 UCHAR mbCards = 0;
5415 UCHAR scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
5416 ' ', 'B', 'T', '-', '9', '3', '0', \
5417 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
5418 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
5420 USHORT default_intena = 0;
5422 #if defined(BUGBUG)
5423 UCHAR debug_int[MAX_CARDS][debug_size] = { 0 };
5424 UCHAR debug_index[MAX_CARDS] = { 0 };
5425 UCHAR reserved_1[3] = { 0 };
5426 #endif
5427 #ident "$Id: scsi.c 1.23 1997/07/09 21:42:54 mohan Exp $"
5428 /*----------------------------------------------------------------------
5431 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
5433 * This file is available under both the GNU General Public License
5434 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
5436 * $Workfile: scsi.c $
5438 * Description: Functions for handling SCSI bus functions such as
5439 * selection/reselection, sync negotiation, message-in
5440 * decoding.
5442 * $Date: 1997/07/09 21:42:54 $
5444 * $Revision: 1.23 $
5446 *----------------------------------------------------------------------*/
5448 /*#include <globals.h>*/
5450 #if (FW_TYPE==_UCB_MGR_)
5451 /*#include <budi.h>*/
5452 #endif
5454 /*#include <sccbmgr.h>*/
5455 /*#include <blx30.h>*/
5456 /*#include <target.h>*/
5457 /*#include <scsi2.h>*/
5458 /*#include <eeprom.h>*/
5459 /*#include <harpoon.h>*/
5463 extern SCCBCARD BL_Card[MAX_CARDS];
5464 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
5465 #if defined(BUGBUG)
5466 void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
5467 #endif
5470 /*---------------------------------------------------------------------
5472 * Function: sfetm
5474 * Description: Read in a message byte from the SCSI bus, and check
5475 * for a parity error.
5477 *---------------------------------------------------------------------*/
5479 #if defined(DOS)
5480 UCHAR sfm(USHORT port, PSCCB pCurrSCCB)
5481 #else
5482 UCHAR sfm(ULONG port, PSCCB pCurrSCCB)
5483 #endif
5485 UCHAR message;
5486 USHORT TimeOutLoop;
5488 TimeOutLoop = 0;
5489 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
5490 (TimeOutLoop++ < 20000) ){}
5493 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
5495 message = RD_HARPOON(port+hp_scsidata_0);
5497 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
5500 if (TimeOutLoop > 20000)
5501 message = 0x00; /* force message byte = 0 if Time Out on Req */
5503 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
5504 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
5506 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
5507 WR_HARPOON(port+hp_xferstat, 0);
5508 WR_HARPOON(port+hp_fiforead, 0);
5509 WR_HARPOON(port+hp_fifowrite, 0);
5510 if (pCurrSCCB != NULL)
5512 pCurrSCCB->Sccb_scsimsg = SMPARITY;
5514 message = 0x00;
5517 ACCEPT_MSG_ATN(port);
5518 TimeOutLoop = 0;
5519 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
5520 (TimeOutLoop++ < 20000) ){}
5521 if (TimeOutLoop > 20000)
5523 WRW_HARPOON((port+hp_intstat), PARITY);
5524 return(message);
5526 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
5528 WRW_HARPOON((port+hp_intstat), PARITY);
5529 return(message);
5531 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
5533 RD_HARPOON(port+hp_scsidata_0);
5535 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
5537 }while(1);
5540 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
5541 WR_HARPOON(port+hp_xferstat, 0);
5542 WR_HARPOON(port+hp_fiforead, 0);
5543 WR_HARPOON(port+hp_fifowrite, 0);
5544 return(message);
5548 /*---------------------------------------------------------------------
5550 * Function: ssel
5552 * Description: Load up automation and select target device.
5554 *---------------------------------------------------------------------*/
5556 #if defined(DOS)
5557 void ssel(USHORT port, UCHAR p_card)
5558 #else
5559 void ssel(ULONG port, UCHAR p_card)
5560 #endif
5563 #if defined(DOS)
5564 UCHAR auto_loaded, i, target, *theCCB;
5565 #elif defined(OS2)
5566 UCHAR auto_loaded, i, target;
5567 UCHAR far *theCCB;
5568 #else
5569 UCHAR auto_loaded, i, target, *theCCB;
5570 #endif
5572 #if defined(DOS)
5573 USHORT cdb_reg;
5574 #else
5575 ULONG cdb_reg;
5576 #endif
5577 PSCCBcard CurrCard;
5578 PSCCB currSCCB;
5579 PSCCBMgr_tar_info currTar_Info;
5580 UCHAR lastTag, lun;
5582 CurrCard = &BL_Card[p_card];
5583 currSCCB = CurrCard->currentSCCB;
5584 target = currSCCB->TargID;
5585 currTar_Info = &sccbMgrTbl[p_card][target];
5586 lastTag = CurrCard->tagQ_Lst;
5588 ARAM_ACCESS(port);
5591 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
5592 currSCCB->ControlByte &= ~F_USE_CMD_Q;
5594 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
5595 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5597 lun = currSCCB->Lun;
5598 else
5599 lun = 0;
5602 #if defined(DOS)
5603 currTar_Info->TarLUNBusy[lun] = TRUE;
5605 #else
5607 if (CurrCard->globalFlags & F_TAG_STARTED)
5609 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
5611 if ((currTar_Info->TarLUN_CA == FALSE)
5612 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
5613 == TAG_Q_TRYING))
5616 if (currTar_Info->TarTagQ_Cnt !=0)
5618 currTar_Info->TarLUNBusy[lun] = TRUE;
5619 queueSelectFail(CurrCard,p_card);
5620 SGRAM_ACCESS(port);
5621 return;
5624 else {
5625 currTar_Info->TarLUNBusy[lun] = TRUE;
5628 } /*End non-tagged */
5630 else {
5631 currTar_Info->TarLUNBusy[lun] = TRUE;
5634 } /*!Use cmd Q Tagged */
5636 else {
5637 if (currTar_Info->TarLUN_CA == TRUE)
5639 queueSelectFail(CurrCard,p_card);
5640 SGRAM_ACCESS(port);
5641 return;
5644 currTar_Info->TarLUNBusy[lun] = TRUE;
5646 } /*else use cmd Q tagged */
5648 } /*if glob tagged started */
5650 else {
5651 currTar_Info->TarLUNBusy[lun] = TRUE;
5654 #endif /* DOS */
5658 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
5659 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5660 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
5662 if(CurrCard->discQCount >= QUEUE_DEPTH)
5664 currTar_Info->TarLUNBusy[lun] = TRUE;
5665 queueSelectFail(CurrCard,p_card);
5666 SGRAM_ACCESS(port);
5667 return;
5669 for (i = 1; i < QUEUE_DEPTH; i++)
5671 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
5672 if (CurrCard->discQ_Tbl[lastTag] == NULL)
5674 CurrCard->tagQ_Lst = lastTag;
5675 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
5676 CurrCard->discQ_Tbl[lastTag] = currSCCB;
5677 CurrCard->discQCount++;
5678 break;
5681 if(i == QUEUE_DEPTH)
5683 currTar_Info->TarLUNBusy[lun] = TRUE;
5684 queueSelectFail(CurrCard,p_card);
5685 SGRAM_ACCESS(port);
5686 return;
5692 auto_loaded = FALSE;
5694 WR_HARPOON(port+hp_select_id, target);
5695 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
5697 if (currSCCB->OperationCode == RESET_COMMAND) {
5698 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
5699 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
5701 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
5703 currSCCB->Sccb_scsimsg = SMDEV_RESET;
5705 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
5706 auto_loaded = TRUE;
5707 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
5709 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
5711 currTar_Info->TarSyncCtrl = 0;
5712 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
5715 #if defined(WIDE_SCSI)
5717 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
5719 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
5721 #endif
5723 sssyncv(port, target, NARROW_SCSI,currTar_Info);
5724 SccbMgrTableInitTarget(p_card, target);
5728 else if(currSCCB->Sccb_scsistat == ABORT_ST)
5730 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
5731 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
5733 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
5735 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
5736 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
5737 >> 6) | (UCHAR)0x20)));
5738 WRW_HARPOON((port+SYNC_MSGS+2),
5739 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
5740 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
5742 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
5743 auto_loaded = TRUE;
5747 #if defined(WIDE_SCSI)
5750 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
5751 auto_loaded = siwidn(port,p_card);
5752 currSCCB->Sccb_scsistat = SELECT_WN_ST;
5755 #endif
5758 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
5759 == SYNC_SUPPORTED)) {
5760 auto_loaded = sisyncn(port,p_card, FALSE);
5761 currSCCB->Sccb_scsistat = SELECT_SN_ST;
5765 if (!auto_loaded)
5768 #if !defined(DOS)
5769 if (currSCCB->ControlByte & F_USE_CMD_Q)
5772 CurrCard->globalFlags |= F_TAG_STARTED;
5774 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
5775 == TAG_Q_REJECT)
5777 currSCCB->ControlByte &= ~F_USE_CMD_Q;
5779 /* Fix up the start instruction with a jump to
5780 Non-Tag-CMD handling */
5781 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
5783 WRW_HARPOON((port+NON_TAG_ID_MSG),
5784 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
5786 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
5788 /* Setup our STATE so we know what happend when
5789 the wheels fall off. */
5790 currSCCB->Sccb_scsistat = SELECT_ST;
5792 currTar_Info->TarLUNBusy[lun] = TRUE;
5795 else
5797 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
5799 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
5800 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
5801 >> 6) | (UCHAR)0x20)));
5803 for (i = 1; i < QUEUE_DEPTH; i++)
5805 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
5806 if (CurrCard->discQ_Tbl[lastTag] == NULL)
5808 WRW_HARPOON((port+ID_MSG_STRT+6),
5809 (MPM_OP+AMSG_OUT+lastTag));
5810 CurrCard->tagQ_Lst = lastTag;
5811 currSCCB->Sccb_tag = lastTag;
5812 CurrCard->discQ_Tbl[lastTag] = currSCCB;
5813 CurrCard->discQCount++;
5814 break;
5819 if ( i == QUEUE_DEPTH )
5821 currTar_Info->TarLUNBusy[lun] = TRUE;
5822 queueSelectFail(CurrCard,p_card);
5823 SGRAM_ACCESS(port);
5824 return;
5827 currSCCB->Sccb_scsistat = SELECT_Q_ST;
5829 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
5833 else
5835 #endif /* !DOS */
5837 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
5839 WRW_HARPOON((port+NON_TAG_ID_MSG),
5840 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
5842 currSCCB->Sccb_scsistat = SELECT_ST;
5844 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
5845 #if !defined(DOS)
5847 #endif
5850 #if defined(OS2)
5851 theCCB = (UCHAR far *)&currSCCB->Cdb[0];
5852 #else
5853 theCCB = (UCHAR *)&currSCCB->Cdb[0];
5854 #endif
5856 cdb_reg = port + CMD_STRT;
5858 for (i=0; i < currSCCB->CdbLength; i++)
5860 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
5861 cdb_reg +=2;
5862 theCCB++;
5865 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
5866 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
5868 } /* auto_loaded */
5870 #if defined(WIDE_SCSI)
5871 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
5872 WR_HARPOON(port+hp_xferstat, 0x00);
5873 #endif
5875 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
5877 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
5880 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
5882 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
5884 else
5887 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
5888 auto_loaded |= AUTO_IMMED; */
5889 auto_loaded = AUTO_IMMED;
5891 DISABLE_AUTO(port);
5893 WR_HARPOON(port+hp_autostart_3, auto_loaded);
5896 SGRAM_ACCESS(port);
5900 /*---------------------------------------------------------------------
5902 * Function: sres
5904 * Description: Hookup the correct CCB and handle the incoming messages.
5906 *---------------------------------------------------------------------*/
5908 #if defined(DOS)
5909 void sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard)
5910 #else
5911 void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
5912 #endif
5915 #if defined(V302)
5916 #ifdef DOS
5917 UCHAR our_target,message, msgRetryCount;
5918 extern UCHAR lun, tag;
5919 #else
5920 UCHAR our_target,message,lun,tag, msgRetryCount;
5921 #endif
5923 #else /* V302 */
5924 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
5925 #endif /* V302 */
5928 PSCCBMgr_tar_info currTar_Info;
5929 PSCCB currSCCB;
5934 if(pCurrCard->currentSCCB != NULL)
5936 currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
5937 DISABLE_AUTO(port);
5940 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
5943 currSCCB = pCurrCard->currentSCCB;
5944 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5946 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
5947 currSCCB->Sccb_scsistat = BUS_FREE_ST;
5949 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5951 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
5952 currSCCB->Sccb_scsistat = BUS_FREE_ST;
5954 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
5955 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5957 currTar_Info->TarLUNBusy[currSCCB->Lun] = FALSE;
5958 if(currSCCB->Sccb_scsistat != ABORT_ST)
5960 pCurrCard->discQCount--;
5961 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
5962 = NULL;
5965 else
5967 currTar_Info->TarLUNBusy[0] = FALSE;
5968 if(currSCCB->Sccb_tag)
5970 if(currSCCB->Sccb_scsistat != ABORT_ST)
5972 pCurrCard->discQCount--;
5973 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5975 }else
5977 if(currSCCB->Sccb_scsistat != ABORT_ST)
5979 pCurrCard->discQCount--;
5980 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
5985 queueSelectFail(&BL_Card[p_card],p_card);
5988 #if defined(WIDE_SCSI)
5989 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
5990 #endif
5993 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
5994 currTar_Info = &sccbMgrTbl[p_card][our_target];
5997 msgRetryCount = 0;
6001 #if defined(V302)
6003 message = GetTarLun(port, p_card, our_target, pCurrCard, &tag, &lun);
6005 #else /* V302 */
6007 currTar_Info = &sccbMgrTbl[p_card][our_target];
6008 tag = 0;
6011 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
6013 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
6016 WRW_HARPOON((port+hp_intstat), PHASE);
6017 return;
6021 WRW_HARPOON((port+hp_intstat), PHASE);
6022 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
6025 message = sfm(port,pCurrCard->currentSCCB);
6026 if (message)
6029 if (message <= (0x80 | LUN_MASK))
6031 lun = message & (UCHAR)LUN_MASK;
6033 #if !defined(DOS)
6034 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
6036 if (currTar_Info->TarTagQ_Cnt != 0)
6039 if (!(currTar_Info->TarLUN_CA))
6041 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
6044 message = sfm(port,pCurrCard->currentSCCB);
6045 if (message)
6047 ACCEPT_MSG(port);
6050 else
6051 message = FALSE;
6053 if(message != FALSE)
6055 tag = sfm(port,pCurrCard->currentSCCB);
6057 if (!(tag))
6058 message = FALSE;
6061 } /*C.A. exists! */
6063 } /*End Q cnt != 0 */
6065 } /*End Tag cmds supported! */
6066 #endif /* !DOS */
6068 } /*End valid ID message. */
6070 else
6073 ACCEPT_MSG_ATN(port);
6076 } /* End good id message. */
6078 else
6081 message = FALSE;
6084 else
6086 ACCEPT_MSG_ATN(port);
6088 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
6089 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
6090 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
6092 return;
6095 #endif /* V302 */
6097 if(message == FALSE)
6099 msgRetryCount++;
6100 if(msgRetryCount == 1)
6102 SendMsg(port, SMPARITY);
6104 else
6106 SendMsg(port, SMDEV_RESET);
6108 sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
6110 if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
6113 sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
6117 if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
6120 sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
6124 queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
6125 SccbMgrTableInitTarget(p_card,our_target);
6126 return;
6129 }while(message == FALSE);
6133 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
6134 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
6136 currTar_Info->TarLUNBusy[lun] = TRUE;
6137 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
6138 if(pCurrCard->currentSCCB != NULL)
6140 ACCEPT_MSG(port);
6142 else
6144 ACCEPT_MSG_ATN(port);
6147 else
6149 currTar_Info->TarLUNBusy[0] = TRUE;
6152 if (tag)
6154 if (pCurrCard->discQ_Tbl[tag] != NULL)
6156 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
6157 currTar_Info->TarTagQ_Cnt--;
6158 ACCEPT_MSG(port);
6160 else
6162 ACCEPT_MSG_ATN(port);
6164 }else
6166 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
6167 if(pCurrCard->currentSCCB != NULL)
6169 ACCEPT_MSG(port);
6171 else
6173 ACCEPT_MSG_ATN(port);
6178 if(pCurrCard->currentSCCB != NULL)
6180 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
6182 /* During Abort Tag command, the target could have got re-selected
6183 and completed the command. Check the select Q and remove the CCB
6184 if it is in the Select Q */
6185 queueFindSccb(pCurrCard->currentSCCB, p_card);
6190 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
6191 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
6192 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
6195 #if defined(V302)
6197 #if defined(DOS)
6198 UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun)
6199 #else
6200 UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun)
6201 #endif
6203 UCHAR message;
6204 PSCCBMgr_tar_info currTar_Info;
6207 currTar_Info = &sccbMgrTbl[p_card][our_target];
6208 *tag = 0;
6211 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
6213 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
6216 WRW_HARPOON((port+hp_intstat), PHASE);
6217 return(TRUE);
6221 WRW_HARPOON((port+hp_intstat), PHASE);
6222 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
6225 message = sfm(port,pCurrCard->currentSCCB);
6226 if (message)
6229 if (message <= (0x80 | LUN_MASK))
6231 *lun = message & (UCHAR)LUN_MASK;
6233 #if !defined(DOS)
6234 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
6236 if (currTar_Info->TarTagQ_Cnt != 0)
6239 if (!(currTar_Info->TarLUN_CA))
6241 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
6244 message = sfm(port,pCurrCard->currentSCCB);
6245 if (message)
6247 ACCEPT_MSG(port);
6250 else
6251 return(FALSE);
6253 *tag = sfm(port,pCurrCard->currentSCCB);
6255 if (!(*tag)) return(FALSE);
6257 } /*C.A. exists! */
6259 } /*End Q cnt != 0 */
6261 } /*End Tag cmds supported! */
6262 #endif /* !DOS */
6264 } /*End valid ID message. */
6266 else
6269 ACCEPT_MSG_ATN(port);
6272 } /* End good id message. */
6274 else
6277 return(FALSE);
6280 else
6282 ACCEPT_MSG_ATN(port);
6283 return(TRUE);
6285 return(TRUE);
6288 #endif /* V302 */
6290 #if defined(DOS)
6291 void SendMsg(USHORT port, UCHAR message)
6292 #else
6293 void SendMsg(ULONG port, UCHAR message)
6294 #endif
6296 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
6298 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
6301 WRW_HARPOON((port+hp_intstat), PHASE);
6302 return;
6306 WRW_HARPOON((port+hp_intstat), PHASE);
6307 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
6309 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
6312 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
6314 WR_HARPOON(port+hp_scsidata_0,message);
6316 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6318 ACCEPT_MSG(port);
6320 WR_HARPOON(port+hp_portctrl_0, 0x00);
6322 if ((message == SMABORT) || (message == SMDEV_RESET) ||
6323 (message == SMABORT_TAG) )
6325 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
6327 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
6329 WRW_HARPOON((port+hp_intstat), BUS_FREE);
6335 /*---------------------------------------------------------------------
6337 * Function: sdecm
6339 * Description: Determine the proper responce to the message from the
6340 * target device.
6342 *---------------------------------------------------------------------*/
6343 #if defined(DOS)
6344 void sdecm(UCHAR message, USHORT port, UCHAR p_card)
6345 #else
6346 void sdecm(UCHAR message, ULONG port, UCHAR p_card)
6347 #endif
6349 PSCCB currSCCB;
6350 PSCCBcard CurrCard;
6351 PSCCBMgr_tar_info currTar_Info;
6353 CurrCard = &BL_Card[p_card];
6354 currSCCB = CurrCard->currentSCCB;
6356 currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
6358 if (message == SMREST_DATA_PTR)
6360 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
6362 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
6364 hostDataXferRestart(currSCCB);
6367 ACCEPT_MSG(port);
6368 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6371 else if (message == SMCMD_COMP)
6375 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
6377 currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
6378 currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
6381 ACCEPT_MSG(port);
6385 else if ((message == SMNO_OP) || (message >= SMIDENT)
6386 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
6389 ACCEPT_MSG(port);
6390 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6393 else if (message == SMREJECT)
6396 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
6397 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
6398 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
6399 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
6402 WRW_HARPOON((port+hp_intstat), BUS_FREE);
6404 ACCEPT_MSG(port);
6407 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
6408 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
6410 if(currSCCB->Lun == 0x00)
6412 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
6415 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
6417 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
6420 #if defined(WIDE_SCSI)
6421 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
6425 currTar_Info->TarStatus = (currTar_Info->TarStatus &
6426 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
6428 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
6431 #endif
6433 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
6435 currTar_Info->TarStatus = (currTar_Info->TarStatus &
6436 ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
6439 currSCCB->ControlByte &= ~F_USE_CMD_Q;
6440 CurrCard->discQCount--;
6441 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
6442 currSCCB->Sccb_tag = 0x00;
6447 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
6451 if(currSCCB->Lun == 0x00)
6453 WRW_HARPOON((port+hp_intstat), BUS_FREE);
6454 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
6458 else
6461 if((CurrCard->globalFlags & F_CONLUN_IO) &&
6462 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6463 currTar_Info->TarLUNBusy[currSCCB->Lun] = TRUE;
6464 else
6465 currTar_Info->TarLUNBusy[0] = TRUE;
6468 currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
6470 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6475 else
6477 ACCEPT_MSG(port);
6479 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
6480 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
6482 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
6484 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6489 else if (message == SMEXT)
6492 ACCEPT_MSG(port);
6493 shandem(port,p_card,currSCCB);
6496 else if (message == SMIGNORWR)
6499 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
6501 message = sfm(port,currSCCB);
6503 if(currSCCB->Sccb_scsimsg != SMPARITY)
6504 ACCEPT_MSG(port);
6505 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6509 else
6512 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
6513 currSCCB->Sccb_scsimsg = SMREJECT;
6515 ACCEPT_MSG_ATN(port);
6516 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6521 /*---------------------------------------------------------------------
6523 * Function: shandem
6525 * Description: Decide what to do with the extended message.
6527 *---------------------------------------------------------------------*/
6528 #if defined(DOS)
6529 void shandem(USHORT port, UCHAR p_card, PSCCB pCurrSCCB)
6530 #else
6531 void shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
6532 #endif
6534 UCHAR length,message;
6536 length = sfm(port,pCurrSCCB);
6537 if (length)
6540 ACCEPT_MSG(port);
6541 message = sfm(port,pCurrSCCB);
6542 if (message)
6545 if (message == SMSYNC)
6548 if (length == 0x03)
6551 ACCEPT_MSG(port);
6552 stsyncn(port,p_card);
6554 else
6557 pCurrSCCB->Sccb_scsimsg = SMREJECT;
6558 ACCEPT_MSG_ATN(port);
6561 #if defined(WIDE_SCSI)
6562 else if (message == SMWDTR)
6565 if (length == 0x02)
6568 ACCEPT_MSG(port);
6569 stwidn(port,p_card);
6571 else
6574 pCurrSCCB->Sccb_scsimsg = SMREJECT;
6575 ACCEPT_MSG_ATN(port);
6577 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6580 #endif
6581 else
6584 pCurrSCCB->Sccb_scsimsg = SMREJECT;
6585 ACCEPT_MSG_ATN(port);
6587 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6590 else
6592 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
6593 ACCEPT_MSG(port);
6594 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6596 }else
6598 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
6599 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6604 /*---------------------------------------------------------------------
6606 * Function: sisyncn
6608 * Description: Read in a message byte from the SCSI bus, and check
6609 * for a parity error.
6611 *---------------------------------------------------------------------*/
6613 #if defined(DOS)
6614 UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag)
6615 #else
6616 UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
6617 #endif
6619 PSCCB currSCCB;
6620 PSCCBMgr_tar_info currTar_Info;
6622 currSCCB = BL_Card[p_card].currentSCCB;
6623 currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
6625 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
6628 WRW_HARPOON((port+ID_MSG_STRT),
6629 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
6631 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
6633 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
6634 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
6635 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
6638 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
6640 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
6642 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
6644 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
6646 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
6648 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
6650 else
6651 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
6654 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
6655 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
6656 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
6659 if(syncFlag == FALSE)
6661 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
6662 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
6663 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
6665 else
6667 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
6671 return(TRUE);
6674 else {
6676 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
6677 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
6678 return(FALSE);
6684 /*---------------------------------------------------------------------
6686 * Function: stsyncn
6688 * Description: The has sent us a Sync Nego message so handle it as
6689 * necessary.
6691 *---------------------------------------------------------------------*/
6692 #if defined(DOS)
6693 void stsyncn(USHORT port, UCHAR p_card)
6694 #else
6695 void stsyncn(ULONG port, UCHAR p_card)
6696 #endif
6698 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
6699 PSCCB currSCCB;
6700 PSCCBMgr_tar_info currTar_Info;
6702 currSCCB = BL_Card[p_card].currentSCCB;
6703 currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
6705 sync_msg = sfm(port,currSCCB);
6707 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
6709 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6710 return;
6713 ACCEPT_MSG(port);
6716 offset = sfm(port,currSCCB);
6718 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
6720 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6721 return;
6724 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
6726 our_sync_msg = 12; /* Setup our Message to 20mb/s */
6728 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
6730 our_sync_msg = 25; /* Setup our Message to 10mb/s */
6732 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
6734 our_sync_msg = 50; /* Setup our Message to 5mb/s */
6735 else
6737 our_sync_msg = 0; /* Message = Async */
6739 if (sync_msg < our_sync_msg) {
6740 sync_msg = our_sync_msg; /*if faster, then set to max. */
6743 if (offset == ASYNC)
6744 sync_msg = ASYNC;
6746 if (offset > MAX_OFFSET)
6747 offset = MAX_OFFSET;
6749 sync_reg = 0x00;
6751 if (sync_msg > 12)
6753 sync_reg = 0x20; /* Use 10MB/s */
6755 if (sync_msg > 25)
6757 sync_reg = 0x40; /* Use 6.6MB/s */
6759 if (sync_msg > 38)
6761 sync_reg = 0x60; /* Use 5MB/s */
6763 if (sync_msg > 50)
6765 sync_reg = 0x80; /* Use 4MB/s */
6767 if (sync_msg > 62)
6769 sync_reg = 0xA0; /* Use 3.33MB/s */
6771 if (sync_msg > 75)
6773 sync_reg = 0xC0; /* Use 2.85MB/s */
6775 if (sync_msg > 87)
6777 sync_reg = 0xE0; /* Use 2.5MB/s */
6779 if (sync_msg > 100) {
6781 sync_reg = 0x00; /* Use ASYNC */
6782 offset = 0x00;
6786 #if defined(WIDE_SCSI)
6787 if (currTar_Info->TarStatus & WIDE_ENABLED)
6789 sync_reg |= offset;
6791 else
6793 sync_reg |= (offset | NARROW_SCSI);
6795 #else
6796 sync_reg |= (offset | NARROW_SCSI);
6797 #endif
6799 sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
6802 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
6805 ACCEPT_MSG(port);
6807 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
6808 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
6810 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6813 else {
6816 ACCEPT_MSG_ATN(port);
6818 sisyncr(port,sync_msg,offset);
6820 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
6821 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
6826 /*---------------------------------------------------------------------
6828 * Function: sisyncr
6830 * Description: Answer the targets sync message.
6832 *---------------------------------------------------------------------*/
6833 #if defined(DOS)
6834 void sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset)
6835 #else
6836 void sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
6837 #endif
6839 ARAM_ACCESS(port);
6840 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
6841 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
6842 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
6843 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
6844 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
6845 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
6846 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
6847 SGRAM_ACCESS(port);
6849 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
6850 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
6852 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
6854 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
6859 #if defined(WIDE_SCSI)
6861 /*---------------------------------------------------------------------
6863 * Function: siwidn
6865 * Description: Read in a message byte from the SCSI bus, and check
6866 * for a parity error.
6868 *---------------------------------------------------------------------*/
6870 #if defined(DOS)
6871 UCHAR siwidn(USHORT port, UCHAR p_card)
6872 #else
6873 UCHAR siwidn(ULONG port, UCHAR p_card)
6874 #endif
6876 PSCCB currSCCB;
6877 PSCCBMgr_tar_info currTar_Info;
6879 currSCCB = BL_Card[p_card].currentSCCB;
6880 currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
6882 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
6885 WRW_HARPOON((port+ID_MSG_STRT),
6886 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
6888 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
6890 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
6891 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
6892 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
6893 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
6894 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
6895 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
6897 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
6900 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
6901 ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
6903 return(TRUE);
6906 else {
6908 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
6909 ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
6911 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
6912 return(FALSE);
6918 /*---------------------------------------------------------------------
6920 * Function: stwidn
6922 * Description: The has sent us a Wide Nego message so handle it as
6923 * necessary.
6925 *---------------------------------------------------------------------*/
6926 #if defined(DOS)
6927 void stwidn(USHORT port, UCHAR p_card)
6928 #else
6929 void stwidn(ULONG port, UCHAR p_card)
6930 #endif
6932 UCHAR width;
6933 PSCCB currSCCB;
6934 PSCCBMgr_tar_info currTar_Info;
6936 currSCCB = BL_Card[p_card].currentSCCB;
6937 currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
6939 width = sfm(port,currSCCB);
6941 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
6943 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6944 return;
6948 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
6949 width = 0;
6951 if (width) {
6952 currTar_Info->TarStatus |= WIDE_ENABLED;
6953 width = 0;
6955 else {
6956 width = NARROW_SCSI;
6957 currTar_Info->TarStatus &= ~WIDE_ENABLED;
6961 sssyncv(port,currSCCB->TargID,width,currTar_Info);
6964 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
6969 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
6971 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
6973 ACCEPT_MSG_ATN(port);
6974 ARAM_ACCESS(port);
6975 sisyncn(port,p_card, TRUE);
6976 currSCCB->Sccb_scsistat = SELECT_SN_ST;
6977 SGRAM_ACCESS(port);
6979 else
6981 ACCEPT_MSG(port);
6982 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
6986 else {
6989 ACCEPT_MSG_ATN(port);
6991 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
6992 width = SM16BIT;
6993 else
6994 width = SM8BIT;
6996 siwidr(port,width);
6998 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
7003 /*---------------------------------------------------------------------
7005 * Function: siwidr
7007 * Description: Answer the targets Wide nego message.
7009 *---------------------------------------------------------------------*/
7010 #if defined(DOS)
7011 void siwidr(USHORT port, UCHAR width)
7012 #else
7013 void siwidr(ULONG port, UCHAR width)
7014 #endif
7016 ARAM_ACCESS(port);
7017 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
7018 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
7019 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
7020 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
7021 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
7022 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
7023 SGRAM_ACCESS(port);
7025 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
7026 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
7028 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
7030 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
7033 #endif
7037 /*---------------------------------------------------------------------
7039 * Function: sssyncv
7041 * Description: Write the desired value to the Sync Register for the
7042 * ID specified.
7044 *---------------------------------------------------------------------*/
7045 #if defined(DOS)
7046 void sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info)
7047 #else
7048 void sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info)
7049 #endif
7051 UCHAR index;
7053 index = p_id;
7055 switch (index) {
7057 case 0:
7058 index = 12; /* hp_synctarg_0 */
7059 break;
7060 case 1:
7061 index = 13; /* hp_synctarg_1 */
7062 break;
7063 case 2:
7064 index = 14; /* hp_synctarg_2 */
7065 break;
7066 case 3:
7067 index = 15; /* hp_synctarg_3 */
7068 break;
7069 case 4:
7070 index = 8; /* hp_synctarg_4 */
7071 break;
7072 case 5:
7073 index = 9; /* hp_synctarg_5 */
7074 break;
7075 case 6:
7076 index = 10; /* hp_synctarg_6 */
7077 break;
7078 case 7:
7079 index = 11; /* hp_synctarg_7 */
7080 break;
7081 case 8:
7082 index = 4; /* hp_synctarg_8 */
7083 break;
7084 case 9:
7085 index = 5; /* hp_synctarg_9 */
7086 break;
7087 case 10:
7088 index = 6; /* hp_synctarg_10 */
7089 break;
7090 case 11:
7091 index = 7; /* hp_synctarg_11 */
7092 break;
7093 case 12:
7094 index = 0; /* hp_synctarg_12 */
7095 break;
7096 case 13:
7097 index = 1; /* hp_synctarg_13 */
7098 break;
7099 case 14:
7100 index = 2; /* hp_synctarg_14 */
7101 break;
7102 case 15:
7103 index = 3; /* hp_synctarg_15 */
7107 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
7109 currTar_Info->TarSyncCtrl = p_sync_value;
7113 /*---------------------------------------------------------------------
7115 * Function: sresb
7117 * Description: Reset the desired card's SCSI bus.
7119 *---------------------------------------------------------------------*/
7120 #if defined(DOS)
7121 void sresb(USHORT port, UCHAR p_card)
7122 #else
7123 void sresb(ULONG port, UCHAR p_card)
7124 #endif
7126 UCHAR scsiID, i;
7128 PSCCBMgr_tar_info currTar_Info;
7130 WR_HARPOON(port+hp_page_ctrl,
7131 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
7132 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
7134 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
7136 scsiID = RD_HARPOON(port+hp_seltimeout);
7137 WR_HARPOON(port+hp_seltimeout,TO_5ms);
7138 WRW_HARPOON((port+hp_intstat), TIMEOUT);
7140 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
7142 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
7144 WR_HARPOON(port+hp_seltimeout,scsiID);
7146 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
7148 Wait(port, TO_5ms);
7150 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
7152 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
7154 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
7156 currTar_Info = &sccbMgrTbl[p_card][scsiID];
7158 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
7160 currTar_Info->TarSyncCtrl = 0;
7161 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
7164 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
7166 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
7169 sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
7171 SccbMgrTableInitTarget(p_card, scsiID);
7174 BL_Card[p_card].scanIndex = 0x00;
7175 BL_Card[p_card].currentSCCB = NULL;
7176 BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
7177 | F_NEW_SCCB_CMD);
7178 BL_Card[p_card].cmdCounter = 0x00;
7179 BL_Card[p_card].discQCount = 0x00;
7180 BL_Card[p_card].tagQ_Lst = 0x01;
7182 for(i = 0; i < QUEUE_DEPTH; i++)
7183 BL_Card[p_card].discQ_Tbl[i] = NULL;
7185 WR_HARPOON(port+hp_page_ctrl,
7186 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
7190 /*---------------------------------------------------------------------
7192 * Function: ssenss
7194 * Description: Setup for the Auto Sense command.
7196 *---------------------------------------------------------------------*/
7197 void ssenss(PSCCBcard pCurrCard)
7199 UCHAR i;
7200 PSCCB currSCCB;
7202 currSCCB = pCurrCard->currentSCCB;
7205 currSCCB->Save_CdbLen = currSCCB->CdbLength;
7207 for (i = 0; i < 6; i++) {
7209 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
7212 currSCCB->CdbLength = SIX_BYTE_CMD;
7213 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
7214 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
7215 currSCCB->Cdb[2] = 0x00;
7216 currSCCB->Cdb[3] = 0x00;
7217 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
7218 currSCCB->Cdb[5] = 0x00;
7220 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
7222 currSCCB->Sccb_ATC = 0x00;
7224 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
7226 currSCCB->Sccb_XferState &= ~F_SG_XFER;
7228 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
7230 currSCCB->ControlByte = 0x00;
7232 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
7237 /*---------------------------------------------------------------------
7239 * Function: sxfrp
7241 * Description: Transfer data into the bit bucket until the device
7242 * decides to switch phase.
7244 *---------------------------------------------------------------------*/
7246 #if defined(DOS)
7247 void sxfrp(USHORT p_port, UCHAR p_card)
7248 #else
7249 void sxfrp(ULONG p_port, UCHAR p_card)
7250 #endif
7252 UCHAR curr_phz;
7255 DISABLE_AUTO(p_port);
7257 if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
7259 hostDataXferAbort(p_port,p_card,BL_Card[p_card].currentSCCB);
7263 /* If the Automation handled the end of the transfer then do not
7264 match the phase or we will get out of sync with the ISR. */
7266 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
7267 return;
7269 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
7271 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
7273 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
7276 WR_HARPOON(p_port+hp_scsisig, curr_phz);
7278 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
7279 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
7281 if (curr_phz & (UCHAR)SCSI_IOBIT)
7283 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
7285 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
7287 RD_HARPOON(p_port+hp_fifodata_0);
7290 else
7292 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
7293 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
7295 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
7298 } /* End of While loop for padding data I/O phase */
7300 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
7302 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
7303 break;
7306 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
7307 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
7309 RD_HARPOON(p_port+hp_fifodata_0);
7312 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
7314 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
7315 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
7317 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
7318 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
7323 /*---------------------------------------------------------------------
7325 * Function: schkdd
7327 * Description: Make sure data has been flushed from both FIFOs and abort
7328 * the operations if necessary.
7330 *---------------------------------------------------------------------*/
7332 #if defined(DOS)
7333 void schkdd(USHORT port, UCHAR p_card)
7334 #else
7335 void schkdd(ULONG port, UCHAR p_card)
7336 #endif
7338 USHORT TimeOutLoop;
7339 UCHAR sPhase;
7341 PSCCB currSCCB;
7343 currSCCB = BL_Card[p_card].currentSCCB;
7346 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
7347 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
7348 return;
7353 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
7356 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
7358 currSCCB->Sccb_XferCnt = 1;
7360 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
7361 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
7362 WR_HARPOON(port+hp_xferstat, 0x00);
7365 else
7368 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
7370 currSCCB->Sccb_XferCnt = 0;
7373 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
7374 (currSCCB->HostStatus == SCCB_COMPLETE)) {
7376 currSCCB->HostStatus = SCCB_PARITY_ERR;
7377 WRW_HARPOON((port+hp_intstat), PARITY);
7381 hostDataXferAbort(port,p_card,currSCCB);
7384 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
7386 TimeOutLoop = 0;
7388 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
7390 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
7391 return;
7393 if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
7394 break;
7396 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
7397 return;
7399 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
7400 break;
7403 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
7404 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
7405 (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) ||
7406 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
7407 (sPhase == (SCSI_BSY | S_DATAI_PH)))
7410 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
7412 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
7414 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
7415 phaseDataIn(port,p_card);
7418 else {
7419 phaseDataOut(port,p_card);
7422 else
7424 sxfrp(port,p_card);
7425 if (!(RDW_HARPOON((port+hp_intstat)) &
7426 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
7428 WRW_HARPOON((port+hp_intstat), AUTO_INT);
7429 phaseDecode(port,p_card);
7435 else {
7436 WR_HARPOON(port+hp_portctrl_0, 0x00);
7441 /*---------------------------------------------------------------------
7443 * Function: sinits
7445 * Description: Setup SCCB manager fields in this SCCB.
7447 *---------------------------------------------------------------------*/
7449 void sinits(PSCCB p_sccb, UCHAR p_card)
7451 PSCCBMgr_tar_info currTar_Info;
7453 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
7455 return;
7457 currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
7459 p_sccb->Sccb_XferState = 0x00;
7460 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
7462 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
7463 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
7465 p_sccb->Sccb_SGoffset = 0;
7466 p_sccb->Sccb_XferState = F_SG_XFER;
7467 p_sccb->Sccb_XferCnt = 0x00;
7470 if (p_sccb->DataLength == 0x00)
7472 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
7474 if (p_sccb->ControlByte & F_USE_CMD_Q)
7476 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
7477 p_sccb->ControlByte &= ~F_USE_CMD_Q;
7479 else
7480 currTar_Info->TarStatus |= TAG_Q_TRYING;
7483 /* For !single SCSI device in system & device allow Disconnect
7484 or command is tag_q type then send Cmd with Disconnect Enable
7485 else send Cmd with Disconnect Disable */
7488 if (((!(BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
7489 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
7490 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
7492 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
7493 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
7494 p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
7497 else {
7499 p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun;
7502 p_sccb->HostStatus = 0x00;
7503 p_sccb->TargetStatus = 0x00;
7504 p_sccb->Sccb_tag = 0x00;
7505 p_sccb->Sccb_MGRFlags = 0x00;
7506 p_sccb->Sccb_sgseg = 0x00;
7507 p_sccb->Sccb_ATC = 0x00;
7508 p_sccb->Sccb_savedATC = 0x00;
7510 p_sccb->SccbVirtDataPtr = 0x00;
7511 p_sccb->Sccb_forwardlink = NULL;
7512 p_sccb->Sccb_backlink = NULL;
7514 p_sccb->Sccb_scsistat = BUS_FREE_ST;
7515 p_sccb->SccbStatus = SCCB_IN_PROCESS;
7516 p_sccb->Sccb_scsimsg = SMNO_OP;
7521 #ident "$Id: phase.c 1.11 1997/01/31 02:08:49 mohan Exp $"
7522 /*----------------------------------------------------------------------
7525 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
7527 * This file is available under both the GNU General Public License
7528 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
7530 * $Workfile: phase.c $
7532 * Description: Functions to intially handle the SCSI bus phase when
7533 * the target asserts request (and the automation is not
7534 * enabled to handle the situation).
7536 * $Date: 1997/01/31 02:08:49 $
7538 * $Revision: 1.11 $
7540 *----------------------------------------------------------------------*/
7542 /*#include <globals.h>*/
7544 #if (FW_TYPE==_UCB_MGR_)
7545 /*#include <budi.h>*/
7546 #endif
7548 /*#include <sccbmgr.h>*/
7549 /*#include <blx30.h>*/
7550 /*#include <target.h>*/
7551 /*#include <scsi2.h>*/
7552 /*#include <harpoon.h>*/
7556 extern SCCBCARD BL_Card[MAX_CARDS];
7557 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
7559 #if defined(OS2)
7560 extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
7561 #else
7562 #if defined(DOS)
7563 extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
7564 #else
7565 extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
7566 #endif
7567 #endif
7570 /*---------------------------------------------------------------------
7572 * Function: Phase Decode
7574 * Description: Determine the phase and call the appropriate function.
7576 *---------------------------------------------------------------------*/
7578 #if defined(DOS)
7579 void phaseDecode(USHORT p_port, UCHAR p_card)
7580 #else
7581 void phaseDecode(ULONG p_port, UCHAR p_card)
7582 #endif
7584 unsigned char phase_ref;
7585 #if defined(OS2)
7586 void (far *phase) (ULONG, UCHAR);
7587 #else
7588 #if defined(DOS)
7589 void (*phase) (USHORT, UCHAR);
7590 #else
7591 void (*phase) (ULONG, UCHAR);
7592 #endif
7593 #endif
7596 DISABLE_AUTO(p_port);
7598 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
7600 phase = s_PhaseTbl[phase_ref];
7602 (*phase)(p_port, p_card); /* Call the correct phase func */
7607 /*---------------------------------------------------------------------
7609 * Function: Data Out Phase
7611 * Description: Start up both the BusMaster and Xbow.
7613 *---------------------------------------------------------------------*/
7615 #if defined(OS2)
7616 void far phaseDataOut(ULONG port, UCHAR p_card)
7617 #else
7618 #if defined(DOS)
7619 void phaseDataOut(USHORT port, UCHAR p_card)
7620 #else
7621 void phaseDataOut(ULONG port, UCHAR p_card)
7622 #endif
7623 #endif
7626 PSCCB currSCCB;
7628 currSCCB = BL_Card[p_card].currentSCCB;
7629 if (currSCCB == NULL)
7631 return; /* Exit if No SCCB record */
7634 currSCCB->Sccb_scsistat = DATA_OUT_ST;
7635 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
7637 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
7639 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
7641 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
7643 dataXferProcessor(port, &BL_Card[p_card]);
7645 #if defined(NOBUGBUG)
7646 if (RDW_HARPOON((port+hp_intstat)) & XFER_CNT_0)
7647 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
7649 #endif
7652 if (currSCCB->Sccb_XferCnt == 0) {
7655 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
7656 (currSCCB->HostStatus == SCCB_COMPLETE))
7657 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
7659 sxfrp(port,p_card);
7660 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
7661 phaseDecode(port,p_card);
7666 /*---------------------------------------------------------------------
7668 * Function: Data In Phase
7670 * Description: Startup the BusMaster and the XBOW.
7672 *---------------------------------------------------------------------*/
7674 #if defined(OS2)
7675 void far phaseDataIn(ULONG port, UCHAR p_card)
7676 #else
7677 #if defined(DOS)
7678 void phaseDataIn(USHORT port, UCHAR p_card)
7679 #else
7680 void phaseDataIn(ULONG port, UCHAR p_card)
7681 #endif
7682 #endif
7685 PSCCB currSCCB;
7687 currSCCB = BL_Card[p_card].currentSCCB;
7689 if (currSCCB == NULL)
7691 return; /* Exit if No SCCB record */
7695 currSCCB->Sccb_scsistat = DATA_IN_ST;
7696 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
7697 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
7699 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
7701 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
7703 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
7705 dataXferProcessor(port, &BL_Card[p_card]);
7707 if (currSCCB->Sccb_XferCnt == 0) {
7710 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
7711 (currSCCB->HostStatus == SCCB_COMPLETE))
7712 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
7714 sxfrp(port,p_card);
7715 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
7716 phaseDecode(port,p_card);
7721 /*---------------------------------------------------------------------
7723 * Function: Command Phase
7725 * Description: Load the CDB into the automation and start it up.
7727 *---------------------------------------------------------------------*/
7729 #if defined(OS2)
7730 void far phaseCommand(ULONG p_port, UCHAR p_card)
7731 #else
7732 #if defined(DOS)
7733 void phaseCommand(USHORT p_port, UCHAR p_card)
7734 #else
7735 void phaseCommand(ULONG p_port, UCHAR p_card)
7736 #endif
7737 #endif
7739 PSCCB currSCCB;
7740 #if defined(DOS)
7741 USHORT cdb_reg;
7742 #else
7743 ULONG cdb_reg;
7744 #endif
7745 UCHAR i;
7747 currSCCB = BL_Card[p_card].currentSCCB;
7749 if (currSCCB->OperationCode == RESET_COMMAND) {
7751 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
7752 currSCCB->CdbLength = SIX_BYTE_CMD;
7755 WR_HARPOON(p_port+hp_scsisig, 0x00);
7757 ARAM_ACCESS(p_port);
7760 cdb_reg = p_port + CMD_STRT;
7762 for (i=0; i < currSCCB->CdbLength; i++) {
7764 if (currSCCB->OperationCode == RESET_COMMAND)
7766 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
7768 else
7769 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
7770 cdb_reg +=2;
7773 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
7774 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
7776 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
7778 currSCCB->Sccb_scsistat = COMMAND_ST;
7780 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
7781 SGRAM_ACCESS(p_port);
7785 /*---------------------------------------------------------------------
7787 * Function: Status phase
7789 * Description: Bring in the status and command complete message bytes
7791 *---------------------------------------------------------------------*/
7793 #if defined(OS2)
7794 void far phaseStatus(ULONG port, UCHAR p_card)
7795 #else
7796 #if defined(DOS)
7797 void phaseStatus(USHORT port, UCHAR p_card)
7798 #else
7799 void phaseStatus(ULONG port, UCHAR p_card)
7800 #endif
7801 #endif
7803 /* Start-up the automation to finish off this command and let the
7804 isr handle the interrupt for command complete when it comes in.
7805 We could wait here for the interrupt to be generated?
7808 WR_HARPOON(port+hp_scsisig, 0x00);
7810 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
7814 /*---------------------------------------------------------------------
7816 * Function: Phase Message Out
7818 * Description: Send out our message (if we have one) and handle whatever
7819 * else is involed.
7821 *---------------------------------------------------------------------*/
7823 #if defined(OS2)
7824 void far phaseMsgOut(ULONG port, UCHAR p_card)
7825 #else
7826 #if defined(DOS)
7827 void phaseMsgOut(USHORT port, UCHAR p_card)
7828 #else
7829 void phaseMsgOut(ULONG port, UCHAR p_card)
7830 #endif
7831 #endif
7833 UCHAR message,scsiID;
7834 PSCCB currSCCB;
7835 PSCCBMgr_tar_info currTar_Info;
7837 currSCCB = BL_Card[p_card].currentSCCB;
7839 if (currSCCB != NULL) {
7841 message = currSCCB->Sccb_scsimsg;
7842 scsiID = currSCCB->TargID;
7844 if (message == SMDEV_RESET)
7848 currTar_Info = &sccbMgrTbl[p_card][scsiID];
7849 currTar_Info->TarSyncCtrl = 0;
7850 sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
7852 if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
7855 sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
7859 if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
7862 sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
7866 queueFlushSccb(p_card,SCCB_COMPLETE);
7867 SccbMgrTableInitTarget(p_card,scsiID);
7869 else if (currSCCB->Sccb_scsistat == ABORT_ST)
7871 currSCCB->HostStatus = SCCB_COMPLETE;
7872 if(BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
7874 BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
7875 sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
7880 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
7884 if(message == SMNO_OP)
7886 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
7888 ssel(port,p_card);
7889 return;
7892 else
7896 if (message == SMABORT)
7898 queueFlushSccb(p_card,SCCB_COMPLETE);
7902 else
7904 message = SMABORT;
7907 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
7910 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
7912 WR_HARPOON(port+hp_scsidata_0,message);
7914 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
7916 ACCEPT_MSG(port);
7918 WR_HARPOON(port+hp_portctrl_0, 0x00);
7920 if ((message == SMABORT) || (message == SMDEV_RESET) ||
7921 (message == SMABORT_TAG) )
7924 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
7926 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
7928 WRW_HARPOON((port+hp_intstat), BUS_FREE);
7930 if (currSCCB != NULL)
7933 if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7934 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
7935 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
7936 else
7937 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
7939 queueCmdComplete(&BL_Card[p_card],currSCCB, p_card);
7942 else
7944 BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
7948 else
7951 sxfrp(port,p_card);
7955 else
7958 if(message == SMPARITY)
7960 currSCCB->Sccb_scsimsg = SMNO_OP;
7961 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
7963 else
7965 sxfrp(port,p_card);
7971 /*---------------------------------------------------------------------
7973 * Function: Message In phase
7975 * Description: Bring in the message and determine what to do with it.
7977 *---------------------------------------------------------------------*/
7979 #if defined(OS2)
7980 void far phaseMsgIn(ULONG port, UCHAR p_card)
7981 #else
7982 #if defined(DOS)
7983 void phaseMsgIn(USHORT port, UCHAR p_card)
7984 #else
7985 void phaseMsgIn(ULONG port, UCHAR p_card)
7986 #endif
7987 #endif
7989 UCHAR message;
7990 PSCCB currSCCB;
7992 currSCCB = BL_Card[p_card].currentSCCB;
7994 if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
7997 phaseChkFifo(port, p_card);
8000 message = RD_HARPOON(port+hp_scsidata_0);
8001 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
8004 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
8008 else
8011 message = sfm(port,currSCCB);
8012 if (message)
8016 sdecm(message,port,p_card);
8019 else
8021 if(currSCCB->Sccb_scsimsg != SMPARITY)
8022 ACCEPT_MSG(port);
8023 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
8030 /*---------------------------------------------------------------------
8032 * Function: Illegal phase
8034 * Description: Target switched to some illegal phase, so all we can do
8035 * is report an error back to the host (if that is possible)
8036 * and send an ABORT message to the misbehaving target.
8038 *---------------------------------------------------------------------*/
8040 #if defined(OS2)
8041 void far phaseIllegal(ULONG port, UCHAR p_card)
8042 #else
8043 #if defined(DOS)
8044 void phaseIllegal(USHORT port, UCHAR p_card)
8045 #else
8046 void phaseIllegal(ULONG port, UCHAR p_card)
8047 #endif
8048 #endif
8050 PSCCB currSCCB;
8052 currSCCB = BL_Card[p_card].currentSCCB;
8054 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
8055 if (currSCCB != NULL) {
8057 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
8058 currSCCB->Sccb_scsistat = ABORT_ST;
8059 currSCCB->Sccb_scsimsg = SMABORT;
8062 ACCEPT_MSG_ATN(port);
8067 /*---------------------------------------------------------------------
8069 * Function: Phase Check FIFO
8071 * Description: Make sure data has been flushed from both FIFOs and abort
8072 * the operations if necessary.
8074 *---------------------------------------------------------------------*/
8076 #if defined(DOS)
8077 void phaseChkFifo(USHORT port, UCHAR p_card)
8078 #else
8079 void phaseChkFifo(ULONG port, UCHAR p_card)
8080 #endif
8082 ULONG xfercnt;
8083 PSCCB currSCCB;
8085 currSCCB = BL_Card[p_card].currentSCCB;
8087 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
8090 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
8091 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
8094 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
8096 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
8098 currSCCB->Sccb_XferCnt = 0;
8100 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
8101 (currSCCB->HostStatus == SCCB_COMPLETE))
8103 currSCCB->HostStatus = SCCB_PARITY_ERR;
8104 WRW_HARPOON((port+hp_intstat), PARITY);
8107 hostDataXferAbort(port,p_card,currSCCB);
8109 dataXferProcessor(port, &BL_Card[p_card]);
8111 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
8112 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
8115 } /*End Data In specific code. */
8119 #if defined(DOS)
8120 asm { mov dx,port;
8121 add dx,hp_xfercnt_2;
8122 in al,dx;
8123 dec dx;
8124 xor ah,ah;
8125 mov word ptr xfercnt+2,ax;
8126 in al,dx;
8127 dec dx;
8128 mov ah,al;
8129 in al,dx;
8130 mov word ptr xfercnt,ax;
8132 #else
8133 GET_XFER_CNT(port,xfercnt);
8134 #endif
8137 WR_HARPOON(port+hp_xfercnt_0, 0x00);
8140 WR_HARPOON(port+hp_portctrl_0, 0x00);
8142 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
8144 currSCCB->Sccb_XferCnt = xfercnt;
8146 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
8147 (currSCCB->HostStatus == SCCB_COMPLETE)) {
8149 currSCCB->HostStatus = SCCB_PARITY_ERR;
8150 WRW_HARPOON((port+hp_intstat), PARITY);
8154 hostDataXferAbort(port,p_card,currSCCB);
8157 WR_HARPOON(port+hp_fifowrite, 0x00);
8158 WR_HARPOON(port+hp_fiforead, 0x00);
8159 WR_HARPOON(port+hp_xferstat, 0x00);
8161 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
8165 /*---------------------------------------------------------------------
8167 * Function: Phase Bus Free
8169 * Description: We just went bus free so figure out if it was
8170 * because of command complete or from a disconnect.
8172 *---------------------------------------------------------------------*/
8173 #if defined(DOS)
8174 void phaseBusFree(USHORT port, UCHAR p_card)
8175 #else
8176 void phaseBusFree(ULONG port, UCHAR p_card)
8177 #endif
8179 PSCCB currSCCB;
8181 currSCCB = BL_Card[p_card].currentSCCB;
8183 if (currSCCB != NULL)
8186 DISABLE_AUTO(port);
8189 if (currSCCB->OperationCode == RESET_COMMAND)
8192 if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8193 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
8194 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
8195 else
8196 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
8198 queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
8200 queueSearchSelect(&BL_Card[p_card],p_card);
8204 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
8206 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
8207 (UCHAR)SYNC_SUPPORTED;
8208 sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
8211 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
8213 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
8214 (sccbMgrTbl[p_card][currSCCB->TargID].
8215 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
8217 sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
8220 #if !defined(DOS)
8221 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
8223 /* Make sure this is not a phony BUS_FREE. If we were
8224 reselected or if BUSY is NOT on then this is a
8225 valid BUS FREE. SRR Wednesday, 5/10/1995. */
8227 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
8228 (RDW_HARPOON((port+hp_intstat)) & RSEL))
8230 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
8231 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
8234 else
8236 return;
8239 #endif
8241 else
8244 currSCCB->Sccb_scsistat = BUS_FREE_ST;
8246 if (!currSCCB->HostStatus)
8248 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
8251 if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8252 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
8253 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
8254 else
8255 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
8257 queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
8258 return;
8262 BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
8264 } /*end if !=null */
8270 #ident "$Id: automate.c 1.14 1997/01/31 02:11:46 mohan Exp $"
8271 /*----------------------------------------------------------------------
8274 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
8276 * This file is available under both the GNU General Public License
8277 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
8279 * $Workfile: automate.c $
8281 * Description: Functions relating to programming the automation of
8282 * the HARPOON.
8284 * $Date: 1997/01/31 02:11:46 $
8286 * $Revision: 1.14 $
8288 *----------------------------------------------------------------------*/
8290 /*#include <globals.h>*/
8292 #if (FW_TYPE==_UCB_MGR_)
8293 /*#include <budi.h>*/
8294 #endif
8296 /*#include <sccbmgr.h>*/
8297 /*#include <blx30.h>*/
8298 /*#include <target.h>*/
8299 /*#include <scsi2.h>*/
8300 /*#include <harpoon.h>*/
8303 extern SCCBCARD BL_Card[MAX_CARDS];
8304 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
8305 extern SCCBCARD BL_Card[MAX_CARDS];
8308 /*---------------------------------------------------------------------
8310 * Function: Auto Load Default Map
8312 * Description: Load the Automation RAM with the defualt map values.
8314 *---------------------------------------------------------------------*/
8315 #if defined(DOS)
8316 void autoLoadDefaultMap(USHORT p_port)
8317 #else
8318 void autoLoadDefaultMap(ULONG p_port)
8319 #endif
8321 #if defined(DOS)
8322 USHORT map_addr;
8323 #else
8324 ULONG map_addr;
8325 #endif
8327 ARAM_ACCESS(p_port);
8328 map_addr = p_port + hp_aramBase;
8330 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
8331 map_addr +=2;
8332 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
8333 map_addr +=2;
8334 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
8335 map_addr +=2;
8336 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
8337 map_addr +=2;
8338 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
8339 map_addr +=2;
8340 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
8341 map_addr +=2;
8342 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
8343 map_addr +=2;
8344 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
8345 map_addr +=2;
8346 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
8347 map_addr +=2;
8348 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
8349 map_addr +=2;
8350 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
8351 map_addr +=2;
8352 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
8353 map_addr +=2;
8354 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
8355 map_addr +=2;
8356 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
8357 map_addr +=2;
8358 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
8359 map_addr +=2;
8360 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
8361 map_addr +=2;
8362 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
8363 map_addr +=2;
8364 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
8365 map_addr +=2; /*This means AYNC DATA IN */
8366 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
8367 map_addr +=2;
8368 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
8369 map_addr +=2;
8370 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
8371 map_addr +=2;
8372 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
8373 map_addr +=2;
8374 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
8375 map_addr +=2;
8376 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
8377 map_addr +=2;
8378 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
8379 map_addr +=2;
8380 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
8381 map_addr +=2;
8382 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
8383 map_addr +=2;
8384 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
8385 map_addr +=2;
8386 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
8387 map_addr +=2;
8388 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
8389 map_addr +=2;
8390 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
8391 map_addr +=2;
8392 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
8393 map_addr +=2;
8394 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
8395 map_addr +=2;
8396 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
8397 map_addr +=2;
8398 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
8399 map_addr +=2;
8400 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
8401 map_addr +=2;
8403 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
8404 map_addr +=2;
8405 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
8406 map_addr +=2;
8407 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
8408 map_addr +=2;
8409 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
8410 map_addr +=2; /* DIDN'T GET ONE */
8411 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
8412 map_addr +=2;
8413 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
8414 map_addr +=2;
8415 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
8419 SGRAM_ACCESS(p_port);
8422 /*---------------------------------------------------------------------
8424 * Function: Auto Command Complete
8426 * Description: Post command back to host and find another command
8427 * to execute.
8429 *---------------------------------------------------------------------*/
8431 #if defined(DOS)
8432 void autoCmdCmplt(USHORT p_port, UCHAR p_card)
8433 #else
8434 void autoCmdCmplt(ULONG p_port, UCHAR p_card)
8435 #endif
8437 PSCCB currSCCB;
8438 UCHAR status_byte;
8440 currSCCB = BL_Card[p_card].currentSCCB;
8442 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
8444 sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = FALSE;
8446 if (status_byte != SSGOOD) {
8448 if (status_byte == SSQ_FULL) {
8451 if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8452 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
8454 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
8455 if(BL_Card[p_card].discQCount != 0)
8456 BL_Card[p_card].discQCount--;
8457 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
8459 else
8461 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
8462 if(currSCCB->Sccb_tag)
8464 if(BL_Card[p_card].discQCount != 0)
8465 BL_Card[p_card].discQCount--;
8466 BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
8467 }else
8469 if(BL_Card[p_card].discQCount != 0)
8470 BL_Card[p_card].discQCount--;
8471 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
8475 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
8477 queueSelectFail(&BL_Card[p_card],p_card);
8479 return;
8482 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
8484 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
8485 (UCHAR)SYNC_SUPPORTED;
8487 sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
8488 BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
8490 if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8491 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
8493 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
8494 if(BL_Card[p_card].discQCount != 0)
8495 BL_Card[p_card].discQCount--;
8496 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
8498 else
8500 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
8501 if(currSCCB->Sccb_tag)
8503 if(BL_Card[p_card].discQCount != 0)
8504 BL_Card[p_card].discQCount--;
8505 BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
8506 }else
8508 if(BL_Card[p_card].discQCount != 0)
8509 BL_Card[p_card].discQCount--;
8510 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
8513 return;
8517 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
8520 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
8521 (sccbMgrTbl[p_card][currSCCB->TargID].
8522 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
8524 sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
8525 BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
8527 if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8528 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
8530 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
8531 if(BL_Card[p_card].discQCount != 0)
8532 BL_Card[p_card].discQCount--;
8533 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
8535 else
8537 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
8538 if(currSCCB->Sccb_tag)
8540 if(BL_Card[p_card].discQCount != 0)
8541 BL_Card[p_card].discQCount--;
8542 BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
8543 }else
8545 if(BL_Card[p_card].discQCount != 0)
8546 BL_Card[p_card].discQCount--;
8547 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
8550 return;
8554 if (status_byte == SSCHECK)
8556 if(BL_Card[p_card].globalFlags & F_DO_RENEGO)
8558 if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
8560 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
8562 if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
8564 sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
8569 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
8571 currSCCB->SccbStatus = SCCB_ERROR;
8572 currSCCB->TargetStatus = status_byte;
8574 if (status_byte == SSCHECK) {
8576 sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
8577 = TRUE;
8580 #if (FW_TYPE==_SCCB_MGR_)
8581 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
8583 if (currSCCB->RequestSenseLength == 0)
8584 currSCCB->RequestSenseLength = 14;
8586 ssenss(&BL_Card[p_card]);
8587 BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
8589 if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8590 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
8592 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
8593 if(BL_Card[p_card].discQCount != 0)
8594 BL_Card[p_card].discQCount--;
8595 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
8597 else
8599 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
8600 if(currSCCB->Sccb_tag)
8602 if(BL_Card[p_card].discQCount != 0)
8603 BL_Card[p_card].discQCount--;
8604 BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
8605 }else
8607 if(BL_Card[p_card].discQCount != 0)
8608 BL_Card[p_card].discQCount--;
8609 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
8612 return;
8614 #else
8615 if ((!(currSCCB->Sccb_ucb_ptr->UCB_opcode & OPC_NO_AUTO_SENSE)) &&
8616 (currSCCB->RequestSenseLength))
8618 ssenss(&BL_Card[p_card]);
8619 BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
8621 if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8622 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
8624 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
8625 if(BL_Card[p_card].discQCount != 0)
8626 BL_Card[p_card].discQCount--;
8627 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
8629 else
8631 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
8632 if(currSCCB->Sccb_tag)
8634 if(BL_Card[p_card].discQCount != 0)
8635 BL_Card[p_card].discQCount--;
8636 BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
8637 }else
8639 if(BL_Card[p_card].discQCount != 0)
8640 BL_Card[p_card].discQCount--;
8641 BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
8644 return;
8647 #endif
8653 if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
8654 ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
8655 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
8656 else
8657 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
8660 queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
8662 #ident "$Id: busmstr.c 1.8 1997/01/31 02:10:27 mohan Exp $"
8663 /*----------------------------------------------------------------------
8666 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
8668 * This file is available under both the GNU General Public License
8669 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
8671 * $Workfile: busmstr.c $
8673 * Description: Functions to start, stop, and abort BusMaster operations.
8675 * $Date: 1997/01/31 02:10:27 $
8677 * $Revision: 1.8 $
8679 *----------------------------------------------------------------------*/
8681 /*#include <globals.h>*/
8683 #if (FW_TYPE==_UCB_MGR_)
8684 /*#include <budi.h>*/
8685 #endif
8687 /*#include <sccbmgr.h>*/
8688 /*#include <blx30.h>*/
8689 /*#include <target.h>*/
8690 /*#include <scsi2.h>*/
8691 /*#include <harpoon.h>*/
8695 extern SCCBCARD BL_Card[MAX_CARDS];
8696 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
8699 #define SHORT_WAIT 0x0000000F
8700 #define LONG_WAIT 0x0000FFFFL
8702 #if defined(BUGBUG)
8703 void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
8704 #endif
8706 /*---------------------------------------------------------------------
8708 * Function: Data Transfer Processor
8710 * Description: This routine performs two tasks.
8711 * (1) Start data transfer by calling HOST_DATA_XFER_START
8712 * function. Once data transfer is started, (2) Depends
8713 * on the type of data transfer mode Scatter/Gather mode
8714 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
8715 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
8716 * data transfer done. In Scatter/Gather mode, this routine
8717 * checks bus master command complete and dual rank busy
8718 * bit to keep chaining SC transfer command. Similarly,
8719 * in Scatter/Gather mode, it checks Sccb_MGRFlag
8720 * (F_HOST_XFER_ACT bit) for data transfer done.
8722 *---------------------------------------------------------------------*/
8724 #if defined(DOS)
8725 void dataXferProcessor(USHORT port, PSCCBcard pCurrCard)
8726 #else
8727 void dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
8728 #endif
8730 PSCCB currSCCB;
8732 currSCCB = pCurrCard->currentSCCB;
8734 if (currSCCB->Sccb_XferState & F_SG_XFER)
8736 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
8739 currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
8740 currSCCB->Sccb_SGoffset = 0x00;
8742 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
8744 busMstrSGDataXferStart(port, currSCCB);
8747 else
8749 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
8751 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
8753 busMstrDataXferStart(port, currSCCB);
8759 /*---------------------------------------------------------------------
8761 * Function: BusMaster Scatter Gather Data Transfer Start
8763 * Description:
8765 *---------------------------------------------------------------------*/
8766 #if defined(DOS)
8767 void busMstrSGDataXferStart(USHORT p_port, PSCCB pcurrSCCB)
8768 #else
8769 void busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
8770 #endif
8772 ULONG count,addr,tmpSGCnt;
8773 UINT sg_index;
8774 UCHAR sg_count, i;
8775 #if defined(DOS)
8776 USHORT reg_offset;
8777 #else
8778 ULONG reg_offset;
8779 #endif
8782 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
8784 count = ((ULONG) HOST_RD_CMD)<<24;
8787 else {
8788 count = ((ULONG) HOST_WRT_CMD)<<24;
8791 sg_count = 0;
8792 tmpSGCnt = 0;
8793 sg_index = pcurrSCCB->Sccb_sgseg;
8794 reg_offset = hp_aramBase;
8797 i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
8800 WR_HARPOON(p_port+hp_page_ctrl, i);
8802 while ((sg_count < (UCHAR)SG_BUF_CNT) &&
8803 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
8805 #if defined(COMPILER_16_BIT) && !defined(DOS)
8806 tmpSGCnt += *(((ULONG far *)pcurrSCCB->DataPointer)+
8807 (sg_index * 2));
8809 count |= *(((ULONG far *)pcurrSCCB->DataPointer)+
8810 (sg_index * 2));
8812 addr = *(((ULONG far *)pcurrSCCB->DataPointer)+
8813 ((sg_index * 2) + 1));
8815 #else
8816 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
8817 (sg_index * 2));
8819 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
8820 (sg_index * 2));
8822 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
8823 ((sg_index * 2) + 1));
8824 #endif
8827 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
8829 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
8830 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
8832 tmpSGCnt = count & 0x00FFFFFFL;
8835 WR_HARP32(p_port,reg_offset,addr);
8836 reg_offset +=4;
8838 WR_HARP32(p_port,reg_offset,count);
8839 reg_offset +=4;
8841 count &= 0xFF000000L;
8842 sg_index++;
8843 sg_count++;
8845 } /*End While */
8847 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
8849 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
8851 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
8853 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
8856 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
8857 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
8860 else {
8863 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
8864 (tmpSGCnt & 0x000000001))
8867 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
8868 tmpSGCnt--;
8872 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
8874 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
8875 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
8879 WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
8884 /*---------------------------------------------------------------------
8886 * Function: BusMaster Data Transfer Start
8888 * Description:
8890 *---------------------------------------------------------------------*/
8891 #if defined(DOS)
8892 void busMstrDataXferStart(USHORT p_port, PSCCB pcurrSCCB)
8893 #else
8894 void busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
8895 #endif
8897 ULONG addr,count;
8899 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
8901 count = pcurrSCCB->Sccb_XferCnt;
8903 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
8906 else {
8907 addr = pcurrSCCB->SensePointer;
8908 count = pcurrSCCB->RequestSenseLength;
8912 #if defined(DOS)
8913 asm { mov dx,p_port;
8914 mov ax,word ptr count;
8915 add dx,hp_xfer_cnt_lo;
8916 out dx,al;
8917 inc dx;
8918 xchg ah,al
8919 out dx,al;
8920 inc dx;
8921 mov ax,word ptr count+2;
8922 out dx,al;
8923 inc dx;
8924 inc dx;
8925 mov ax,word ptr addr;
8926 out dx,al;
8927 inc dx;
8928 xchg ah,al
8929 out dx,al;
8930 inc dx;
8931 mov ax,word ptr addr+2;
8932 out dx,al;
8933 inc dx;
8934 xchg ah,al
8935 out dx,al;
8938 WR_HARP32(p_port,hp_xfercnt_0,count);
8940 #else
8941 HP_SETUP_ADDR_CNT(p_port,addr,count);
8942 #endif
8945 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
8947 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
8948 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
8950 WR_HARPOON(p_port+hp_xfer_cmd,
8951 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
8954 else {
8956 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
8957 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
8959 WR_HARPOON(p_port+hp_xfer_cmd,
8960 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
8966 /*---------------------------------------------------------------------
8968 * Function: BusMaster Timeout Handler
8970 * Description: This function is called after a bus master command busy time
8971 * out is detected. This routines issue halt state machine
8972 * with a software time out for command busy. If command busy
8973 * is still asserted at the end of the time out, it issues
8974 * hard abort with another software time out. It hard abort
8975 * command busy is also time out, it'll just give up.
8977 *---------------------------------------------------------------------*/
8978 #if defined(DOS)
8979 UCHAR busMstrTimeOut(USHORT p_port)
8980 #else
8981 UCHAR busMstrTimeOut(ULONG p_port)
8982 #endif
8984 ULONG timeout;
8986 timeout = LONG_WAIT;
8988 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
8990 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
8994 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
8995 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
8997 timeout = LONG_WAIT;
8998 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
9001 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
9003 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
9004 return(TRUE);
9007 else {
9008 return(FALSE);
9013 /*---------------------------------------------------------------------
9015 * Function: Host Data Transfer Abort
9017 * Description: Abort any in progress transfer.
9019 *---------------------------------------------------------------------*/
9020 #if defined(DOS)
9021 void hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB)
9022 #else
9023 void hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
9024 #endif
9027 ULONG timeout;
9028 ULONG remain_cnt;
9029 UINT sg_ptr;
9031 BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
9033 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
9036 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
9038 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
9039 timeout = LONG_WAIT;
9041 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
9043 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
9045 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
9047 if (busMstrTimeOut(port)) {
9049 if (pCurrSCCB->HostStatus == 0x00)
9051 pCurrSCCB->HostStatus = SCCB_BM_ERR;
9055 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
9057 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
9059 if (pCurrSCCB->HostStatus == 0x00)
9062 pCurrSCCB->HostStatus = SCCB_BM_ERR;
9063 #if defined(BUGBUG)
9064 WR_HARPOON(port+hp_dual_addr_lo,
9065 RD_HARPOON(port+hp_ext_status));
9066 #endif
9072 else if (pCurrSCCB->Sccb_XferCnt) {
9074 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
9077 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
9078 ~SCATTER_EN));
9080 WR_HARPOON(port+hp_sg_addr,0x00);
9082 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
9084 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
9086 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
9089 remain_cnt = pCurrSCCB->Sccb_XferCnt;
9091 while (remain_cnt < 0x01000000L) {
9093 sg_ptr--;
9095 #if defined(COMPILER_16_BIT) && !defined(DOS)
9096 if (remain_cnt > (ULONG)(*(((ULONG far *)pCurrSCCB->
9097 DataPointer) + (sg_ptr * 2)))) {
9099 remain_cnt -= (ULONG)(*(((ULONG far *)pCurrSCCB->
9100 DataPointer) + (sg_ptr * 2)));
9103 #else
9104 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
9105 DataPointer) + (sg_ptr * 2)))) {
9107 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
9108 DataPointer) + (sg_ptr * 2)));
9110 #endif
9112 else {
9114 break;
9120 if (remain_cnt < 0x01000000L) {
9123 pCurrSCCB->Sccb_SGoffset = remain_cnt;
9125 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
9128 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
9129 && (remain_cnt == 0))
9131 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
9134 else {
9137 if (pCurrSCCB->HostStatus == 0x00) {
9139 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
9145 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
9148 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
9150 busMstrTimeOut(port);
9153 else {
9155 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
9157 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
9159 if (pCurrSCCB->HostStatus == 0x00) {
9161 pCurrSCCB->HostStatus = SCCB_BM_ERR;
9162 #if defined(BUGBUG)
9163 WR_HARPOON(port+hp_dual_addr_lo,
9164 RD_HARPOON(port+hp_ext_status));
9165 #endif
9173 else {
9176 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
9178 timeout = SHORT_WAIT;
9180 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
9181 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
9182 timeout--) {}
9185 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
9187 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
9188 FLUSH_XFER_CNTR));
9190 timeout = LONG_WAIT;
9192 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
9193 timeout--) {}
9195 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
9196 ~FLUSH_XFER_CNTR));
9199 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
9201 if (pCurrSCCB->HostStatus == 0x00) {
9203 pCurrSCCB->HostStatus = SCCB_BM_ERR;
9206 busMstrTimeOut(port);
9210 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
9212 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
9214 if (pCurrSCCB->HostStatus == 0x00) {
9216 pCurrSCCB->HostStatus = SCCB_BM_ERR;
9217 #if defined(BUGBUG)
9218 WR_HARPOON(port+hp_dual_addr_lo,
9219 RD_HARPOON(port+hp_ext_status));
9220 #endif
9228 else {
9231 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
9233 timeout = LONG_WAIT;
9235 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
9237 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
9239 if (pCurrSCCB->HostStatus == 0x00) {
9241 pCurrSCCB->HostStatus = SCCB_BM_ERR;
9244 busMstrTimeOut(port);
9249 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
9251 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
9253 if (pCurrSCCB->HostStatus == 0x00) {
9255 pCurrSCCB->HostStatus = SCCB_BM_ERR;
9256 #if defined(BUGBUG)
9257 WR_HARPOON(port+hp_dual_addr_lo,
9258 RD_HARPOON(port+hp_ext_status));
9259 #endif
9265 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
9267 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
9268 ~SCATTER_EN));
9270 WR_HARPOON(port+hp_sg_addr,0x00);
9272 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
9274 pCurrSCCB->Sccb_SGoffset = 0x00;
9277 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
9278 pCurrSCCB->DataLength) {
9280 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
9282 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
9287 else {
9289 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
9291 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
9295 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
9300 /*---------------------------------------------------------------------
9302 * Function: Host Data Transfer Restart
9304 * Description: Reset the available count due to a restore data
9305 * pointers message.
9307 *---------------------------------------------------------------------*/
9308 void hostDataXferRestart(PSCCB currSCCB)
9310 ULONG data_count;
9311 UINT sg_index;
9312 #if defined(COMPILER_16_BIT) && !defined(DOS)
9313 ULONG far *sg_ptr;
9314 #else
9315 ULONG *sg_ptr;
9316 #endif
9318 if (currSCCB->Sccb_XferState & F_SG_XFER) {
9320 currSCCB->Sccb_XferCnt = 0;
9322 sg_index = 0xffff; /*Index by long words into sg list. */
9323 data_count = 0; /*Running count of SG xfer counts. */
9325 #if defined(COMPILER_16_BIT) && !defined(DOS)
9326 sg_ptr = (ULONG far *)currSCCB->DataPointer;
9327 #else
9328 sg_ptr = (ULONG *)currSCCB->DataPointer;
9329 #endif
9331 while (data_count < currSCCB->Sccb_ATC) {
9333 sg_index++;
9334 data_count += *(sg_ptr+(sg_index * 2));
9337 if (data_count == currSCCB->Sccb_ATC) {
9339 currSCCB->Sccb_SGoffset = 0;
9340 sg_index++;
9343 else {
9344 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
9347 currSCCB->Sccb_sgseg = (USHORT)sg_index;
9350 else {
9351 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
9354 #ident "$Id: scam.c 1.17 1997/03/20 23:49:37 mohan Exp $"
9355 /*----------------------------------------------------------------------
9358 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
9360 * This file is available under both the GNU General Public License
9361 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
9363 * $Workfile: scam.c $
9365 * Description: Functions relating to handling of the SCAM selection
9366 * and the determination of the SCSI IDs to be assigned
9367 * to all perspective SCSI targets.
9369 * $Date: 1997/03/20 23:49:37 $
9371 * $Revision: 1.17 $
9373 *----------------------------------------------------------------------*/
9375 /*#include <globals.h>*/
9377 #if (FW_TYPE==_UCB_MGR_)
9378 /*#include <budi.h>*/
9379 #endif
9381 /*#include <sccbmgr.h>*/
9382 /*#include <blx30.h>*/
9383 /*#include <target.h>*/
9384 /*#include <scsi2.h>*/
9385 /*#include <eeprom.h>*/
9386 /*#include <harpoon.h>*/
9391 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
9392 extern SCCBCARD BL_Card[MAX_CARDS];
9393 extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR];
9394 extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
9395 #if defined(DOS) || defined(OS2)
9396 extern UCHAR temp_id_string[ID_STRING_LENGTH];
9397 #endif
9398 extern UCHAR scamHAString[];
9400 /*---------------------------------------------------------------------
9402 * Function: scini
9404 * Description: Setup all data structures necessary for SCAM selection.
9406 *---------------------------------------------------------------------*/
9408 void scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
9411 #if defined(SCAM_LEV_2)
9412 UCHAR loser,assigned_id;
9413 #endif
9414 #if defined(DOS)
9416 USHORT p_port;
9417 #else
9418 ULONG p_port;
9419 #endif
9421 UCHAR i,k,ScamFlg ;
9422 PSCCBcard currCard;
9423 PNVRamInfo pCurrNvRam;
9425 currCard = &BL_Card[p_card];
9426 p_port = currCard->ioPort;
9427 pCurrNvRam = currCard->pNvRamInfo;
9430 if(pCurrNvRam){
9431 ScamFlg = pCurrNvRam->niScamConf;
9432 i = pCurrNvRam->niSysConf;
9434 else{
9435 ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2);
9436 i = (UCHAR)(utilEERead(p_port, (SYSTEM_CONFIG/2)));
9438 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
9439 return;
9441 inisci(p_card,p_port, p_our_id);
9443 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
9444 too slow to return to SCAM selection */
9446 /* if (p_power_up)
9447 Wait1Second(p_port);
9448 else
9449 Wait(p_port, TO_250ms); */
9451 Wait1Second(p_port);
9453 #if defined(SCAM_LEV_2)
9455 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
9457 while (!(scarb(p_port,INIT_SELTD))) {}
9459 scsel(p_port);
9461 do {
9462 scxferc(p_port,SYNC_PTRN);
9463 scxferc(p_port,DOM_MSTR);
9464 loser = scsendi(p_port,&scamInfo[p_our_id].id_string[0]);
9465 } while ( loser == 0xFF );
9467 scbusf(p_port);
9469 if ((p_power_up) && (!loser))
9471 sresb(p_port,p_card);
9472 Wait(p_port, TO_250ms);
9474 while (!(scarb(p_port,INIT_SELTD))) {}
9476 scsel(p_port);
9478 do {
9479 scxferc(p_port, SYNC_PTRN);
9480 scxferc(p_port, DOM_MSTR);
9481 loser = scsendi(p_port,&scamInfo[p_our_id].
9482 id_string[0]);
9483 } while ( loser == 0xFF );
9485 scbusf(p_port);
9489 else
9491 loser = FALSE;
9495 if (!loser)
9498 #endif /* SCAM_LEV_2 */
9500 scamInfo[p_our_id].state = ID_ASSIGNED;
9503 if (ScamFlg & SCAM_ENABLED)
9506 for (i=0; i < MAX_SCSI_TAR; i++)
9508 if ((scamInfo[i].state == ID_UNASSIGNED) ||
9509 (scamInfo[i].state == ID_UNUSED))
9511 if (scsell(p_port,i))
9513 scamInfo[i].state = LEGACY;
9514 if ((scamInfo[i].id_string[0] != 0xFF) ||
9515 (scamInfo[i].id_string[1] != 0xFA))
9518 scamInfo[i].id_string[0] = 0xFF;
9519 scamInfo[i].id_string[1] = 0xFA;
9520 if(pCurrNvRam == NULL)
9521 currCard->globalFlags |= F_UPDATE_EEPROM;
9527 sresb(p_port,p_card);
9528 Wait1Second(p_port);
9529 while (!(scarb(p_port,INIT_SELTD))) {}
9530 scsel(p_port);
9531 scasid(p_card, p_port);
9534 #if defined(SCAM_LEV_2)
9538 else if ((loser) && (ScamFlg & SCAM_ENABLED))
9540 scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
9541 assigned_id = FALSE;
9542 scwtsel(p_port);
9544 do {
9545 while (scxferc(p_port,0x00) != SYNC_PTRN) {}
9547 i = scxferc(p_port,0x00);
9548 if (i == ASSIGN_ID)
9550 if (!(scsendi(p_port,&scamInfo[p_our_id].id_string[0])))
9552 i = scxferc(p_port,0x00);
9553 if (scvalq(i))
9555 k = scxferc(p_port,0x00);
9557 if (scvalq(k))
9559 currCard->ourId =
9560 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
9561 inisci(p_card, p_port, p_our_id);
9562 scamInfo[currCard->ourId].state = ID_ASSIGNED;
9563 scamInfo[currCard->ourId].id_string[0]
9564 = SLV_TYPE_CODE0;
9565 assigned_id = TRUE;
9571 else if (i == SET_P_FLAG)
9573 if (!(scsendi(p_port,
9574 &scamInfo[p_our_id].id_string[0])))
9575 scamInfo[p_our_id].id_string[0] |= 0x80;
9577 }while (!assigned_id);
9579 while (scxferc(p_port,0x00) != CFG_CMPLT) {}
9582 #endif /* SCAM_LEV_2 */
9583 if (ScamFlg & SCAM_ENABLED)
9585 scbusf(p_port);
9586 if (currCard->globalFlags & F_UPDATE_EEPROM)
9588 scsavdi(p_card, p_port);
9589 currCard->globalFlags &= ~F_UPDATE_EEPROM;
9594 #if defined(DOS)
9595 for (i=0; i < MAX_SCSI_TAR; i++)
9597 if (((ScamFlg & SCAM_ENABLED) && (scamInfo[i].state == LEGACY))
9598 || (i != p_our_id))
9600 scsellDOS(p_port,i);
9603 #endif
9606 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
9608 if ((scamInfo[i].state == ID_ASSIGNED) ||
9609 (scamInfo[i].state == LEGACY))
9610 k++;
9613 if (k==2)
9614 currCard->globalFlags |= F_SINGLE_DEVICE;
9615 else
9616 currCard->globalFlags &= ~F_SINGLE_DEVICE;
9621 /*---------------------------------------------------------------------
9623 * Function: scarb
9625 * Description: Gain control of the bus and wait SCAM select time (250ms)
9627 *---------------------------------------------------------------------*/
9629 #if defined(DOS)
9630 int scarb(USHORT p_port, UCHAR p_sel_type)
9631 #else
9632 int scarb(ULONG p_port, UCHAR p_sel_type)
9633 #endif
9635 if (p_sel_type == INIT_SELTD)
9638 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
9641 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
9642 return(FALSE);
9644 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
9645 return(FALSE);
9647 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
9649 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
9651 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
9652 ~SCSI_BSY));
9653 return(FALSE);
9657 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
9659 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
9661 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
9662 ~(SCSI_BSY | SCSI_SEL)));
9663 return(FALSE);
9668 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
9669 & ~ACTdeassert));
9670 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
9671 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
9672 #if defined(WIDE_SCSI)
9673 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
9674 #endif
9675 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
9677 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
9679 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
9680 & ~SCSI_BSY));
9682 Wait(p_port,TO_250ms);
9684 return(TRUE);
9688 /*---------------------------------------------------------------------
9690 * Function: scbusf
9692 * Description: Release the SCSI bus and disable SCAM selection.
9694 *---------------------------------------------------------------------*/
9696 #if defined(DOS)
9697 void scbusf(USHORT p_port)
9698 #else
9699 void scbusf(ULONG p_port)
9700 #endif
9702 WR_HARPOON(p_port+hp_page_ctrl,
9703 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
9706 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
9708 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
9709 & ~SCSI_BUS_EN));
9711 WR_HARPOON(p_port+hp_scsisig, 0x00);
9714 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
9715 & ~SCAM_EN));
9717 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
9718 | ACTdeassert));
9720 #if defined(SCAM_LEV_2)
9721 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
9722 #else
9723 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT));
9724 #endif
9726 WR_HARPOON(p_port+hp_page_ctrl,
9727 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
9732 /*---------------------------------------------------------------------
9734 * Function: scasid
9736 * Description: Assign an ID to all the SCAM devices.
9738 *---------------------------------------------------------------------*/
9740 #if defined(DOS)
9741 void scasid(UCHAR p_card, USHORT p_port)
9742 #else
9743 void scasid(UCHAR p_card, ULONG p_port)
9744 #endif
9746 #if defined(DOS) || defined(OS2)
9747 /* Use external defined in global space area, instead of Stack
9748 space. WIN/95 DOS doesnot work TINY mode. The OS doesnot intialize
9749 SS equal to DS. Thus the array allocated on stack doesnot get
9750 access correctly */
9751 #else
9752 UCHAR temp_id_string[ID_STRING_LENGTH];
9753 #endif
9755 UCHAR i,k,scam_id;
9756 UCHAR crcBytes[3];
9757 PNVRamInfo pCurrNvRam;
9758 ushort_ptr pCrcBytes;
9760 pCurrNvRam = BL_Card[p_card].pNvRamInfo;
9762 i=FALSE;
9764 while (!i)
9767 for (k=0; k < ID_STRING_LENGTH; k++)
9769 temp_id_string[k] = (UCHAR) 0x00;
9772 scxferc(p_port,SYNC_PTRN);
9773 scxferc(p_port,ASSIGN_ID);
9775 if (!(sciso(p_port,&temp_id_string[0])))
9777 if(pCurrNvRam){
9778 pCrcBytes = (ushort_ptr)&crcBytes[0];
9779 *pCrcBytes = CalcCrc16(&temp_id_string[0]);
9780 crcBytes[2] = CalcLrc(&temp_id_string[0]);
9781 temp_id_string[1] = crcBytes[2];
9782 temp_id_string[2] = crcBytes[0];
9783 temp_id_string[3] = crcBytes[1];
9784 for(k = 4; k < ID_STRING_LENGTH; k++)
9785 temp_id_string[k] = (UCHAR) 0x00;
9787 i = scmachid(p_card,temp_id_string);
9789 if (i == CLR_PRIORITY)
9791 scxferc(p_port,MISC_CODE);
9792 scxferc(p_port,CLR_P_FLAG);
9793 i = FALSE; /*Not the last ID yet. */
9796 else if (i != NO_ID_AVAIL)
9798 if (i < 8 )
9799 scxferc(p_port,ID_0_7);
9800 else
9801 scxferc(p_port,ID_8_F);
9803 scam_id = (i & (UCHAR) 0x07);
9806 for (k=1; k < 0x08; k <<= 1)
9807 if (!( k & i ))
9808 scam_id += 0x08; /*Count number of zeros in DB0-3. */
9810 scxferc(p_port,scam_id);
9812 i = FALSE; /*Not the last ID yet. */
9816 else
9818 i = TRUE;
9821 } /*End while */
9823 scxferc(p_port,SYNC_PTRN);
9824 scxferc(p_port,CFG_CMPLT);
9831 /*---------------------------------------------------------------------
9833 * Function: scsel
9835 * Description: Select all the SCAM devices.
9837 *---------------------------------------------------------------------*/
9839 #if defined(DOS)
9840 void scsel(USHORT p_port)
9841 #else
9842 void scsel(ULONG p_port)
9843 #endif
9846 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
9847 scwiros(p_port, SCSI_MSG);
9849 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
9852 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
9853 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
9854 (UCHAR)(BIT(7)+BIT(6))));
9857 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
9858 scwiros(p_port, SCSI_SEL);
9860 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
9861 ~(UCHAR)BIT(6)));
9862 scwirod(p_port, BIT(6));
9864 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
9869 /*---------------------------------------------------------------------
9871 * Function: scxferc
9873 * Description: Handshake the p_data (DB4-0) across the bus.
9875 *---------------------------------------------------------------------*/
9877 #if defined(DOS)
9878 UCHAR scxferc(USHORT p_port, UCHAR p_data)
9879 #else
9880 UCHAR scxferc(ULONG p_port, UCHAR p_data)
9881 #endif
9883 UCHAR curr_data, ret_data;
9885 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
9887 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
9889 curr_data &= ~BIT(7);
9891 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
9893 scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
9894 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
9896 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
9898 curr_data |= BIT(6);
9900 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
9902 curr_data &= ~BIT(5);
9904 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
9906 scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
9908 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
9909 curr_data |= BIT(7);
9911 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
9913 curr_data &= ~BIT(6);
9915 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
9917 scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
9919 return(ret_data);
9923 /*---------------------------------------------------------------------
9925 * Function: scsendi
9927 * Description: Transfer our Identification string to determine if we
9928 * will be the dominant master.
9930 *---------------------------------------------------------------------*/
9932 #if defined(DOS)
9933 UCHAR scsendi(USHORT p_port, UCHAR p_id_string[])
9934 #else
9935 UCHAR scsendi(ULONG p_port, UCHAR p_id_string[])
9936 #endif
9938 UCHAR ret_data,byte_cnt,bit_cnt,defer;
9940 defer = FALSE;
9942 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
9944 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
9946 if (defer)
9947 ret_data = scxferc(p_port,00);
9949 else if (p_id_string[byte_cnt] & bit_cnt)
9951 ret_data = scxferc(p_port,02);
9953 else {
9955 ret_data = scxferc(p_port,01);
9956 if (ret_data & 02)
9957 defer = TRUE;
9960 if ((ret_data & 0x1C) == 0x10)
9961 return(0x00); /*End of isolation stage, we won! */
9963 if (ret_data & 0x1C)
9964 return(0xFF);
9966 if ((defer) && (!(ret_data & 0x1F)))
9967 return(0x01); /*End of isolation stage, we lost. */
9969 } /*bit loop */
9971 } /*byte loop */
9973 if (defer)
9974 return(0x01); /*We lost */
9975 else
9976 return(0); /*We WON! Yeeessss! */
9981 /*---------------------------------------------------------------------
9983 * Function: sciso
9985 * Description: Transfer the Identification string.
9987 *---------------------------------------------------------------------*/
9989 #if defined(DOS)
9990 UCHAR sciso(USHORT p_port, UCHAR p_id_string[])
9991 #else
9992 UCHAR sciso(ULONG p_port, UCHAR p_id_string[])
9993 #endif
9995 UCHAR ret_data,the_data,byte_cnt,bit_cnt;
9997 the_data = 0;
9999 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
10001 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
10003 ret_data = scxferc(p_port,0);
10005 if (ret_data & 0xFC)
10006 return(0xFF);
10008 else {
10010 the_data <<= 1;
10011 if (ret_data & BIT(1)) {
10012 the_data |= 1;
10016 if ((ret_data & 0x1F) == 0)
10019 if(bit_cnt != 0 || bit_cnt != 8)
10021 byte_cnt = 0;
10022 bit_cnt = 0;
10023 scxferc(p_port, SYNC_PTRN);
10024 scxferc(p_port, ASSIGN_ID);
10025 continue;
10028 if (byte_cnt)
10029 return(0x00);
10030 else
10031 return(0xFF);
10034 } /*bit loop */
10036 p_id_string[byte_cnt] = the_data;
10038 } /*byte loop */
10040 return(0);
10045 /*---------------------------------------------------------------------
10047 * Function: scwirod
10049 * Description: Sample the SCSI data bus making sure the signal has been
10050 * deasserted for the correct number of consecutive samples.
10052 *---------------------------------------------------------------------*/
10054 #if defined(DOS)
10055 void scwirod(USHORT p_port, UCHAR p_data_bit)
10056 #else
10057 void scwirod(ULONG p_port, UCHAR p_data_bit)
10058 #endif
10060 UCHAR i;
10062 i = 0;
10063 while ( i < MAX_SCSI_TAR ) {
10065 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
10067 i = 0;
10069 else
10071 i++;
10078 /*---------------------------------------------------------------------
10080 * Function: scwiros
10082 * Description: Sample the SCSI Signal lines making sure the signal has been
10083 * deasserted for the correct number of consecutive samples.
10085 *---------------------------------------------------------------------*/
10087 #if defined(DOS)
10088 void scwiros(USHORT p_port, UCHAR p_data_bit)
10089 #else
10090 void scwiros(ULONG p_port, UCHAR p_data_bit)
10091 #endif
10093 UCHAR i;
10095 i = 0;
10096 while ( i < MAX_SCSI_TAR ) {
10098 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
10100 i = 0;
10102 else
10104 i++;
10110 /*---------------------------------------------------------------------
10112 * Function: scvalq
10114 * Description: Make sure we received a valid data byte.
10116 *---------------------------------------------------------------------*/
10118 UCHAR scvalq(UCHAR p_quintet)
10120 UCHAR count;
10122 for (count=1; count < 0x08; count<<=1) {
10123 if (!(p_quintet & count))
10124 p_quintet -= 0x80;
10127 if (p_quintet & 0x18)
10128 return(FALSE);
10130 else
10131 return(TRUE);
10135 /*---------------------------------------------------------------------
10137 * Function: scsell
10139 * Description: Select the specified device ID using a selection timeout
10140 * less than 4ms. If somebody responds then it is a legacy
10141 * drive and this ID must be marked as such.
10143 *---------------------------------------------------------------------*/
10145 #if defined(DOS)
10146 UCHAR scsell(USHORT p_port, UCHAR targ_id)
10147 #else
10148 UCHAR scsell(ULONG p_port, UCHAR targ_id)
10149 #endif
10151 #if defined(DOS)
10152 USHORT i;
10153 #else
10154 ULONG i;
10155 #endif
10157 WR_HARPOON(p_port+hp_page_ctrl,
10158 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
10160 ARAM_ACCESS(p_port);
10162 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
10163 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
10166 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
10167 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
10169 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
10171 WRW_HARPOON((p_port+hp_intstat),
10172 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
10174 WR_HARPOON(p_port+hp_select_id, targ_id);
10176 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
10177 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
10178 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
10181 while (!(RDW_HARPOON((p_port+hp_intstat)) &
10182 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
10184 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
10185 Wait(p_port, TO_250ms);
10187 DISABLE_AUTO(p_port);
10189 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
10190 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
10192 SGRAM_ACCESS(p_port);
10194 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
10196 WRW_HARPOON((p_port+hp_intstat),
10197 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
10199 WR_HARPOON(p_port+hp_page_ctrl,
10200 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
10202 return(FALSE); /*No legacy device */
10205 else {
10207 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
10208 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
10210 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
10211 ACCEPT_MSG(p_port);
10215 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
10217 WR_HARPOON(p_port+hp_page_ctrl,
10218 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
10220 return(TRUE); /*Found one of them oldies! */
10224 #if defined(DOS)
10225 /*---------------------------------------------------------------------
10227 * Function: scsell for DOS
10229 * Description: Select the specified device ID using a selection timeout
10230 * less than 2ms. This was specially required to solve
10231 * the problem with Plextor 12X CD-ROM drive. This drive
10232 * was responding the Selection at the end of 4ms and
10233 * hanging the system.
10235 *---------------------------------------------------------------------*/
10237 UCHAR scsellDOS(USHORT p_port, UCHAR targ_id)
10239 USHORT i;
10241 WR_HARPOON(p_port+hp_page_ctrl,
10242 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
10244 ARAM_ACCESS(p_port);
10246 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
10247 WR_HARPOON(p_port+hp_seltimeout,TO_2ms);
10250 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
10251 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
10253 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
10255 WRW_HARPOON((p_port+hp_intstat),
10256 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
10258 WR_HARPOON(p_port+hp_select_id, targ_id);
10260 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
10261 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
10262 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
10265 while (!(RDW_HARPOON((p_port+hp_intstat)) &
10266 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
10268 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
10269 Wait(p_port, TO_250ms);
10271 DISABLE_AUTO(p_port);
10273 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
10274 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
10276 SGRAM_ACCESS(p_port);
10278 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
10280 WRW_HARPOON((p_port+hp_intstat),
10281 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
10283 WR_HARPOON(p_port+hp_page_ctrl,
10284 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
10286 return(FALSE); /*No legacy device */
10289 else {
10291 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
10292 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
10294 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
10295 ACCEPT_MSG(p_port);
10299 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
10301 WR_HARPOON(p_port+hp_page_ctrl,
10302 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
10304 return(TRUE); /*Found one of them oldies! */
10307 #endif /* DOS */
10309 /*---------------------------------------------------------------------
10311 * Function: scwtsel
10313 * Description: Wait to be selected by another SCAM initiator.
10315 *---------------------------------------------------------------------*/
10317 #if defined(DOS)
10318 void scwtsel(USHORT p_port)
10319 #else
10320 void scwtsel(ULONG p_port)
10321 #endif
10323 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
10327 /*---------------------------------------------------------------------
10329 * Function: inisci
10331 * Description: Setup the data Structure with the info from the EEPROM.
10333 *---------------------------------------------------------------------*/
10335 #if defined(DOS)
10336 void inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id)
10337 #else
10338 void inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
10339 #endif
10341 UCHAR i,k,max_id;
10342 USHORT ee_data;
10343 PNVRamInfo pCurrNvRam;
10345 pCurrNvRam = BL_Card[p_card].pNvRamInfo;
10347 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
10348 max_id = 0x08;
10350 else
10351 max_id = 0x10;
10353 if(pCurrNvRam){
10354 for(i = 0; i < max_id; i++){
10356 for(k = 0; k < 4; k++)
10357 scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
10358 for(k = 4; k < ID_STRING_LENGTH; k++)
10359 scamInfo[i].id_string[k] = (UCHAR) 0x00;
10361 if(scamInfo[i].id_string[0] == 0x00)
10362 scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
10363 else
10364 scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
10367 }else {
10368 for (i=0; i < max_id; i++)
10370 for (k=0; k < ID_STRING_LENGTH; k+=2)
10372 ee_data = utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
10373 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
10374 scamInfo[i].id_string[k] = (UCHAR) ee_data;
10375 ee_data >>= 8;
10376 scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
10379 if ((scamInfo[i].id_string[0] == 0x00) ||
10380 (scamInfo[i].id_string[0] == 0xFF))
10382 scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
10384 else
10385 scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
10389 for(k = 0; k < ID_STRING_LENGTH; k++)
10390 scamInfo[p_our_id].id_string[k] = scamHAString[k];
10394 /*---------------------------------------------------------------------
10396 * Function: scmachid
10398 * Description: Match the Device ID string with our values stored in
10399 * the EEPROM.
10401 *---------------------------------------------------------------------*/
10403 UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[])
10406 UCHAR i,k,match;
10409 for (i=0; i < MAX_SCSI_TAR; i++) {
10411 #if !defined(SCAM_LEV_2)
10412 if (scamInfo[i].state == ID_UNASSIGNED)
10414 #endif
10415 match = TRUE;
10417 for (k=0; k < ID_STRING_LENGTH; k++)
10419 if (p_id_string[k] != scamInfo[i].id_string[k])
10420 match = FALSE;
10423 if (match)
10425 scamInfo[i].state = ID_ASSIGNED;
10426 return(i);
10429 #if !defined(SCAM_LEV_2)
10431 #endif
10437 if (p_id_string[0] & BIT(5))
10438 i = 8;
10439 else
10440 i = MAX_SCSI_TAR;
10442 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
10443 match = p_id_string[1] & (UCHAR) 0x1F;
10444 else
10445 match = 7;
10447 while (i > 0)
10449 i--;
10451 if (scamInfo[match].state == ID_UNUSED)
10453 for (k=0; k < ID_STRING_LENGTH; k++)
10455 scamInfo[match].id_string[k] = p_id_string[k];
10458 scamInfo[match].state = ID_ASSIGNED;
10460 if(BL_Card[p_card].pNvRamInfo == NULL)
10461 BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
10462 return(match);
10467 match--;
10469 if (match == 0xFF)
10471 if (p_id_string[0] & BIT(5))
10472 match = 7;
10473 else
10474 match = MAX_SCSI_TAR-1;
10480 if (p_id_string[0] & BIT(7))
10482 return(CLR_PRIORITY);
10486 if (p_id_string[0] & BIT(5))
10487 i = 8;
10488 else
10489 i = MAX_SCSI_TAR;
10491 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
10492 match = p_id_string[1] & (UCHAR) 0x1F;
10493 else
10494 match = 7;
10496 while (i > 0)
10499 i--;
10501 if (scamInfo[match].state == ID_UNASSIGNED)
10503 for (k=0; k < ID_STRING_LENGTH; k++)
10505 scamInfo[match].id_string[k] = p_id_string[k];
10508 scamInfo[match].id_string[0] |= BIT(7);
10509 scamInfo[match].state = ID_ASSIGNED;
10510 if(BL_Card[p_card].pNvRamInfo == NULL)
10511 BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
10512 return(match);
10517 match--;
10519 if (match == 0xFF)
10521 if (p_id_string[0] & BIT(5))
10522 match = 7;
10523 else
10524 match = MAX_SCSI_TAR-1;
10528 return(NO_ID_AVAIL);
10532 /*---------------------------------------------------------------------
10534 * Function: scsavdi
10536 * Description: Save off the device SCAM ID strings.
10538 *---------------------------------------------------------------------*/
10540 #if defined(DOS)
10541 void scsavdi(UCHAR p_card, USHORT p_port)
10542 #else
10543 void scsavdi(UCHAR p_card, ULONG p_port)
10544 #endif
10546 UCHAR i,k,max_id;
10547 USHORT ee_data,sum_data;
10550 sum_data = 0x0000;
10552 for (i = 1; i < EE_SCAMBASE/2; i++)
10554 sum_data += utilEERead(p_port, i);
10558 utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
10560 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
10561 max_id = 0x08;
10563 else
10564 max_id = 0x10;
10566 for (i=0; i < max_id; i++)
10569 for (k=0; k < ID_STRING_LENGTH; k+=2)
10571 ee_data = scamInfo[i].id_string[k+1];
10572 ee_data <<= 8;
10573 ee_data |= scamInfo[i].id_string[k];
10574 sum_data += ee_data;
10575 utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
10576 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
10581 utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
10582 utilEEWriteOnOff(p_port,0); /* Turn off write access */
10584 #ident "$Id: diagnose.c 1.10 1997/06/10 16:51:47 mohan Exp $"
10585 /*----------------------------------------------------------------------
10588 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
10590 * This file is available under both the GNU General Public License
10591 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
10593 * $Workfile: diagnose.c $
10595 * Description: Diagnostic funtions for testing the integrity of
10596 * the HARPOON.
10598 * $Date: 1997/06/10 16:51:47 $
10600 * $Revision: 1.10 $
10602 *----------------------------------------------------------------------*/
10604 /*#include <globals.h>*/
10606 #if (FW_TYPE==_UCB_MGR_)
10607 /*#include <budi.h>*/
10608 #endif
10610 /*#include <sccbmgr.h>*/
10611 /*#include <blx30.h>*/
10612 /*#include <target.h>*/
10613 /*#include <eeprom.h>*/
10614 /*#include <harpoon.h>*/
10616 /*---------------------------------------------------------------------
10618 * Function: XbowInit
10620 * Description: Setup the Xbow for normal operation.
10622 *---------------------------------------------------------------------*/
10624 #if defined(DOS)
10625 void XbowInit(USHORT port, UCHAR ScamFlg)
10626 #else
10627 void XbowInit(ULONG port, UCHAR ScamFlg)
10628 #endif
10630 UCHAR i;
10632 i = RD_HARPOON(port+hp_page_ctrl);
10633 WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
10635 WR_HARPOON(port+hp_scsireset,0x00);
10636 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
10638 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
10639 FIFO_CLR));
10641 WR_HARPOON(port+hp_scsireset,SCSI_INI);
10643 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
10645 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
10646 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
10648 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
10650 #if defined(SCAM_LEV_2)
10651 default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
10652 BUS_FREE | XFER_CNT_0 | AUTO_INT;
10654 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
10655 default_intena |= SCAM_SEL;
10657 #else
10658 default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
10659 BUS_FREE | XFER_CNT_0 | AUTO_INT;
10660 #endif
10661 WRW_HARPOON((port+hp_intena), default_intena);
10663 WR_HARPOON(port+hp_seltimeout,TO_290ms);
10665 /* Turn on SCSI_MODE8 for narrow cards to fix the
10666 strapping issue with the DUAL CHANNEL card */
10667 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
10668 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
10670 #if defined(NO_BIOS_OPTION)
10672 WR_HARPOON(port+hp_synctarg_0,NARROW_SCSI);
10673 WR_HARPOON(port+hp_synctarg_1,NARROW_SCSI);
10674 WR_HARPOON(port+hp_synctarg_2,NARROW_SCSI);
10675 WR_HARPOON(port+hp_synctarg_3,NARROW_SCSI);
10676 WR_HARPOON(port+hp_synctarg_4,NARROW_SCSI);
10677 WR_HARPOON(port+hp_synctarg_5,NARROW_SCSI);
10678 WR_HARPOON(port+hp_synctarg_6,NARROW_SCSI);
10679 WR_HARPOON(port+hp_synctarg_7,NARROW_SCSI);
10680 WR_HARPOON(port+hp_synctarg_8,NARROW_SCSI);
10681 WR_HARPOON(port+hp_synctarg_9,NARROW_SCSI);
10682 WR_HARPOON(port+hp_synctarg_10,NARROW_SCSI);
10683 WR_HARPOON(port+hp_synctarg_11,NARROW_SCSI);
10684 WR_HARPOON(port+hp_synctarg_12,NARROW_SCSI);
10685 WR_HARPOON(port+hp_synctarg_13,NARROW_SCSI);
10686 WR_HARPOON(port+hp_synctarg_14,NARROW_SCSI);
10687 WR_HARPOON(port+hp_synctarg_15,NARROW_SCSI);
10689 #endif
10690 WR_HARPOON(port+hp_page_ctrl, i);
10695 /*---------------------------------------------------------------------
10697 * Function: BusMasterInit
10699 * Description: Initialize the BusMaster for normal operations.
10701 *---------------------------------------------------------------------*/
10703 #if defined(DOS)
10704 void BusMasterInit(USHORT p_port)
10705 #else
10706 void BusMasterInit(ULONG p_port)
10707 #endif
10711 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
10712 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
10714 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
10717 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
10719 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
10722 #if defined(NT)
10724 WR_HARPOON(p_port+hp_pci_cmd_cfg, (RD_HARPOON(p_port+hp_pci_cmd_cfg)
10725 & ~MEM_SPACE_ENA));
10727 #endif
10729 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
10730 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
10731 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
10732 ~SCATTER_EN));
10736 /*---------------------------------------------------------------------
10738 * Function: DiagXbow
10740 * Description: Test Xbow integrity. Non-zero return indicates an error.
10742 *---------------------------------------------------------------------*/
10744 #if defined(DOS)
10745 int DiagXbow(USHORT port)
10746 #else
10747 int DiagXbow(ULONG port)
10748 #endif
10750 unsigned char fifo_cnt,loop_cnt;
10752 unsigned char fifodata[5];
10753 fifodata[0] = 0x00;
10754 fifodata[1] = 0xFF;
10755 fifodata[2] = 0x55;
10756 fifodata[3] = 0xAA;
10757 fifodata[4] = 0x00;
10760 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
10761 WRW_HARPOON((port+hp_intena), 0x0000);
10763 WR_HARPOON(port+hp_seltimeout,TO_5ms);
10765 WR_HARPOON(port+hp_portctrl_0,START_TO);
10768 for(fifodata[4] = 0x01; fifodata[4] != (UCHAR) 0; fifodata[4] = fifodata[4] << 1) {
10770 WR_HARPOON(port+hp_selfid_0,fifodata[4]);
10771 WR_HARPOON(port+hp_selfid_1,fifodata[4]);
10773 if ((RD_HARPOON(port+hp_selfid_0) != fifodata[4]) ||
10774 (RD_HARPOON(port+hp_selfid_1) != fifodata[4]))
10775 return(1);
10779 for(loop_cnt = 0; loop_cnt < 4; loop_cnt++) {
10781 WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | HOST_WRT | START_TO));
10784 for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) {
10786 WR_HARPOON(port+hp_fifodata_0, fifodata[loop_cnt]);
10790 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_FULL))
10791 return(1);
10794 WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | START_TO));
10796 for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) {
10798 if (RD_HARPOON(port+hp_fifodata_0) != fifodata[loop_cnt])
10799 return(1);
10803 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
10804 return(1);
10808 while(!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
10811 WR_HARPOON(port+hp_seltimeout,TO_290ms);
10813 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
10815 WRW_HARPOON((port+hp_intena), default_intena);
10817 return(0);
10821 /*---------------------------------------------------------------------
10823 * Function: DiagBusMaster
10825 * Description: Test BusMaster integrity. Non-zero return indicates an
10826 * error.
10828 *---------------------------------------------------------------------*/
10830 #if defined(DOS)
10831 int DiagBusMaster(USHORT port)
10832 #else
10833 int DiagBusMaster(ULONG port)
10834 #endif
10836 UCHAR testdata;
10838 for(testdata = (UCHAR) 1; testdata != (UCHAR)0; testdata = testdata << 1) {
10840 WR_HARPOON(port+hp_xfer_cnt_lo,testdata);
10841 WR_HARPOON(port+hp_xfer_cnt_mi,testdata);
10842 WR_HARPOON(port+hp_xfer_cnt_hi,testdata);
10843 WR_HARPOON(port+hp_host_addr_lo,testdata);
10844 WR_HARPOON(port+hp_host_addr_lmi,testdata);
10845 WR_HARPOON(port+hp_host_addr_hmi,testdata);
10846 WR_HARPOON(port+hp_host_addr_hi,testdata);
10848 if ((RD_HARPOON(port+hp_xfer_cnt_lo) != testdata) ||
10849 (RD_HARPOON(port+hp_xfer_cnt_mi) != testdata) ||
10850 (RD_HARPOON(port+hp_xfer_cnt_hi) != testdata) ||
10851 (RD_HARPOON(port+hp_host_addr_lo) != testdata) ||
10852 (RD_HARPOON(port+hp_host_addr_lmi) != testdata) ||
10853 (RD_HARPOON(port+hp_host_addr_hmi) != testdata) ||
10854 (RD_HARPOON(port+hp_host_addr_hi) != testdata))
10856 return(1);
10858 RD_HARPOON(port+hp_int_status); /*Clear interrupts. */
10859 return(0);
10864 /*---------------------------------------------------------------------
10866 * Function: DiagEEPROM
10868 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
10869 * neccessary.
10871 *---------------------------------------------------------------------*/
10873 #if defined(DOS)
10874 void DiagEEPROM(USHORT p_port)
10875 #else
10876 void DiagEEPROM(ULONG p_port)
10877 #endif
10880 USHORT index,temp,max_wd_cnt;
10882 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
10883 max_wd_cnt = EEPROM_WD_CNT;
10884 else
10885 max_wd_cnt = EEPROM_WD_CNT * 2;
10887 temp = utilEERead(p_port, FW_SIGNATURE/2);
10889 if (temp == 0x4641) {
10891 for (index = 2; index < max_wd_cnt; index++) {
10893 temp += utilEERead(p_port, index);
10897 if (temp == utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
10899 return; /*EEPROM is Okay so return now! */
10904 utilEEWriteOnOff(p_port,(UCHAR)1);
10906 for (index = 0; index < max_wd_cnt; index++) {
10908 utilEEWrite(p_port, 0x0000, index);
10911 temp = 0;
10913 utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
10914 temp += 0x4641;
10915 utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
10916 temp += 0x3920;
10917 utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
10918 temp += 0x3033;
10919 utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
10920 temp += 0x2020;
10921 utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
10922 temp += 0x70D3;
10923 utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
10924 temp += 0x0010;
10925 utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
10926 temp += 0x0003;
10927 utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
10928 temp += 0x0007;
10930 utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
10931 temp += 0x0000;
10932 utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
10933 temp += 0x0000;
10934 utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
10935 temp += 0x0000;
10937 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
10938 temp += 0x4242;
10939 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
10940 temp += 0x4242;
10941 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
10942 temp += 0x4242;
10943 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
10944 temp += 0x4242;
10945 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
10946 temp += 0x4242;
10947 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
10948 temp += 0x4242;
10949 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
10950 temp += 0x4242;
10951 utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
10952 temp += 0x4242;
10955 utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
10956 temp += 0x6C46;
10957 utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
10958 temp += 0x7361;
10959 utilEEWrite(p_port, 0x5068, 68/2);
10960 temp += 0x5068;
10961 utilEEWrite(p_port, 0x696F, 70/2);
10962 temp += 0x696F;
10963 utilEEWrite(p_port, 0x746E, 72/2);
10964 temp += 0x746E;
10965 utilEEWrite(p_port, 0x4C20, 74/2);
10966 temp += 0x4C20;
10967 utilEEWrite(p_port, 0x2054, 76/2);
10968 temp += 0x2054;
10969 utilEEWrite(p_port, 0x2020, 78/2);
10970 temp += 0x2020;
10972 index = ((EE_SCAMBASE/2)+(7*16));
10973 utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
10974 temp += (0x0700+TYPE_CODE0);
10975 index++;
10976 utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
10977 temp += 0x5542; /* BUSLOGIC */
10978 index++;
10979 utilEEWrite(p_port, 0x4C53, index);
10980 temp += 0x4C53;
10981 index++;
10982 utilEEWrite(p_port, 0x474F, index);
10983 temp += 0x474F;
10984 index++;
10985 utilEEWrite(p_port, 0x4349, index);
10986 temp += 0x4349;
10987 index++;
10988 utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
10989 temp += 0x5442; /* BT- 930 */
10990 index++;
10991 utilEEWrite(p_port, 0x202D, index);
10992 temp += 0x202D;
10993 index++;
10994 utilEEWrite(p_port, 0x3339, index);
10995 temp += 0x3339;
10996 index++; /*Serial # */
10997 utilEEWrite(p_port, 0x2030, index); /* 01234567 */
10998 temp += 0x2030;
10999 index++;
11000 utilEEWrite(p_port, 0x5453, index);
11001 temp += 0x5453;
11002 index++;
11003 utilEEWrite(p_port, 0x5645, index);
11004 temp += 0x5645;
11005 index++;
11006 utilEEWrite(p_port, 0x2045, index);
11007 temp += 0x2045;
11008 index++;
11009 utilEEWrite(p_port, 0x202F, index);
11010 temp += 0x202F;
11011 index++;
11012 utilEEWrite(p_port, 0x4F4A, index);
11013 temp += 0x4F4A;
11014 index++;
11015 utilEEWrite(p_port, 0x204E, index);
11016 temp += 0x204E;
11017 index++;
11018 utilEEWrite(p_port, 0x3539, index);
11019 temp += 0x3539;
11023 utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
11025 utilEEWriteOnOff(p_port,(UCHAR)0);
11029 #ident "$Id: utility.c 1.23 1997/06/10 16:55:06 mohan Exp $"
11030 /*----------------------------------------------------------------------
11033 * Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
11035 * This file is available under both the GNU General Public License
11036 * and a BSD-style copyright; see LICENSE.FlashPoint for details.
11038 * $Workfile: utility.c $
11040 * Description: Utility functions relating to queueing and EEPROM
11041 * manipulation and any other garbage functions.
11043 * $Date: 1997/06/10 16:55:06 $
11045 * $Revision: 1.23 $
11047 *----------------------------------------------------------------------*/
11048 /*#include <globals.h>*/
11050 #if (FW_TYPE==_UCB_MGR_)
11051 /*#include <budi.h>*/
11052 #endif
11054 /*#include <sccbmgr.h>*/
11055 /*#include <blx30.h>*/
11056 /*#include <target.h>*/
11057 /*#include <scsi2.h>*/
11058 /*#include <harpoon.h>*/
11062 extern SCCBCARD BL_Card[MAX_CARDS];
11063 extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
11064 extern unsigned int SccbGlobalFlags;
11067 /*---------------------------------------------------------------------
11069 * Function: Queue Search Select
11071 * Description: Try to find a new command to execute.
11073 *---------------------------------------------------------------------*/
11075 void queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
11077 UCHAR scan_ptr, lun;
11078 PSCCBMgr_tar_info currTar_Info;
11079 PSCCB pOldSccb;
11081 scan_ptr = pCurrCard->scanIndex;
11084 currTar_Info = &sccbMgrTbl[p_card][scan_ptr];
11085 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
11086 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
11088 if (currTar_Info->TarSelQ_Cnt != 0)
11091 scan_ptr++;
11092 if (scan_ptr == MAX_SCSI_TAR)
11093 scan_ptr = 0;
11095 for(lun=0; lun < MAX_LUN; lun++)
11097 if(currTar_Info->TarLUNBusy[lun] == FALSE)
11100 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
11101 pOldSccb = NULL;
11103 while((pCurrCard->currentSCCB != NULL) &&
11104 (lun != pCurrCard->currentSCCB->Lun))
11106 pOldSccb = pCurrCard->currentSCCB;
11107 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
11108 Sccb_forwardlink;
11110 if(pCurrCard->currentSCCB == NULL)
11111 continue;
11112 if(pOldSccb != NULL)
11114 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
11115 Sccb_forwardlink;
11116 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
11117 Sccb_backlink;
11118 currTar_Info->TarSelQ_Cnt--;
11120 else
11122 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
11124 if (currTar_Info->TarSelQ_Head == NULL)
11126 currTar_Info->TarSelQ_Tail = NULL;
11127 currTar_Info->TarSelQ_Cnt = 0;
11129 else
11131 currTar_Info->TarSelQ_Cnt--;
11132 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
11135 pCurrCard->scanIndex = scan_ptr;
11137 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
11139 break;
11144 else
11146 scan_ptr++;
11147 if (scan_ptr == MAX_SCSI_TAR) {
11148 scan_ptr = 0;
11153 else
11155 if ((currTar_Info->TarSelQ_Cnt != 0) &&
11156 (currTar_Info->TarLUNBusy[0] == FALSE))
11159 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
11161 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
11163 if (currTar_Info->TarSelQ_Head == NULL)
11165 currTar_Info->TarSelQ_Tail = NULL;
11166 currTar_Info->TarSelQ_Cnt = 0;
11168 else
11170 currTar_Info->TarSelQ_Cnt--;
11171 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
11174 scan_ptr++;
11175 if (scan_ptr == MAX_SCSI_TAR)
11176 scan_ptr = 0;
11178 pCurrCard->scanIndex = scan_ptr;
11180 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
11182 break;
11185 else
11187 scan_ptr++;
11188 if (scan_ptr == MAX_SCSI_TAR)
11190 scan_ptr = 0;
11194 } while (scan_ptr != pCurrCard->scanIndex);
11198 /*---------------------------------------------------------------------
11200 * Function: Queue Select Fail
11202 * Description: Add the current SCCB to the head of the Queue.
11204 *---------------------------------------------------------------------*/
11206 void queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
11208 UCHAR thisTarg;
11209 PSCCBMgr_tar_info currTar_Info;
11211 if (pCurrCard->currentSCCB != NULL)
11213 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
11214 currTar_Info = &sccbMgrTbl[p_card][thisTarg];
11216 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
11218 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
11220 if (currTar_Info->TarSelQ_Cnt == 0)
11222 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
11225 else
11227 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
11231 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
11233 pCurrCard->currentSCCB = NULL;
11234 currTar_Info->TarSelQ_Cnt++;
11237 /*---------------------------------------------------------------------
11239 * Function: Queue Command Complete
11241 * Description: Call the callback function with the current SCCB.
11243 *---------------------------------------------------------------------*/
11245 void queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb, UCHAR p_card)
11248 #if (FW_TYPE==_UCB_MGR_)
11250 u08bits SCSIcmd;
11251 CALL_BK_FN callback;
11252 PSCCBMgr_tar_info currTar_Info;
11254 PUCB p_ucb;
11255 p_ucb=p_sccb->Sccb_ucb_ptr;
11257 SCSIcmd = p_sccb->Cdb[0];
11260 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED))
11263 if ((p_ucb->UCB_opcode & OPC_CHK_UNDER_OVER_RUN) &&
11264 (p_sccb->HostStatus == SCCB_COMPLETE) &&
11265 (p_sccb->TargetStatus != SSCHECK))
11267 if ((SCSIcmd == SCSI_READ) ||
11268 (SCSIcmd == SCSI_WRITE) ||
11269 (SCSIcmd == SCSI_READ_EXTENDED) ||
11270 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
11271 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
11272 (SCSIcmd == SCSI_START_STOP_UNIT) ||
11273 (pCurrCard->globalFlags & F_NO_FILTER)
11275 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
11278 p_ucb->UCB_status=SCCB_SUCCESS;
11280 if ((p_ucb->UCB_hbastat=p_sccb->HostStatus) || (p_ucb->UCB_scsistat=p_sccb->TargetStatus))
11282 p_ucb->UCB_status=SCCB_ERROR;
11285 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
11286 (p_sccb->OperationCode == RESIDUAL_COMMAND))
11289 utilUpdateResidual(p_sccb);
11291 p_ucb->UCB_datalen=p_sccb->DataLength;
11294 pCurrCard->cmdCounter--;
11295 if (!pCurrCard->cmdCounter)
11298 if (pCurrCard->globalFlags & F_GREEN_PC)
11300 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
11301 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
11304 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
11305 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
11308 if(pCurrCard->discQCount != 0)
11310 currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
11311 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
11312 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
11314 pCurrCard->discQCount--;
11315 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
11317 else
11319 if(p_sccb->Sccb_tag)
11321 pCurrCard->discQCount--;
11322 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
11323 }else
11325 pCurrCard->discQCount--;
11326 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
11331 callback = (CALL_BK_FN)p_ucb->UCB_callback;
11332 callback(p_ucb);
11333 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
11334 pCurrCard->currentSCCB = NULL;
11340 #else
11342 UCHAR i, SCSIcmd;
11343 CALL_BK_FN callback;
11344 PSCCBMgr_tar_info currTar_Info;
11346 SCSIcmd = p_sccb->Cdb[0];
11349 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
11351 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
11352 (p_sccb->HostStatus == SCCB_COMPLETE) &&
11353 (p_sccb->TargetStatus != SSCHECK))
11355 if ((SCSIcmd == SCSI_READ) ||
11356 (SCSIcmd == SCSI_WRITE) ||
11357 (SCSIcmd == SCSI_READ_EXTENDED) ||
11358 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
11359 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
11360 (SCSIcmd == SCSI_START_STOP_UNIT) ||
11361 (pCurrCard->globalFlags & F_NO_FILTER)
11363 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
11367 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
11369 if (p_sccb->HostStatus || p_sccb->TargetStatus)
11370 p_sccb->SccbStatus = SCCB_ERROR;
11371 else
11372 p_sccb->SccbStatus = SCCB_SUCCESS;
11375 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
11377 p_sccb->CdbLength = p_sccb->Save_CdbLen;
11378 for (i=0; i < 6; i++) {
11379 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
11383 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
11384 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
11386 utilUpdateResidual(p_sccb);
11389 pCurrCard->cmdCounter--;
11390 if (!pCurrCard->cmdCounter) {
11392 if (pCurrCard->globalFlags & F_GREEN_PC) {
11393 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
11394 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
11397 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
11398 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
11402 if(pCurrCard->discQCount != 0)
11404 currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
11405 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
11406 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
11408 pCurrCard->discQCount--;
11409 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
11411 else
11413 if(p_sccb->Sccb_tag)
11415 pCurrCard->discQCount--;
11416 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
11417 }else
11419 pCurrCard->discQCount--;
11420 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
11426 callback = (CALL_BK_FN)p_sccb->SccbCallback;
11427 callback(p_sccb);
11428 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
11429 pCurrCard->currentSCCB = NULL;
11431 #endif /* ( if FW_TYPE==...) */
11434 /*---------------------------------------------------------------------
11436 * Function: Queue Disconnect
11438 * Description: Add SCCB to our disconnect array.
11440 *---------------------------------------------------------------------*/
11441 void queueDisconnect(PSCCB p_sccb, UCHAR p_card)
11443 PSCCBMgr_tar_info currTar_Info;
11445 currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
11447 if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
11448 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
11450 BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
11452 else
11454 if (p_sccb->Sccb_tag)
11456 BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
11457 sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = FALSE;
11458 sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
11459 }else
11461 BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
11464 BL_Card[p_card].currentSCCB = NULL;
11468 /*---------------------------------------------------------------------
11470 * Function: Queue Flush SCCB
11472 * Description: Flush all SCCB's back to the host driver for this target.
11474 *---------------------------------------------------------------------*/
11476 void queueFlushSccb(UCHAR p_card, UCHAR error_code)
11478 UCHAR qtag,thisTarg;
11479 PSCCB currSCCB;
11480 PSCCBMgr_tar_info currTar_Info;
11482 currSCCB = BL_Card[p_card].currentSCCB;
11483 if(currSCCB != NULL)
11485 thisTarg = (UCHAR)currSCCB->TargID;
11486 currTar_Info = &sccbMgrTbl[p_card][thisTarg];
11488 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
11490 if (BL_Card[p_card].discQ_Tbl[qtag] &&
11491 (BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
11494 BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
11496 queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card);
11498 BL_Card[p_card].discQ_Tbl[qtag] = NULL;
11499 currTar_Info->TarTagQ_Cnt--;
11507 /*---------------------------------------------------------------------
11509 * Function: Queue Flush Target SCCB
11511 * Description: Flush all SCCB's back to the host driver for this target.
11513 *---------------------------------------------------------------------*/
11515 void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code)
11517 UCHAR qtag;
11518 PSCCBMgr_tar_info currTar_Info;
11520 currTar_Info = &sccbMgrTbl[p_card][thisTarg];
11522 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
11524 if (BL_Card[p_card].discQ_Tbl[qtag] &&
11525 (BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
11528 BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
11530 queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card);
11532 BL_Card[p_card].discQ_Tbl[qtag] = NULL;
11533 currTar_Info->TarTagQ_Cnt--;
11544 void queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
11546 PSCCBMgr_tar_info currTar_Info;
11547 currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID];
11549 p_SCCB->Sccb_forwardlink = NULL;
11551 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
11553 if (currTar_Info->TarSelQ_Cnt == 0) {
11555 currTar_Info->TarSelQ_Head = p_SCCB;
11558 else {
11560 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
11564 currTar_Info->TarSelQ_Tail = p_SCCB;
11565 currTar_Info->TarSelQ_Cnt++;
11569 /*---------------------------------------------------------------------
11571 * Function: Queue Find SCCB
11573 * Description: Search the target select Queue for this SCCB, and
11574 * remove it if found.
11576 *---------------------------------------------------------------------*/
11578 UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
11580 PSCCB q_ptr;
11581 PSCCBMgr_tar_info currTar_Info;
11583 currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID];
11585 q_ptr = currTar_Info->TarSelQ_Head;
11587 while(q_ptr != NULL) {
11589 if (q_ptr == p_SCCB) {
11592 if (currTar_Info->TarSelQ_Head == q_ptr) {
11594 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
11597 if (currTar_Info->TarSelQ_Tail == q_ptr) {
11599 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
11602 if (q_ptr->Sccb_forwardlink != NULL) {
11603 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
11606 if (q_ptr->Sccb_backlink != NULL) {
11607 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
11610 currTar_Info->TarSelQ_Cnt--;
11612 return(TRUE);
11615 else {
11616 q_ptr = q_ptr->Sccb_forwardlink;
11621 return(FALSE);
11626 /*---------------------------------------------------------------------
11628 * Function: Utility Update Residual Count
11630 * Description: Update the XferCnt to the remaining byte count.
11631 * If we transferred all the data then just write zero.
11632 * If Non-SG transfer then report Total Cnt - Actual Transfer
11633 * Cnt. For SG transfers add the count fields of all
11634 * remaining SG elements, as well as any partial remaining
11635 * element.
11637 *---------------------------------------------------------------------*/
11639 void utilUpdateResidual(PSCCB p_SCCB)
11641 ULONG partial_cnt;
11642 UINT sg_index;
11643 #if defined(COMPILER_16_BIT) && !defined(DOS)
11644 ULONG far *sg_ptr;
11645 #else
11646 ULONG *sg_ptr;
11647 #endif
11649 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
11651 p_SCCB->DataLength = 0x0000;
11654 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
11656 partial_cnt = 0x0000;
11658 sg_index = p_SCCB->Sccb_sgseg;
11660 #if defined(COMPILER_16_BIT) && !defined(DOS)
11661 sg_ptr = (ULONG far *)p_SCCB->DataPointer;
11662 #else
11663 sg_ptr = (ULONG *)p_SCCB->DataPointer;
11664 #endif
11666 if (p_SCCB->Sccb_SGoffset) {
11668 partial_cnt = p_SCCB->Sccb_SGoffset;
11669 sg_index++;
11672 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
11673 p_SCCB->DataLength ) {
11675 partial_cnt += *(sg_ptr+(sg_index * 2));
11676 sg_index++;
11679 p_SCCB->DataLength = partial_cnt;
11682 else {
11684 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
11689 /*---------------------------------------------------------------------
11691 * Function: Wait 1 Second
11693 * Description: Wait for 1 second.
11695 *---------------------------------------------------------------------*/
11697 #if defined(DOS)
11698 void Wait1Second(USHORT p_port)
11699 #else
11700 void Wait1Second(ULONG p_port)
11701 #endif
11703 UCHAR i;
11705 for(i=0; i < 4; i++) {
11707 Wait(p_port, TO_250ms);
11709 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
11710 break;
11712 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
11713 break;
11718 /*---------------------------------------------------------------------
11720 * Function: Wait
11722 * Description: Wait the desired delay.
11724 *---------------------------------------------------------------------*/
11726 #if defined(DOS)
11727 void Wait(USHORT p_port, UCHAR p_delay)
11728 #else
11729 void Wait(ULONG p_port, UCHAR p_delay)
11730 #endif
11732 UCHAR old_timer;
11733 UCHAR green_flag;
11735 old_timer = RD_HARPOON(p_port+hp_seltimeout);
11737 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
11738 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
11740 WR_HARPOON(p_port+hp_seltimeout,p_delay);
11741 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
11742 WRW_HARPOON((p_port+hp_intena), (default_intena & ~TIMEOUT));
11745 WR_HARPOON(p_port+hp_portctrl_0,
11746 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
11748 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
11750 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
11751 break;
11753 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
11754 break;
11757 WR_HARPOON(p_port+hp_portctrl_0,
11758 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
11760 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
11761 WRW_HARPOON((p_port+hp_intena), default_intena);
11763 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
11765 WR_HARPOON(p_port+hp_seltimeout,old_timer);
11769 /*---------------------------------------------------------------------
11771 * Function: Enable/Disable Write to EEPROM
11773 * Description: The EEPROM must first be enabled for writes
11774 * A total of 9 clocks are needed.
11776 *---------------------------------------------------------------------*/
11778 #if defined(DOS)
11779 void utilEEWriteOnOff(USHORT p_port,UCHAR p_mode)
11780 #else
11781 void utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
11782 #endif
11784 UCHAR ee_value;
11786 ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
11788 if (p_mode)
11790 utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
11792 else
11795 utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
11797 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
11798 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
11802 /*---------------------------------------------------------------------
11804 * Function: Write EEPROM
11806 * Description: Write a word to the EEPROM at the specified
11807 * address.
11809 *---------------------------------------------------------------------*/
11811 #if defined(DOS)
11812 void utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr)
11813 #else
11814 void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
11815 #endif
11818 UCHAR ee_value;
11819 USHORT i;
11821 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
11822 (SEE_MS | SEE_CS));
11826 utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
11829 ee_value |= (SEE_MS + SEE_CS);
11831 for(i = 0x8000; i != 0; i>>=1) {
11833 if (i & ee_data)
11834 ee_value |= SEE_DO;
11835 else
11836 ee_value &= ~SEE_DO;
11838 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11839 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11840 ee_value |= SEE_CLK; /* Clock data! */
11841 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11842 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11843 ee_value &= ~SEE_CLK;
11844 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11845 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11847 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
11848 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
11850 Wait(p_port, TO_10ms);
11852 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
11853 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
11854 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
11857 /*---------------------------------------------------------------------
11859 * Function: Read EEPROM
11861 * Description: Read a word from the EEPROM at the desired
11862 * address.
11864 *---------------------------------------------------------------------*/
11866 #if defined(DOS)
11867 USHORT utilEERead(USHORT p_port, USHORT ee_addr)
11868 #else
11869 USHORT utilEERead(ULONG p_port, USHORT ee_addr)
11870 #endif
11872 USHORT i, ee_data1, ee_data2;
11874 i = 0;
11875 ee_data1 = utilEEReadOrg(p_port, ee_addr);
11878 ee_data2 = utilEEReadOrg(p_port, ee_addr);
11880 if(ee_data1 == ee_data2)
11881 return(ee_data1);
11883 ee_data1 = ee_data2;
11884 i++;
11886 }while(i < 4);
11888 return(ee_data1);
11891 /*---------------------------------------------------------------------
11893 * Function: Read EEPROM Original
11895 * Description: Read a word from the EEPROM at the desired
11896 * address.
11898 *---------------------------------------------------------------------*/
11900 #if defined(DOS)
11901 USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr)
11902 #else
11903 USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr)
11904 #endif
11907 UCHAR ee_value;
11908 USHORT i, ee_data;
11910 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
11911 (SEE_MS | SEE_CS));
11914 utilEESendCmdAddr(p_port, EE_READ, ee_addr);
11917 ee_value |= (SEE_MS + SEE_CS);
11918 ee_data = 0;
11920 for(i = 1; i <= 16; i++) {
11922 ee_value |= SEE_CLK; /* Clock data! */
11923 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11924 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11925 ee_value &= ~SEE_CLK;
11926 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11927 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11929 ee_data <<= 1;
11931 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
11932 ee_data |= 1;
11935 ee_value &= ~(SEE_MS + SEE_CS);
11936 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
11937 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
11939 return(ee_data);
11943 /*---------------------------------------------------------------------
11945 * Function: Send EE command and Address to the EEPROM
11947 * Description: Transfers the correct command and sends the address
11948 * to the eeprom.
11950 *---------------------------------------------------------------------*/
11952 #if defined(DOS)
11953 void utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr)
11954 #else
11955 void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
11956 #endif
11958 UCHAR ee_value;
11959 UCHAR narrow_flg;
11961 USHORT i;
11964 narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
11967 ee_value = SEE_MS;
11968 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11970 ee_value |= SEE_CS; /* Set CS to EEPROM */
11971 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11974 for(i = 0x04; i != 0; i>>=1) {
11976 if (i & ee_cmd)
11977 ee_value |= SEE_DO;
11978 else
11979 ee_value &= ~SEE_DO;
11981 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11982 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11983 ee_value |= SEE_CLK; /* Clock data! */
11984 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11985 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11986 ee_value &= ~SEE_CLK;
11987 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11988 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
11992 if (narrow_flg)
11993 i = 0x0080;
11995 else
11996 i = 0x0200;
11999 while (i != 0) {
12001 if (i & ee_addr)
12002 ee_value |= SEE_DO;
12003 else
12004 ee_value &= ~SEE_DO;
12006 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
12007 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
12008 ee_value |= SEE_CLK; /* Clock data! */
12009 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
12010 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
12011 ee_value &= ~SEE_CLK;
12012 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
12013 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
12015 i >>= 1;
12019 USHORT CalcCrc16(UCHAR buffer[])
12021 USHORT crc=0;
12022 int i,j;
12023 USHORT ch;
12024 for (i=0; i < ID_STRING_LENGTH; i++)
12026 ch = (USHORT) buffer[i];
12027 for(j=0; j < 8; j++)
12029 if ((crc ^ ch) & 1)
12030 crc = (crc >> 1) ^ CRCMASK;
12031 else
12032 crc >>= 1;
12033 ch >>= 1;
12036 return(crc);
12039 UCHAR CalcLrc(UCHAR buffer[])
12041 int i;
12042 UCHAR lrc;
12043 lrc = 0;
12044 for(i = 0; i < ID_STRING_LENGTH; i++)
12045 lrc ^= buffer[i];
12046 return(lrc);
12052 The following inline definitions avoid type conflicts.
12055 static inline unsigned char
12056 FlashPoint__ProbeHostAdapter(FlashPoint_Info_T *FlashPointInfo)
12058 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
12062 static inline FlashPoint_CardHandle_T
12063 FlashPoint__HardwareResetHostAdapter(FlashPoint_Info_T *FlashPointInfo)
12065 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
12068 static inline void
12069 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
12071 FlashPoint_ReleaseHostAdapter(CardHandle);
12075 static inline void
12076 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB)
12078 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
12082 static inline void
12083 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB)
12085 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
12089 static inline boolean
12090 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
12092 return FlashPoint_InterruptPending(CardHandle);
12096 static inline int
12097 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
12099 return FlashPoint_HandleInterrupt(CardHandle);
12103 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
12104 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
12105 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
12106 #define FlashPoint_StartCCB FlashPoint__StartCCB
12107 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
12108 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
12109 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
12113 FlashPoint_InquireTargetInfo returns the Synchronous Period, Synchronous
12114 Offset, and Wide Transfers Active information for TargetID on CardHandle.
12117 void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T CardHandle,
12118 int TargetID,
12119 unsigned char *SynchronousPeriod,
12120 unsigned char *SynchronousOffset,
12121 unsigned char *WideTransfersActive)
12123 SCCBMGR_TAR_INFO *TargetInfo =
12124 &sccbMgrTbl[((SCCBCARD *)CardHandle)->cardIndex][TargetID];
12125 if ((TargetInfo->TarSyncCtrl & SYNC_OFFSET) > 0)
12127 *SynchronousPeriod = 5 * ((TargetInfo->TarSyncCtrl >> 5) + 1);
12128 *SynchronousOffset = TargetInfo->TarSyncCtrl & SYNC_OFFSET;
12130 else
12132 *SynchronousPeriod = 0;
12133 *SynchronousOffset = 0;
12135 *WideTransfersActive = (TargetInfo->TarSyncCtrl & NARROW_SCSI ? 0 : 1);
12139 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
12143 Define prototypes for the FlashPoint SCCB Manager Functions.
12146 extern unsigned char FlashPoint_ProbeHostAdapter(FlashPoint_Info_T *);
12147 extern FlashPoint_CardHandle_T
12148 FlashPoint_HardwareResetHostAdapter(FlashPoint_Info_T *);
12149 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *);
12150 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *);
12151 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
12152 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
12153 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
12154 extern void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T,
12155 int, unsigned char *,
12156 unsigned char *, unsigned char *);
12159 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */