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
36 #define CRCMASK 0xA001
40 #define FAILURE 0xFFFFFFFFL
43 typedef unsigned long ULONG;
46 typedef unsigned short * ushort_ptr;
53 #define u08bits unsigned s08bits
54 #define u16bits unsigned s16bits
55 #define u32bits unsigned s32bits
59 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
60 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
65 typedef struct _SCCB *PSCCB;
66 typedef void (*CALL_BK_FN)(PSCCB);
69 typedef struct SCCBMgr_info {
71 unsigned char si_present;
72 unsigned char si_intvect;
75 unsigned short si_fw_revision;
76 unsigned short si_per_targ_init_sync;
77 unsigned short si_per_targ_fast_nego;
78 unsigned short si_per_targ_ultra_nego;
79 unsigned short si_per_targ_no_disc;
80 unsigned short si_per_targ_wide_nego;
81 unsigned short si_flags;
82 unsigned char si_card_family;
83 unsigned char si_bustype;
84 unsigned char si_card_model[3];
85 unsigned char si_relative_cardnum;
86 unsigned char si_reserved[4];
88 unsigned char si_XlatInfo[4];
89 ULONG si_reserved2[5];
90 ULONG si_secondary_range;
93 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
96 #define SCSI_PARITY_ENA 0x0001
97 #define LOW_BYTE_TERM 0x0010
98 #define HIGH_BYTE_TERM 0x0020
99 #define BUSTYPE_PCI 0x3
101 #define SUPPORT_16TAR_32LUN 0x0002
102 #define SOFT_RESET 0x0004
103 #define EXTENDED_TRANSLATION 0x0008
104 #define POST_ALL_UNDERRRUNS 0x0040
105 #define FLAG_SCAM_ENABLED 0x0080
106 #define FLAG_SCAM_LEVEL2 0x0100
111 #define HARPOON_FAMILY 0x02
115 /* SCCB struct used for both SCCB and UCB manager compiles!
116 * The UCB Manager treats the SCCB as it's 'native hardware structure'
121 typedef struct _SCCB {
122 unsigned char OperationCode;
123 unsigned char ControlByte;
124 unsigned char CdbLength;
125 unsigned char RequestSenseLength;
128 unsigned char CcbRes[2];
129 unsigned char HostStatus;
130 unsigned char TargetStatus;
131 unsigned char TargID;
133 unsigned char Cdb[12];
134 unsigned char CcbRes1;
135 unsigned char Reserved1;
140 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
141 ULONG SccbIOPort; /* Identifies board base port */
142 unsigned char SccbStatus;
143 unsigned char SCCBRes2;
144 unsigned short SccbOSFlags;
147 ULONG Sccb_XferCnt; /* actual transfer count */
149 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
151 unsigned short Sccb_MGRFlags;
152 unsigned short Sccb_sgseg;
153 unsigned char Sccb_scsimsg; /* identify msg for selection */
154 unsigned char Sccb_tag;
155 unsigned char Sccb_scsistat;
156 unsigned char Sccb_idmsg; /* image of last msg in */
157 PSCCB Sccb_forwardlink;
160 unsigned char Save_Cdb[6];
161 unsigned char Save_CdbLen;
162 unsigned char Sccb_XferState;
171 #define SCATTER_GATHER_COMMAND 0x02
172 #define RESIDUAL_COMMAND 0x03
173 #define RESIDUAL_SG_COMMAND 0x04
174 #define RESET_COMMAND 0x81
177 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
178 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
179 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
180 #define SCCB_DATA_XFER_IN 0x08 /* Read */
183 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
186 #define BUS_FREE_ST 0
188 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
189 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
190 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
191 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
193 #define DATA_OUT_ST 7
195 #define DISCONNECT_ST 9
199 #define F_HOST_XFER_DIR 0x01
200 #define F_ALL_XFERRED 0x02
201 #define F_SG_XFER 0x04
202 #define F_AUTO_SENSE 0x08
203 #define F_ODD_BALL_CNT 0x10
204 #define F_NO_DATA_YET 0x80
207 #define F_STATUSLOADED 0x01
208 #define F_DEV_SELECTED 0x04
211 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
212 #define SCCB_DATA_UNDER_RUN 0x0C
213 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
214 #define SCCB_DATA_OVER_RUN 0x12
215 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
217 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
218 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
219 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
225 #define SCCB_IN_PROCESS 0x00
226 #define SCCB_SUCCESS 0x01
227 #define SCCB_ABORT 0x02
228 #define SCCB_ERROR 0x04
232 #define ORION_FW_REV 3110
236 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
238 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
241 #define MAX_SCSI_TAR 16
243 #define LUN_MASK 0x1f
245 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
247 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
250 #define RD_HARPOON(ioport) inb((u32bits)ioport)
251 #define RDW_HARPOON(ioport) inw((u32bits)ioport)
252 #define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
253 #define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
254 #define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
255 #define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
258 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
259 #define SYNC_TRYING BIT(6)
260 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
262 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
263 #define WIDE_ENABLED BIT(4)
264 #define WIDE_NEGOCIATED BIT(5)
266 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
267 #define TAG_Q_TRYING BIT(2)
268 #define TAG_Q_REJECT BIT(3)
270 #define TAR_ALLOW_DISC BIT(0)
273 #define EE_SYNC_MASK (BIT(0)+BIT(1))
274 #define EE_SYNC_5MB BIT(0)
275 #define EE_SYNC_10MB BIT(1)
276 #define EE_SYNC_20MB (BIT(0)+BIT(1))
278 #define EE_WIDE_SCSI BIT(7)
281 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
284 typedef struct SCCBMgr_tar_info {
288 unsigned char TarLUN_CA; /*Contingent Allgiance */
289 unsigned char TarTagQ_Cnt;
290 unsigned char TarSelQ_Cnt;
291 unsigned char TarStatus;
292 unsigned char TarEEValue;
293 unsigned char TarSyncCtrl;
294 unsigned char TarReserved[2]; /* for alignment */
295 unsigned char LunDiscQ_Idx[MAX_LUN];
296 unsigned char TarLUNBusy[MAX_LUN];
299 typedef struct NVRAMInfo {
300 unsigned char niModel; /* Model No. of card */
301 unsigned char niCardNo; /* Card no. */
302 ULONG niBaseAddr; /* Port Address of card */
303 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
304 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
305 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
306 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
307 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
308 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
311 typedef NVRAMINFO *PNVRamInfo;
319 typedef struct SCCBcard {
321 PSCCBMGR_INFO cardInfo;
325 unsigned short cmdCounter;
326 unsigned char discQCount;
327 unsigned char tagQ_Lst;
328 unsigned char cardIndex;
329 unsigned char scanIndex;
330 unsigned char globalFlags;
332 PNVRamInfo pNvRamInfo;
333 PSCCB discQ_Tbl[QUEUE_DEPTH];
337 typedef struct SCCBcard *PSCCBcard;
340 #define F_TAG_STARTED 0x01
341 #define F_CONLUN_IO 0x02
342 #define F_DO_RENEGO 0x04
343 #define F_NO_FILTER 0x08
344 #define F_GREEN_PC 0x10
345 #define F_HOST_XFER_ACT 0x20
346 #define F_NEW_SCCB_CMD 0x40
347 #define F_UPDATE_EEPROM 0x80
350 #define ID_STRING_LENGTH 32
351 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
354 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
356 #define ASSIGN_ID 0x00
357 #define SET_P_FLAG 0x01
358 #define CFG_CMPLT 0x03
359 #define DOM_MSTR 0x0F
360 #define SYNC_PTRN 0x1F
364 #define MISC_CODE 0x14
365 #define CLR_P_FLAG 0x18
369 #define INIT_SELTD 0x01
370 #define LEVEL2_TAR 0x02
373 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
374 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
375 CLR_PRIORITY,NO_ID_AVAIL };
377 typedef struct SCCBscam_info {
379 unsigned char id_string[ID_STRING_LENGTH];
380 enum scam_id_st state;
385 #define SCSI_REQUEST_SENSE 0x03
386 #define SCSI_READ 0x08
387 #define SCSI_WRITE 0x0A
388 #define SCSI_START_STOP_UNIT 0x1B
389 #define SCSI_READ_EXTENDED 0x28
390 #define SCSI_WRITE_EXTENDED 0x2A
391 #define SCSI_WRITE_AND_VERIFY 0x2E
397 #define SSQ_FULL 0x28
402 #define SMCMD_COMP 0x00
404 #define SMSAVE_DATA_PTR 0x02
405 #define SMREST_DATA_PTR 0x03
408 #define SMREJECT 0x07
410 #define SMPARITY 0x09
411 #define SMDEV_RESET 0x0C
412 #define SMABORT_TAG 0x0D
413 #define SMINIT_RECOVERY 0x0F
414 #define SMREL_RECOVERY 0x10
417 #define DISC_PRIV 0x40
424 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
433 #define SIX_BYTE_CMD 0x06
434 #define TWELVE_BYTE_CMD 0x0C
437 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
440 #define EEPROM_WD_CNT 256
442 #define EEPROM_CHECK_SUM 0
443 #define FW_SIGNATURE 2
444 #define MODEL_NUMB_0 4
445 #define MODEL_NUMB_2 6
446 #define MODEL_NUMB_4 8
447 #define SYSTEM_CONFIG 16
448 #define SCSI_CONFIG 17
449 #define BIOS_CONFIG 18
450 #define SCAM_CONFIG 20
451 #define ADAPTER_SCSI_ID 24
454 #define IGNORE_B_SCAN 32
455 #define SEND_START_ENA 34
456 #define DEVICE_ENABLE 36
458 #define SYNC_RATE_TBL 38
459 #define SYNC_RATE_TBL01 38
460 #define SYNC_RATE_TBL23 40
461 #define SYNC_RATE_TBL45 42
462 #define SYNC_RATE_TBL67 44
463 #define SYNC_RATE_TBL89 46
464 #define SYNC_RATE_TBLab 48
465 #define SYNC_RATE_TBLcd 50
466 #define SYNC_RATE_TBLef 52
470 #define EE_SCAMBASE 256
474 #define SCAM_ENABLED BIT(2)
475 #define SCAM_LEVEL2 BIT(3)
478 #define RENEGO_ENA BITW(10)
479 #define CONNIO_ENA BITW(11)
480 #define GREEN_PC_ENA BITW(12)
483 #define AUTO_RATE_00 00
484 #define AUTO_RATE_05 01
485 #define AUTO_RATE_10 02
486 #define AUTO_RATE_20 03
488 #define WIDE_NEGO_BIT BIT(7)
489 #define DISC_ENABLE_BIT BIT(6)
493 #define hp_vendor_id_0 0x00 /* LSB */
494 #define ORION_VEND_0 0x4B
496 #define hp_vendor_id_1 0x01 /* MSB */
497 #define ORION_VEND_1 0x10
499 #define hp_device_id_0 0x02 /* LSB */
500 #define ORION_DEV_0 0x30
502 #define hp_device_id_1 0x03 /* MSB */
503 #define ORION_DEV_1 0x81
505 /* Sub Vendor ID and Sub Device ID only available in
506 Harpoon Version 2 and higher */
508 #define hp_sub_device_id_0 0x06 /* LSB */
512 #define hp_semaphore 0x0C
513 #define SCCB_MGR_ACTIVE BIT(0)
514 #define TICKLE_ME BIT(1)
515 #define SCCB_MGR_PRESENT BIT(3)
516 #define BIOS_IN_USE BIT(4)
520 #define hp_sys_ctrl 0x0F
522 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
523 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
524 #define HALT_MACH BIT(3) /*Halt State Machine */
525 #define HARD_ABORT BIT(4) /*Hard Abort */
535 #define hp_host_blk_cnt 0x13
537 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
539 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
543 #define hp_int_mask 0x17
545 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
546 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
549 #define hp_xfer_cnt_lo 0x18
550 #define hp_xfer_cnt_hi 0x1A
551 #define hp_xfer_cmd 0x1B
553 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
554 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
557 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
559 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
561 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
563 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
564 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
566 #define hp_host_addr_lo 0x1C
567 #define hp_host_addr_hmi 0x1E
569 #define hp_ee_ctrl 0x22
571 #define EXT_ARB_ACK BIT(7)
572 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
573 #define SEE_MS BIT(5)
574 #define SEE_CS BIT(3)
575 #define SEE_CLK BIT(2)
576 #define SEE_DO BIT(1)
577 #define SEE_DI BIT(0)
580 #define EE_WRITE 0x05
582 #define EWEN_ADDR 0x03C0
584 #define EWDS_ADDR 0x0000
592 #define hp_bm_ctrl 0x26
594 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
595 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
596 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
597 #define FAST_SINGLE BIT(6) /*?? */
599 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
602 #define hp_sg_addr 0x28
603 #define hp_page_ctrl 0x29
605 #define SCATTER_EN BIT(0)
606 #define SGRAM_ARAM BIT(1)
607 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
608 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
613 #define hp_pci_stat_cfg 0x2D
615 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
624 #define hp_rev_num 0x33
627 #define hp_stack_data 0x34
628 #define hp_stack_addr 0x35
630 #define hp_ext_status 0x36
632 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
633 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
634 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
635 #define CMD_ABORTED BIT(4) /*Command aborted */
636 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
637 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
638 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
639 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
640 BM_PARITY_ERR | PIO_OVERRUN)
642 #define hp_int_status 0x37
644 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
645 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
646 #define INT_ASSERTED BIT(5) /* */
649 #define hp_fifo_cnt 0x38
654 #define hp_intena 0x40
656 #define RESET BITW(7)
657 #define PROG_HLT BITW(6)
658 #define PARITY BITW(5)
661 #define SCAM_SEL BITW(2)
663 #define TIMEOUT BITW(0)
664 #define BUS_FREE BITW(15)
665 #define XFER_CNT_0 BITW(14)
666 #define PHASE BITW(13)
667 #define IUNKWN BITW(12)
668 #define ICMD_COMP BITW(11)
669 #define ITICKLE BITW(10)
670 #define IDO_STRT BITW(9)
671 #define ITAR_DISC BITW(8)
672 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
673 #define CLR_ALL_INT 0xFFFF
674 #define CLR_ALL_INT_1 0xFF00
676 #define hp_intstat 0x42
678 #define hp_scsisig 0x44
680 #define SCSI_SEL BIT(7)
681 #define SCSI_BSY BIT(6)
682 #define SCSI_REQ BIT(5)
683 #define SCSI_ACK BIT(4)
684 #define SCSI_ATN BIT(3)
685 #define SCSI_CD BIT(2)
686 #define SCSI_MSG BIT(1)
687 #define SCSI_IOBIT BIT(0)
689 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
690 #define S_MSGO_PH (BIT(2)+BIT(1) )
691 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
692 #define S_DATAI_PH ( BIT(0))
693 #define S_DATAO_PH 0x00
694 #define S_ILL_PH ( BIT(1) )
696 #define hp_scsictrl_0 0x45
698 #define SEL_TAR BIT(6)
699 #define ENA_ATN BIT(4)
700 #define ENA_RESEL BIT(2)
701 #define SCSI_RST BIT(1)
702 #define ENA_SCAM_SEL BIT(0)
706 #define hp_portctrl_0 0x46
708 #define SCSI_PORT BIT(7)
709 #define SCSI_INBIT BIT(6)
710 #define DMA_PORT BIT(5)
711 #define DMA_RD BIT(4)
712 #define HOST_PORT BIT(3)
713 #define HOST_WRT BIT(2)
714 #define SCSI_BUS_EN BIT(1)
715 #define START_TO BIT(0)
717 #define hp_scsireset 0x47
719 #define SCSI_INI BIT(6)
720 #define SCAM_EN BIT(5)
721 #define DMA_RESET BIT(3)
722 #define HPSCSI_RESET BIT(2)
723 #define PROG_RESET BIT(1)
724 #define FIFO_CLR BIT(0)
726 #define hp_xfercnt_0 0x48
727 #define hp_xfercnt_2 0x4A
729 #define hp_fifodata_0 0x4C
730 #define hp_addstat 0x4E
732 #define SCAM_TIMER BIT(7)
733 #define SCSI_MODE8 BIT(3)
734 #define SCSI_PAR_ERR BIT(0)
736 #define hp_prgmcnt_0 0x4F
739 #define hp_selfid_0 0x50
740 #define hp_selfid_1 0x51
741 #define hp_arb_id 0x52
744 #define hp_select_id 0x53
747 #define hp_synctarg_base 0x54
748 #define hp_synctarg_12 0x54
749 #define hp_synctarg_13 0x55
750 #define hp_synctarg_14 0x56
751 #define hp_synctarg_15 0x57
753 #define hp_synctarg_8 0x58
754 #define hp_synctarg_9 0x59
755 #define hp_synctarg_10 0x5A
756 #define hp_synctarg_11 0x5B
758 #define hp_synctarg_4 0x5C
759 #define hp_synctarg_5 0x5D
760 #define hp_synctarg_6 0x5E
761 #define hp_synctarg_7 0x5F
763 #define hp_synctarg_0 0x60
764 #define hp_synctarg_1 0x61
765 #define hp_synctarg_2 0x62
766 #define hp_synctarg_3 0x63
768 #define NARROW_SCSI BIT(4)
769 #define DEFAULT_OFFSET 0x0F
771 #define hp_autostart_0 0x64
772 #define hp_autostart_1 0x65
773 #define hp_autostart_3 0x67
777 #define AUTO_IMMED BIT(5)
778 #define SELECT BIT(6)
779 #define END_DATA (BIT(7)+BIT(6))
781 #define hp_gp_reg_0 0x68
782 #define hp_gp_reg_1 0x69
783 #define hp_gp_reg_3 0x6B
785 #define hp_seltimeout 0x6C
788 #define TO_4ms 0x67 /* 3.9959ms */
790 #define TO_5ms 0x03 /* 4.9152ms */
791 #define TO_10ms 0x07 /* 11.xxxms */
792 #define TO_250ms 0x99 /* 250.68ms */
793 #define TO_290ms 0xB1 /* 289.99ms */
795 #define hp_clkctrl_0 0x6D
797 #define PWR_DWN BIT(6)
798 #define ACTdeassert BIT(4)
799 #define CLK_40MHZ (BIT(1) + BIT(0))
801 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
803 #define hp_fiforead 0x6E
804 #define hp_fifowrite 0x6F
806 #define hp_offsetctr 0x70
807 #define hp_xferstat 0x71
809 #define FIFO_EMPTY BIT(6)
811 #define hp_portctrl_1 0x72
813 #define CHK_SCSI_P BIT(3)
814 #define HOST_MODE8 BIT(0)
816 #define hp_xfer_pad 0x73
818 #define ID_UNLOCK BIT(3)
820 #define hp_scsidata_0 0x74
821 #define hp_scsidata_1 0x75
825 #define hp_aramBase 0x80
826 #define BIOS_DATA_OFFSET 0x60
827 #define BIOS_RELATIVE_CARD 0x64
832 #define AR3 (BITW(9) + BITW(8))
833 #define SDATA BITW(10)
836 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
838 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
842 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
844 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
847 #define ADATA_OUT 0x00
848 #define ADATA_IN BITW(8)
849 #define ACOMMAND BITW(10)
850 #define ASTATUS (BITW(10)+BITW(8))
851 #define AMSG_OUT (BITW(10)+BITW(9))
852 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
855 #define BRH_OP BITW(13) /* Branch */
859 #define EQUAL BITW(8)
860 #define NOT_EQ BITW(9)
862 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
865 #define FIFO_0 BITW(10)
868 #define MPM_OP BITW(15) /* Match phase and move data */
871 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
874 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
879 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
889 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
891 #define SSI_OP (BITW(15)+BITW(11))
894 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
895 #define SSI_IDO_STRT (IDO_STRT >> 8)
897 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
898 #define SSI_ITICKLE (ITICKLE >> 8)
900 #define SSI_IUNKWN (IUNKWN >> 8)
901 #define SSI_INO_CC (IUNKWN >> 8)
902 #define SSI_IRFAIL (IUNKWN >> 8)
905 #define NP 0x10 /*Next Phase */
906 #define NTCMD 0x02 /*Non- Tagged Command start */
907 #define CMDPZ 0x04 /*Command phase */
908 #define DINT 0x12 /*Data Out/In interrupt */
909 #define DI 0x13 /*Data Out */
910 #define DC 0x19 /*Disconnect Message */
911 #define ST 0x1D /*Status Phase */
912 #define UNKNWN 0x24 /*Unknown bus action */
913 #define CC 0x25 /*Command Completion failure */
914 #define TICK 0x26 /*New target reselected us. */
915 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
918 #define ID_MSG_STRT hp_aramBase + 0x00
919 #define NON_TAG_ID_MSG hp_aramBase + 0x06
920 #define CMD_STRT hp_aramBase + 0x08
921 #define SYNC_MSGS hp_aramBase + 0x08
927 #define TAG_STRT 0x00
928 #define DISCONNECT_START 0x10/2
929 #define END_DATA_START 0x14/2
930 #define CMD_ONLY_STRT CMDPZ/2
931 #define SELCHK_STRT SELCHK/2
941 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
942 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
944 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
946 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
948 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
949 WR_HARP32(port,hp_xfercnt_0,count),\
950 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
952 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
954 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
955 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
958 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
959 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
963 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
964 WR_HARPOON(port+hp_scsireset, 0x00))
966 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
967 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
969 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
970 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
972 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
973 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
975 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
976 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
981 static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag);
982 static void FPT_ssel(ULONG port, unsigned char p_card);
983 static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard);
984 static void FPT_shandem(ULONG port, unsigned char p_card,PSCCB pCurrSCCB);
985 static void FPT_stsyncn(ULONG port, unsigned char p_card);
986 static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset);
987 static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
988 PSCCBMgr_tar_info currTar_Info);
989 static void FPT_sresb(ULONG port, unsigned char p_card);
990 static void FPT_sxfrp(ULONG p_port, unsigned char p_card);
991 static void FPT_schkdd(ULONG port, unsigned char p_card);
992 static unsigned char FPT_RdStack(ULONG port, unsigned char index);
993 static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data);
994 static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort);
996 static void FPT_SendMsg(ULONG port, unsigned char message);
997 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
998 unsigned char error_code);
1000 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
1001 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1003 static unsigned char FPT_siwidn(ULONG port, unsigned char p_card);
1004 static void FPT_stwidn(ULONG port, unsigned char p_card);
1005 static void FPT_siwidr(ULONG port, unsigned char width);
1008 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1009 static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
1010 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1011 unsigned char p_card);
1012 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1013 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1014 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1015 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
1016 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1017 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1018 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1021 static void FPT_Wait1Second(ULONG p_port);
1022 static void FPT_Wait(ULONG p_port, unsigned char p_delay);
1023 static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode);
1024 static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr);
1025 static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr);
1026 static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr);
1027 static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr);
1031 static void FPT_phaseDataOut(ULONG port, unsigned char p_card);
1032 static void FPT_phaseDataIn(ULONG port, unsigned char p_card);
1033 static void FPT_phaseCommand(ULONG port, unsigned char p_card);
1034 static void FPT_phaseStatus(ULONG port, unsigned char p_card);
1035 static void FPT_phaseMsgOut(ULONG port, unsigned char p_card);
1036 static void FPT_phaseMsgIn(ULONG port, unsigned char p_card);
1037 static void FPT_phaseIllegal(ULONG port, unsigned char p_card);
1039 static void FPT_phaseDecode(ULONG port, unsigned char p_card);
1040 static void FPT_phaseChkFifo(ULONG port, unsigned char p_card);
1041 static void FPT_phaseBusFree(ULONG p_port, unsigned char p_card);
1046 static void FPT_XbowInit(ULONG port, unsigned char scamFlg);
1047 static void FPT_BusMasterInit(ULONG p_port);
1048 static void FPT_DiagEEPROM(ULONG p_port);
1053 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1054 static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1055 static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1056 static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB);
1057 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1060 static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
1061 PSCCBcard pCurrCard, unsigned short p_int);
1063 static void FPT_SccbMgrTableInitAll(void);
1064 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1065 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1069 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1071 static int FPT_scarb(ULONG p_port, unsigned char p_sel_type);
1072 static void FPT_scbusf(ULONG p_port);
1073 static void FPT_scsel(ULONG p_port);
1074 static void FPT_scasid(unsigned char p_card, ULONG p_port);
1075 static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data);
1076 static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[]);
1077 static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[]);
1078 static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit);
1079 static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit);
1080 static unsigned char FPT_scvalq(unsigned char p_quintet);
1081 static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id);
1082 static void FPT_scwtsel(ULONG p_port);
1083 static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id);
1084 static void FPT_scsavdi(unsigned char p_card, ULONG p_port);
1085 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1088 static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card);
1089 static void FPT_autoLoadDefaultMap(ULONG p_port);
1094 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1095 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1096 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1097 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1100 static unsigned char FPT_mbCards = 0;
1101 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1102 ' ', 'B', 'T', '-', '9', '3', '0', \
1103 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1104 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1106 static unsigned short FPT_default_intena = 0;
1109 static void (*FPT_s_PhaseTbl[8]) (ULONG, unsigned char)= { 0 };
1112 /*---------------------------------------------------------------------
1114 * Function: FlashPoint_ProbeHostAdapter
1116 * Description: Setup and/or Search for cards and return info to caller.
1118 *---------------------------------------------------------------------*/
1120 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1122 static unsigned char first_time = 1;
1124 unsigned char i,j,id,ScamFlg;
1125 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1127 PNVRamInfo pCurrNvRam;
1129 ioport = pCardInfo->si_baseaddr;
1132 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1133 return((int)FAILURE);
1135 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1136 return((int)FAILURE);
1138 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1139 return((int)FAILURE);
1141 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1142 return((int)FAILURE);
1145 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1147 /* For new Harpoon then check for sub_device ID LSB
1148 the bits(0-3) must be all ZERO for compatible with
1149 current version of SCCBMgr, else skip this Harpoon
1152 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1153 return((int)FAILURE);
1158 FPT_SccbMgrTableInitAll();
1163 if(FPT_RdStack(ioport, 0) != 0x00) {
1164 if(FPT_ChkIfChipInitialized(ioport) == 0)
1167 WR_HARPOON(ioport+hp_semaphore, 0x00);
1168 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1169 FPT_DiagEEPROM(ioport);
1173 if(FPT_mbCards < MAX_MB_CARDS) {
1174 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1176 pCurrNvRam->niBaseAddr = ioport;
1177 FPT_RNVRamData(pCurrNvRam);
1179 return((int) FAILURE);
1184 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1185 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1188 pCardInfo->si_id = pCurrNvRam->niAdapId;
1190 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1191 (unsigned char)0x0FF);
1193 pCardInfo->si_lun = 0x00;
1194 pCardInfo->si_fw_revision = ORION_FW_REV;
1201 for (id = 0; id < (16/2); id++) {
1204 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1205 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1206 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1208 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1210 for (i = 0; i < 2; temp >>=8,i++) {
1219 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1220 temp6 |= 0x8000; /* Fall through */
1221 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1222 temp5 |= 0x8000; /* Fall through */
1223 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1224 temp2 |= 0x8000; /* Fall through */
1225 case AUTO_RATE_00: /* Asynchronous */
1229 if (temp & DISC_ENABLE_BIT)
1232 if (temp & WIDE_NEGO_BIT)
1238 pCardInfo->si_per_targ_init_sync = temp2;
1239 pCardInfo->si_per_targ_no_disc = temp3;
1240 pCardInfo->si_per_targ_wide_nego = temp4;
1241 pCardInfo->si_per_targ_fast_nego = temp5;
1242 pCardInfo->si_per_targ_ultra_nego = temp6;
1245 i = pCurrNvRam->niSysConf;
1247 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1250 ScamFlg = pCurrNvRam->niScamConf;
1252 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1254 pCardInfo->si_flags = 0x0000;
1257 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1260 pCardInfo->si_flags |= SOFT_RESET;
1263 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1265 if (ScamFlg & SCAM_ENABLED)
1266 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1268 if (ScamFlg & SCAM_LEVEL2)
1269 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1271 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1273 j |= SCSI_TERM_ENA_L;
1275 WR_HARPOON(ioport+hp_bm_ctrl, j );
1277 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1279 j |= SCSI_TERM_ENA_H;
1281 WR_HARPOON(ioport+hp_ee_ctrl, j );
1283 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1285 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1287 pCardInfo->si_card_family = HARPOON_FAMILY;
1288 pCardInfo->si_bustype = BUSTYPE_PCI;
1291 pCardInfo->si_card_model[0] = '9';
1292 switch(pCurrNvRam->niModel & 0x0f){
1294 pCardInfo->si_card_model[1] = '3';
1295 pCardInfo->si_card_model[2] = '0';
1298 pCardInfo->si_card_model[1] = '5';
1299 pCardInfo->si_card_model[2] = '0';
1302 pCardInfo->si_card_model[1] = '3';
1303 pCardInfo->si_card_model[2] = '2';
1306 pCardInfo->si_card_model[1] = '5';
1307 pCardInfo->si_card_model[2] = '2';
1311 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1312 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1313 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1315 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1316 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1319 if (pCardInfo->si_card_model[1] == '3')
1321 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1322 pCardInfo->si_flags |= LOW_BYTE_TERM;
1324 else if (pCardInfo->si_card_model[2] == '0')
1326 temp = RD_HARPOON(ioport+hp_xfer_pad);
1327 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1328 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1329 pCardInfo->si_flags |= LOW_BYTE_TERM;
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1331 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1332 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1333 WR_HARPOON(ioport+hp_xfer_pad, temp);
1337 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1338 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1339 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1340 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1342 for (i = 0; i < 8; i++)
1345 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1347 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1348 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1350 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1351 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1352 if (!(temp3 & BIT(7)))
1353 pCardInfo->si_flags |= LOW_BYTE_TERM;
1354 if (!(temp3 & BIT(6)))
1355 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1359 ARAM_ACCESS(ioport);
1361 for ( i = 0; i < 4; i++ ) {
1363 pCardInfo->si_XlatInfo[i] =
1364 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1367 /* return with -1 if no sort, else return with
1368 logical card number sorted by BIOS (zero-based) */
1370 pCardInfo->si_relative_cardnum =
1371 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1373 SGRAM_ACCESS(ioport);
1375 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1376 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1377 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1378 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1379 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1380 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1381 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1382 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1384 pCardInfo->si_present = 0x01;
1390 /*---------------------------------------------------------------------
1392 * Function: FlashPoint_HardwareResetHostAdapter
1394 * Description: Setup adapter for normal operation (hard reset).
1396 *---------------------------------------------------------------------*/
1398 static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1400 PSCCBcard CurrCard = NULL;
1401 PNVRamInfo pCurrNvRam;
1402 unsigned char i,j,thisCard, ScamFlg;
1403 unsigned short temp,sync_bit_map,id;
1406 ioport = pCardInfo->si_baseaddr;
1408 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1410 if (thisCard == MAX_CARDS) {
1415 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1417 CurrCard = &FPT_BL_Card[thisCard];
1418 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1422 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1424 FPT_BL_Card[thisCard].ioPort = ioport;
1425 CurrCard = &FPT_BL_Card[thisCard];
1428 for(i = 0; i < FPT_mbCards; i++){
1429 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1430 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1432 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1433 CurrCard->cardIndex = thisCard;
1434 CurrCard->cardInfo = pCardInfo;
1440 pCurrNvRam = CurrCard->pNvRamInfo;
1443 ScamFlg = pCurrNvRam->niScamConf;
1446 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1450 FPT_BusMasterInit(ioport);
1451 FPT_XbowInit(ioport, ScamFlg);
1453 FPT_autoLoadDefaultMap(ioport);
1456 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1458 WR_HARPOON(ioport+hp_selfid_0, id);
1459 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1460 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1461 CurrCard->ourId = pCardInfo->si_id;
1463 i = (unsigned char) pCardInfo->si_flags;
1464 if (i & SCSI_PARITY_ENA)
1465 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1467 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1468 if (i & LOW_BYTE_TERM)
1469 j |= SCSI_TERM_ENA_L;
1470 WR_HARPOON(ioport+hp_bm_ctrl, j);
1472 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1473 if (i & HIGH_BYTE_TERM)
1474 j |= SCSI_TERM_ENA_H;
1475 WR_HARPOON(ioport+hp_ee_ctrl, j );
1478 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1480 FPT_sresb(ioport,thisCard);
1482 FPT_scini(thisCard, pCardInfo->si_id, 0);
1487 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1488 CurrCard->globalFlags |= F_NO_FILTER;
1491 if(pCurrNvRam->niSysConf & 0x10)
1492 CurrCard->globalFlags |= F_GREEN_PC;
1495 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1496 CurrCard->globalFlags |= F_GREEN_PC;
1499 /* Set global flag to indicate Re-Negotiation to be done on all
1502 if(pCurrNvRam->niScsiConf & 0x04)
1503 CurrCard->globalFlags |= F_DO_RENEGO;
1506 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1507 CurrCard->globalFlags |= F_DO_RENEGO;
1511 if(pCurrNvRam->niScsiConf & 0x08)
1512 CurrCard->globalFlags |= F_CONLUN_IO;
1515 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1516 CurrCard->globalFlags |= F_CONLUN_IO;
1520 temp = pCardInfo->si_per_targ_no_disc;
1522 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1525 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1528 sync_bit_map = 0x0001;
1530 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1533 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1534 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1535 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1537 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1539 for (i = 0; i < 2; temp >>=8,i++) {
1541 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1543 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1547 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1548 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1549 (unsigned char)(temp & ~EE_SYNC_MASK);
1552 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1555 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1557 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1561 else { /* NARROW SCSI */
1562 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1573 WR_HARPOON((ioport+hp_semaphore),
1574 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1576 return((ULONG)CurrCard);
1579 static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
1586 PNVRamInfo pCurrNvRam;
1588 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1591 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1597 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1598 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1600 portBase = pCurrNvRam->niBaseAddr;
1602 for(i = 0; i < MAX_SCSI_TAR; i++){
1603 regOffset = hp_aramBase + 64 + i*4;
1604 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1605 scamData = *pScamTbl;
1606 WR_HARP32(portBase, regOffset, scamData);
1610 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1615 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1623 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1624 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1625 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1626 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1627 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1629 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1630 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1632 portBase = pNvRamInfo->niBaseAddr;
1634 for(i = 0; i < MAX_SCSI_TAR; i++){
1635 regOffset = hp_aramBase + 64 + i*4;
1636 RD_HARP32(portBase, regOffset, scamData);
1637 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1638 *pScamTbl = scamData;
1643 static unsigned char FPT_RdStack(ULONG portBase, unsigned char index)
1645 WR_HARPOON(portBase + hp_stack_addr, index);
1646 return(RD_HARPOON(portBase + hp_stack_data));
1649 static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data)
1651 WR_HARPOON(portBase + hp_stack_addr, index);
1652 WR_HARPOON(portBase + hp_stack_data, data);
1656 static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort)
1658 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1660 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1663 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1664 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1669 /*---------------------------------------------------------------------
1671 * Function: FlashPoint_StartCCB
1673 * Description: Start a command pointed to by p_Sccb. When the
1674 * command is completed it will be returned via the
1675 * callback function.
1677 *---------------------------------------------------------------------*/
1678 static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
1681 unsigned char thisCard, lun;
1683 CALL_BK_FN callback;
1685 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1686 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1688 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1691 p_Sccb->HostStatus = SCCB_COMPLETE;
1692 p_Sccb->SccbStatus = SCCB_ERROR;
1693 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1700 FPT_sinits(p_Sccb,thisCard);
1703 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1705 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1706 | SCCB_MGR_ACTIVE));
1708 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1710 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1711 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1715 ((PSCCBcard)pCurrCard)->cmdCounter++;
1717 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1719 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1721 if(p_Sccb->OperationCode == RESET_COMMAND)
1723 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1724 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1725 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1726 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1730 FPT_queueAddSccb(p_Sccb,thisCard);
1734 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1736 if(p_Sccb->OperationCode == RESET_COMMAND)
1738 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1739 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1740 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1741 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1745 FPT_queueAddSccb(p_Sccb,thisCard);
1751 MDISABLE_INT(ioport);
1753 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1754 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1758 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1759 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1760 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1763 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1764 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1769 if(p_Sccb->OperationCode == RESET_COMMAND)
1771 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1772 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1773 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1774 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1778 FPT_queueAddSccb(p_Sccb,thisCard);
1783 MENABLE_INT(ioport);
1789 /*---------------------------------------------------------------------
1791 * Function: FlashPoint_AbortCCB
1793 * Description: Abort the command pointed to by p_Sccb. When the
1794 * command is completed it will be returned via the
1795 * callback function.
1797 *---------------------------------------------------------------------*/
1798 static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
1802 unsigned char thisCard;
1803 CALL_BK_FN callback;
1806 PSCCBMgr_tar_info currTar_Info;
1809 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1811 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1813 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1816 if (FPT_queueFindSccb(p_Sccb,thisCard))
1819 ((PSCCBcard)pCurrCard)->cmdCounter--;
1821 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1822 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1823 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1825 p_Sccb->SccbStatus = SCCB_ABORT;
1826 callback = p_Sccb->SccbCallback;
1834 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1836 p_Sccb->SccbStatus = SCCB_ABORT;
1844 TID = p_Sccb->TargID;
1847 if(p_Sccb->Sccb_tag)
1849 MDISABLE_INT(ioport);
1850 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1852 p_Sccb->SccbStatus = SCCB_ABORT;
1853 p_Sccb->Sccb_scsistat = ABORT_ST;
1854 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1856 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1858 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1859 FPT_ssel(ioport, thisCard);
1863 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1864 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1865 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1866 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1869 MENABLE_INT(ioport);
1874 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1876 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1879 p_Sccb->SccbStatus = SCCB_ABORT;
1890 /*---------------------------------------------------------------------
1892 * Function: FlashPoint_InterruptPending
1894 * Description: Do a quick check to determine if there is a pending
1895 * interrupt for this card and disable the IRQ Pin if so.
1897 *---------------------------------------------------------------------*/
1898 static unsigned char FlashPoint_InterruptPending(ULONG pCurrCard)
1902 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1904 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1916 /*---------------------------------------------------------------------
1918 * Function: FlashPoint_HandleInterrupt
1920 * Description: This is our entry point when an interrupt is generated
1921 * by the card and the upper level driver passes it on to
1924 *---------------------------------------------------------------------*/
1925 static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
1928 unsigned char thisCard,result,bm_status, bm_int_st;
1929 unsigned short hp_int;
1930 unsigned char i, target;
1933 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1934 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1936 MDISABLE_INT(ioport);
1938 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1939 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1943 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1945 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1949 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1951 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1952 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1953 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1958 MENABLE_INT(ioport);
1964 else if (hp_int & ICMD_COMP) {
1966 if ( !(hp_int & BUS_FREE) ) {
1967 /* Wait for the BusFree before starting a new command. We
1968 must also check for being reselected since the BusFree
1969 may not show up if another device reselects us in 1.5us or
1970 less. SRR Wednesday, 3/8/1995.
1972 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1975 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1977 FPT_phaseChkFifo(ioport, thisCard);
1979 /* WRW_HARPOON((ioport+hp_intstat),
1980 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1983 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1985 FPT_autoCmdCmplt(ioport,thisCard);
1990 else if (hp_int & ITAR_DISC)
1993 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1995 FPT_phaseChkFifo(ioport, thisCard);
1999 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2001 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2002 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2004 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2007 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2008 FPT_queueDisconnect(currSCCB,thisCard);
2010 /* Wait for the BusFree before starting a new command. We
2011 must also check for being reselected since the BusFree
2012 may not show up if another device reselects us in 1.5us or
2013 less. SRR Wednesday, 3/8/1995.
2015 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2016 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2017 RD_HARPOON((ioport+hp_scsisig)) ==
2018 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2021 The additional loop exit condition above detects a timing problem
2022 with the revision D/E harpoon chips. The caller should reset the
2023 host adapter to recover when 0xFE is returned.
2025 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2027 MENABLE_INT(ioport);
2031 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2034 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2039 else if (hp_int & RSEL) {
2041 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2043 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2045 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2047 FPT_phaseChkFifo(ioport, thisCard);
2050 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2052 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2053 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2054 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2057 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2058 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2059 FPT_queueDisconnect(currSCCB,thisCard);
2062 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2063 FPT_phaseDecode(ioport,thisCard);
2068 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2071 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2072 FPT_phaseDecode(ioport,thisCard);
2077 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2079 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2080 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2082 FPT_phaseDecode(ioport,thisCard);
2086 /* Harpoon problem some SCSI target device respond to selection
2087 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2088 to latch the correct Target ID into reg. x53.
2089 The work around require to correct this reg. But when write to this
2090 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2091 need to read this reg first then restore it later. After update to 0x53 */
2093 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2094 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2095 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2096 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2097 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2098 WR_HARPOON(ioport+hp_fifowrite, i);
2099 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2103 else if (hp_int & XFER_CNT_0) {
2105 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2107 FPT_schkdd(ioport,thisCard);
2112 else if (hp_int & BUS_FREE) {
2114 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2116 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2118 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2121 FPT_phaseBusFree(ioport,thisCard);
2125 else if (hp_int & ITICKLE) {
2127 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2128 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2133 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2136 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2139 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2141 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2144 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2145 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2146 FPT_ssel(ioport,thisCard);
2155 MENABLE_INT(ioport);
2160 /*---------------------------------------------------------------------
2162 * Function: Sccb_bad_isr
2164 * Description: Some type of interrupt has occurred which is slightly
2165 * out of the ordinary. We will now decode it fully, in
2166 * this routine. This is broken up in an attempt to save
2169 *---------------------------------------------------------------------*/
2170 static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
2171 PSCCBcard pCurrCard, unsigned short p_int)
2173 unsigned char temp, ScamFlg;
2174 PSCCBMgr_tar_info currTar_Info;
2175 PNVRamInfo pCurrNvRam;
2178 if (RD_HARPOON(p_port+hp_ext_status) &
2179 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2182 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2185 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2188 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2191 WR_HARPOON(p_port+hp_pci_stat_cfg,
2192 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2194 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2198 if (pCurrCard->currentSCCB != NULL)
2201 if (!pCurrCard->currentSCCB->HostStatus)
2202 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2204 FPT_sxfrp(p_port,p_card);
2206 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2207 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2208 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2209 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2211 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2213 FPT_phaseDecode(p_port,p_card);
2219 else if (p_int & RESET)
2222 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2223 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2224 if (pCurrCard->currentSCCB != NULL) {
2226 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2228 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2232 DISABLE_AUTO(p_port);
2234 FPT_sresb(p_port,p_card);
2236 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2238 pCurrNvRam = pCurrCard->pNvRamInfo;
2240 ScamFlg = pCurrNvRam->niScamConf;
2243 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2246 FPT_XbowInit(p_port, ScamFlg);
2248 FPT_scini(p_card, pCurrCard->ourId, 0);
2254 else if (p_int & FIFO) {
2256 WRW_HARPOON((p_port+hp_intstat), FIFO);
2258 if (pCurrCard->currentSCCB != NULL)
2259 FPT_sxfrp(p_port,p_card);
2262 else if (p_int & TIMEOUT)
2265 DISABLE_AUTO(p_port);
2267 WRW_HARPOON((p_port+hp_intstat),
2268 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2270 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2273 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2274 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2275 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2276 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2278 currTar_Info->TarLUNBusy[0] = 0;
2281 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2283 currTar_Info->TarSyncCtrl = 0;
2284 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2287 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2289 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2292 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2294 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2298 else if (p_int & SCAM_SEL)
2301 FPT_scarb(p_port,LEVEL2_TAR);
2303 FPT_scasid(p_card, p_port);
2307 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2314 /*---------------------------------------------------------------------
2316 * Function: SccbMgrTableInit
2318 * Description: Initialize all Sccb manager data structures.
2320 *---------------------------------------------------------------------*/
2322 static void FPT_SccbMgrTableInitAll()
2324 unsigned char thisCard;
2326 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2328 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2330 FPT_BL_Card[thisCard].ioPort = 0x00;
2331 FPT_BL_Card[thisCard].cardInfo = NULL;
2332 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2333 FPT_BL_Card[thisCard].ourId = 0x00;
2334 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2339 /*---------------------------------------------------------------------
2341 * Function: SccbMgrTableInit
2343 * Description: Initialize all Sccb manager data structures.
2345 *---------------------------------------------------------------------*/
2347 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2349 unsigned char scsiID, qtag;
2351 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2353 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2356 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2358 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2359 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2360 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2363 pCurrCard->scanIndex = 0x00;
2364 pCurrCard->currentSCCB = NULL;
2365 pCurrCard->globalFlags = 0x00;
2366 pCurrCard->cmdCounter = 0x00;
2367 pCurrCard->tagQ_Lst = 0x01;
2368 pCurrCard->discQCount = 0;
2374 /*---------------------------------------------------------------------
2376 * Function: SccbMgrTableInit
2378 * Description: Initialize all Sccb manager data structures.
2380 *---------------------------------------------------------------------*/
2382 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2385 unsigned char lun, qtag;
2386 PSCCBMgr_tar_info currTar_Info;
2388 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2390 currTar_Info->TarSelQ_Cnt = 0;
2391 currTar_Info->TarSyncCtrl = 0;
2393 currTar_Info->TarSelQ_Head = NULL;
2394 currTar_Info->TarSelQ_Tail = NULL;
2395 currTar_Info->TarTagQ_Cnt = 0;
2396 currTar_Info->TarLUN_CA = 0;
2399 for (lun = 0; lun < MAX_LUN; lun++)
2401 currTar_Info->TarLUNBusy[lun] = 0;
2402 currTar_Info->LunDiscQ_Idx[lun] = 0;
2405 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2407 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2409 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2411 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2412 FPT_BL_Card[p_card].discQCount--;
2419 /*---------------------------------------------------------------------
2423 * Description: Read in a message byte from the SCSI bus, and check
2424 * for a parity error.
2426 *---------------------------------------------------------------------*/
2428 static unsigned char FPT_sfm(ULONG port, PSCCB pCurrSCCB)
2430 unsigned char message;
2431 unsigned short TimeOutLoop;
2434 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2435 (TimeOutLoop++ < 20000) ){}
2438 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2440 message = RD_HARPOON(port+hp_scsidata_0);
2442 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2445 if (TimeOutLoop > 20000)
2446 message = 0x00; /* force message byte = 0 if Time Out on Req */
2448 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2449 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2451 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2452 WR_HARPOON(port+hp_xferstat, 0);
2453 WR_HARPOON(port+hp_fiforead, 0);
2454 WR_HARPOON(port+hp_fifowrite, 0);
2455 if (pCurrSCCB != NULL)
2457 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2462 ACCEPT_MSG_ATN(port);
2464 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2465 (TimeOutLoop++ < 20000) ){}
2466 if (TimeOutLoop > 20000)
2468 WRW_HARPOON((port+hp_intstat), PARITY);
2471 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2473 WRW_HARPOON((port+hp_intstat), PARITY);
2476 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2478 RD_HARPOON(port+hp_scsidata_0);
2480 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2485 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2486 WR_HARPOON(port+hp_xferstat, 0);
2487 WR_HARPOON(port+hp_fiforead, 0);
2488 WR_HARPOON(port+hp_fifowrite, 0);
2493 /*---------------------------------------------------------------------
2495 * Function: FPT_ssel
2497 * Description: Load up automation and select target device.
2499 *---------------------------------------------------------------------*/
2501 static void FPT_ssel(ULONG port, unsigned char p_card)
2504 unsigned char auto_loaded, i, target, *theCCB;
2509 PSCCBMgr_tar_info currTar_Info;
2510 unsigned char lastTag, lun;
2512 CurrCard = &FPT_BL_Card[p_card];
2513 currSCCB = CurrCard->currentSCCB;
2514 target = currSCCB->TargID;
2515 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2516 lastTag = CurrCard->tagQ_Lst;
2521 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2522 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2524 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2525 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2527 lun = currSCCB->Lun;
2532 if (CurrCard->globalFlags & F_TAG_STARTED)
2534 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2536 if ((currTar_Info->TarLUN_CA == 0)
2537 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2541 if (currTar_Info->TarTagQ_Cnt !=0)
2543 currTar_Info->TarLUNBusy[lun] = 1;
2544 FPT_queueSelectFail(CurrCard,p_card);
2550 currTar_Info->TarLUNBusy[lun] = 1;
2553 } /*End non-tagged */
2556 currTar_Info->TarLUNBusy[lun] = 1;
2559 } /*!Use cmd Q Tagged */
2562 if (currTar_Info->TarLUN_CA == 1)
2564 FPT_queueSelectFail(CurrCard,p_card);
2569 currTar_Info->TarLUNBusy[lun] = 1;
2571 } /*else use cmd Q tagged */
2573 } /*if glob tagged started */
2576 currTar_Info->TarLUNBusy[lun] = 1;
2581 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2582 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2583 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2585 if(CurrCard->discQCount >= QUEUE_DEPTH)
2587 currTar_Info->TarLUNBusy[lun] = 1;
2588 FPT_queueSelectFail(CurrCard,p_card);
2592 for (i = 1; i < QUEUE_DEPTH; i++)
2594 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2595 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2597 CurrCard->tagQ_Lst = lastTag;
2598 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2599 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2600 CurrCard->discQCount++;
2604 if(i == QUEUE_DEPTH)
2606 currTar_Info->TarLUNBusy[lun] = 1;
2607 FPT_queueSelectFail(CurrCard,p_card);
2617 WR_HARPOON(port+hp_select_id, target);
2618 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2620 if (currSCCB->OperationCode == RESET_COMMAND) {
2621 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2622 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2624 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2626 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2628 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2630 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2632 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2634 currTar_Info->TarSyncCtrl = 0;
2635 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2638 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2640 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2643 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2644 FPT_SccbMgrTableInitTarget(p_card, target);
2648 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2650 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2651 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2653 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2655 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2656 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2657 >> 6) | (unsigned char)0x20)));
2658 WRW_HARPOON((port+SYNC_MSGS+2),
2659 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2660 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2662 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2667 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2668 auto_loaded = FPT_siwidn(port,p_card);
2669 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2672 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2673 == SYNC_SUPPORTED)) {
2674 auto_loaded = FPT_sisyncn(port,p_card, 0);
2675 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2682 if (currSCCB->ControlByte & F_USE_CMD_Q)
2685 CurrCard->globalFlags |= F_TAG_STARTED;
2687 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2690 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2692 /* Fix up the start instruction with a jump to
2693 Non-Tag-CMD handling */
2694 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2696 WRW_HARPOON((port+NON_TAG_ID_MSG),
2697 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2699 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2701 /* Setup our STATE so we know what happend when
2702 the wheels fall off. */
2703 currSCCB->Sccb_scsistat = SELECT_ST;
2705 currTar_Info->TarLUNBusy[lun] = 1;
2710 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2712 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2713 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2714 >> 6) | (unsigned char)0x20)));
2716 for (i = 1; i < QUEUE_DEPTH; i++)
2718 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2719 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2721 WRW_HARPOON((port+ID_MSG_STRT+6),
2722 (MPM_OP+AMSG_OUT+lastTag));
2723 CurrCard->tagQ_Lst = lastTag;
2724 currSCCB->Sccb_tag = lastTag;
2725 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2726 CurrCard->discQCount++;
2732 if ( i == QUEUE_DEPTH )
2734 currTar_Info->TarLUNBusy[lun] = 1;
2735 FPT_queueSelectFail(CurrCard,p_card);
2740 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2742 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2749 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2751 WRW_HARPOON((port+NON_TAG_ID_MSG),
2752 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2754 currSCCB->Sccb_scsistat = SELECT_ST;
2756 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2760 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2762 cdb_reg = port + CMD_STRT;
2764 for (i=0; i < currSCCB->CdbLength; i++)
2766 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2771 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2772 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2776 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2777 WR_HARPOON(port+hp_xferstat, 0x00);
2779 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2781 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2784 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2786 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2791 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2792 auto_loaded |= AUTO_IMMED; */
2793 auto_loaded = AUTO_IMMED;
2797 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2804 /*---------------------------------------------------------------------
2806 * Function: FPT_sres
2808 * Description: Hookup the correct CCB and handle the incoming messages.
2810 *---------------------------------------------------------------------*/
2812 static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard)
2815 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2818 PSCCBMgr_tar_info currTar_Info;
2824 if(pCurrCard->currentSCCB != NULL)
2826 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2830 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2833 currSCCB = pCurrCard->currentSCCB;
2834 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2836 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2837 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2839 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2841 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2842 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2844 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2845 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2847 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2848 if(currSCCB->Sccb_scsistat != ABORT_ST)
2850 pCurrCard->discQCount--;
2851 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2857 currTar_Info->TarLUNBusy[0] = 0;
2858 if(currSCCB->Sccb_tag)
2860 if(currSCCB->Sccb_scsistat != ABORT_ST)
2862 pCurrCard->discQCount--;
2863 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2867 if(currSCCB->Sccb_scsistat != ABORT_ST)
2869 pCurrCard->discQCount--;
2870 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2875 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2878 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2881 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2882 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2889 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2893 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2895 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2898 WRW_HARPOON((port+hp_intstat), PHASE);
2903 WRW_HARPOON((port+hp_intstat), PHASE);
2904 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2907 message = FPT_sfm(port,pCurrCard->currentSCCB);
2911 if (message <= (0x80 | LUN_MASK))
2913 lun = message & (unsigned char)LUN_MASK;
2915 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2917 if (currTar_Info->TarTagQ_Cnt != 0)
2920 if (!(currTar_Info->TarLUN_CA))
2922 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2925 message = FPT_sfm(port,pCurrCard->currentSCCB);
2936 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2944 } /*End Q cnt != 0 */
2946 } /*End Tag cmds supported! */
2948 } /*End valid ID message. */
2953 ACCEPT_MSG_ATN(port);
2956 } /* End good id message. */
2966 ACCEPT_MSG_ATN(port);
2968 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2969 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2970 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2978 if(msgRetryCount == 1)
2980 FPT_SendMsg(port, SMPARITY);
2984 FPT_SendMsg(port, SMDEV_RESET);
2986 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2988 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2991 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2995 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2998 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
3002 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3003 FPT_SccbMgrTableInitTarget(p_card,our_target);
3007 }while(message == 0);
3011 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3012 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3014 currTar_Info->TarLUNBusy[lun] = 1;
3015 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3016 if(pCurrCard->currentSCCB != NULL)
3022 ACCEPT_MSG_ATN(port);
3027 currTar_Info->TarLUNBusy[0] = 1;
3032 if (pCurrCard->discQ_Tbl[tag] != NULL)
3034 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3035 currTar_Info->TarTagQ_Cnt--;
3040 ACCEPT_MSG_ATN(port);
3044 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3045 if(pCurrCard->currentSCCB != NULL)
3051 ACCEPT_MSG_ATN(port);
3056 if(pCurrCard->currentSCCB != NULL)
3058 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3060 /* During Abort Tag command, the target could have got re-selected
3061 and completed the command. Check the select Q and remove the CCB
3062 if it is in the Select Q */
3063 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3068 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3069 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3070 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3073 static void FPT_SendMsg(ULONG port, unsigned char message)
3075 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3077 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3080 WRW_HARPOON((port+hp_intstat), PHASE);
3085 WRW_HARPOON((port+hp_intstat), PHASE);
3086 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3088 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3091 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3093 WR_HARPOON(port+hp_scsidata_0,message);
3095 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3099 WR_HARPOON(port+hp_portctrl_0, 0x00);
3101 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3102 (message == SMABORT_TAG) )
3104 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3106 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3108 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3114 /*---------------------------------------------------------------------
3116 * Function: FPT_sdecm
3118 * Description: Determine the proper responce to the message from the
3121 *---------------------------------------------------------------------*/
3122 static void FPT_sdecm(unsigned char message, ULONG port, unsigned char p_card)
3126 PSCCBMgr_tar_info currTar_Info;
3128 CurrCard = &FPT_BL_Card[p_card];
3129 currSCCB = CurrCard->currentSCCB;
3131 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3133 if (message == SMREST_DATA_PTR)
3135 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3137 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3139 FPT_hostDataXferRestart(currSCCB);
3143 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3146 else if (message == SMCMD_COMP)
3150 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3152 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3153 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3160 else if ((message == SMNO_OP) || (message >= SMIDENT)
3161 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3165 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3168 else if (message == SMREJECT)
3171 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3172 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3173 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3174 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3177 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3182 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3183 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3185 if(currSCCB->Lun == 0x00)
3187 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3190 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3192 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3195 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3199 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3200 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3202 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3206 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3208 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3209 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3212 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3213 CurrCard->discQCount--;
3214 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3215 currSCCB->Sccb_tag = 0x00;
3220 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3224 if(currSCCB->Lun == 0x00)
3226 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3227 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3234 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3235 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3236 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3238 currTar_Info->TarLUNBusy[0] = 1;
3241 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3243 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3252 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3253 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3255 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3257 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3262 else if (message == SMEXT)
3266 FPT_shandem(port,p_card,currSCCB);
3269 else if (message == SMIGNORWR)
3272 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3274 message = FPT_sfm(port,currSCCB);
3276 if(currSCCB->Sccb_scsimsg != SMPARITY)
3278 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3285 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3286 currSCCB->Sccb_scsimsg = SMREJECT;
3288 ACCEPT_MSG_ATN(port);
3289 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3294 /*---------------------------------------------------------------------
3296 * Function: FPT_shandem
3298 * Description: Decide what to do with the extended message.
3300 *---------------------------------------------------------------------*/
3301 static void FPT_shandem(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
3303 unsigned char length,message;
3305 length = FPT_sfm(port,pCurrSCCB);
3310 message = FPT_sfm(port,pCurrSCCB);
3314 if (message == SMSYNC)
3321 FPT_stsyncn(port,p_card);
3326 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3327 ACCEPT_MSG_ATN(port);
3330 else if (message == SMWDTR)
3337 FPT_stwidn(port,p_card);
3342 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3343 ACCEPT_MSG_ATN(port);
3345 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3351 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3352 ACCEPT_MSG_ATN(port);
3354 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3359 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3361 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3365 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3366 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3371 /*---------------------------------------------------------------------
3373 * Function: FPT_sisyncn
3375 * Description: Read in a message byte from the SCSI bus, and check
3376 * for a parity error.
3378 *---------------------------------------------------------------------*/
3380 static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag)
3383 PSCCBMgr_tar_info currTar_Info;
3385 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3386 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3388 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3391 WRW_HARPOON((port+ID_MSG_STRT),
3392 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3394 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3396 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3397 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3398 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3401 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3403 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3405 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3407 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3409 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3411 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3414 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3417 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3418 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3419 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3424 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3425 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3426 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3430 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3439 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3440 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3447 /*---------------------------------------------------------------------
3449 * Function: FPT_stsyncn
3451 * Description: The has sent us a Sync Nego message so handle it as
3454 *---------------------------------------------------------------------*/
3455 static void FPT_stsyncn(ULONG port, unsigned char p_card)
3457 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3459 PSCCBMgr_tar_info currTar_Info;
3461 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3462 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3464 sync_msg = FPT_sfm(port,currSCCB);
3466 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3468 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3475 offset = FPT_sfm(port,currSCCB);
3477 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3479 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3483 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3485 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3487 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3489 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3491 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3493 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3496 our_sync_msg = 0; /* Message = Async */
3498 if (sync_msg < our_sync_msg) {
3499 sync_msg = our_sync_msg; /*if faster, then set to max. */
3502 if (offset == ASYNC)
3505 if (offset > MAX_OFFSET)
3506 offset = MAX_OFFSET;
3512 sync_reg = 0x20; /* Use 10MB/s */
3516 sync_reg = 0x40; /* Use 6.6MB/s */
3520 sync_reg = 0x60; /* Use 5MB/s */
3524 sync_reg = 0x80; /* Use 4MB/s */
3528 sync_reg = 0xA0; /* Use 3.33MB/s */
3532 sync_reg = 0xC0; /* Use 2.85MB/s */
3536 sync_reg = 0xE0; /* Use 2.5MB/s */
3538 if (sync_msg > 100) {
3540 sync_reg = 0x00; /* Use ASYNC */
3545 if (currTar_Info->TarStatus & WIDE_ENABLED)
3551 sync_reg |= (offset | NARROW_SCSI);
3553 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3556 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3561 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3562 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3564 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3570 ACCEPT_MSG_ATN(port);
3572 FPT_sisyncr(port,sync_msg,offset);
3574 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3575 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3580 /*---------------------------------------------------------------------
3582 * Function: FPT_sisyncr
3584 * Description: Answer the targets sync message.
3586 *---------------------------------------------------------------------*/
3587 static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset)
3590 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3591 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3592 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3593 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3594 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3595 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3596 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3599 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3600 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3602 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3604 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3609 /*---------------------------------------------------------------------
3611 * Function: FPT_siwidn
3613 * Description: Read in a message byte from the SCSI bus, and check
3614 * for a parity error.
3616 *---------------------------------------------------------------------*/
3618 static unsigned char FPT_siwidn(ULONG port, unsigned char p_card)
3621 PSCCBMgr_tar_info currTar_Info;
3623 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3624 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3626 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3629 WRW_HARPOON((port+ID_MSG_STRT),
3630 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3632 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3634 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3635 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3636 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3637 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3638 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3639 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3641 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3644 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3645 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3652 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3653 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3655 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3662 /*---------------------------------------------------------------------
3664 * Function: FPT_stwidn
3666 * Description: The has sent us a Wide Nego message so handle it as
3669 *---------------------------------------------------------------------*/
3670 static void FPT_stwidn(ULONG port, unsigned char p_card)
3672 unsigned char width;
3674 PSCCBMgr_tar_info currTar_Info;
3676 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3677 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3679 width = FPT_sfm(port,currSCCB);
3681 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3683 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3688 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3692 currTar_Info->TarStatus |= WIDE_ENABLED;
3696 width = NARROW_SCSI;
3697 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3701 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3704 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3709 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3711 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3713 ACCEPT_MSG_ATN(port);
3715 FPT_sisyncn(port,p_card, 1);
3716 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3722 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3729 ACCEPT_MSG_ATN(port);
3731 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3736 FPT_siwidr(port,width);
3738 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3743 /*---------------------------------------------------------------------
3745 * Function: FPT_siwidr
3747 * Description: Answer the targets Wide nego message.
3749 *---------------------------------------------------------------------*/
3750 static void FPT_siwidr(ULONG port, unsigned char width)
3753 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3754 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3755 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3756 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3757 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3758 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3761 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3762 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3764 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3766 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3771 /*---------------------------------------------------------------------
3773 * Function: FPT_sssyncv
3775 * Description: Write the desired value to the Sync Register for the
3778 *---------------------------------------------------------------------*/
3779 static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
3780 PSCCBMgr_tar_info currTar_Info)
3782 unsigned char index;
3789 index = 12; /* hp_synctarg_0 */
3792 index = 13; /* hp_synctarg_1 */
3795 index = 14; /* hp_synctarg_2 */
3798 index = 15; /* hp_synctarg_3 */
3801 index = 8; /* hp_synctarg_4 */
3804 index = 9; /* hp_synctarg_5 */
3807 index = 10; /* hp_synctarg_6 */
3810 index = 11; /* hp_synctarg_7 */
3813 index = 4; /* hp_synctarg_8 */
3816 index = 5; /* hp_synctarg_9 */
3819 index = 6; /* hp_synctarg_10 */
3822 index = 7; /* hp_synctarg_11 */
3825 index = 0; /* hp_synctarg_12 */
3828 index = 1; /* hp_synctarg_13 */
3831 index = 2; /* hp_synctarg_14 */
3834 index = 3; /* hp_synctarg_15 */
3838 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3840 currTar_Info->TarSyncCtrl = p_sync_value;
3844 /*---------------------------------------------------------------------
3846 * Function: FPT_sresb
3848 * Description: Reset the desired card's SCSI bus.
3850 *---------------------------------------------------------------------*/
3851 static void FPT_sresb(ULONG port, unsigned char p_card)
3853 unsigned char scsiID, i;
3855 PSCCBMgr_tar_info currTar_Info;
3857 WR_HARPOON(port+hp_page_ctrl,
3858 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3859 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3861 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3863 scsiID = RD_HARPOON(port+hp_seltimeout);
3864 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3865 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3867 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3869 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3871 WR_HARPOON(port+hp_seltimeout,scsiID);
3873 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3875 FPT_Wait(port, TO_5ms);
3877 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3879 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3881 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3883 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3885 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3887 currTar_Info->TarSyncCtrl = 0;
3888 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3891 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3893 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3896 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3898 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3901 FPT_BL_Card[p_card].scanIndex = 0x00;
3902 FPT_BL_Card[p_card].currentSCCB = NULL;
3903 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3905 FPT_BL_Card[p_card].cmdCounter = 0x00;
3906 FPT_BL_Card[p_card].discQCount = 0x00;
3907 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3909 for(i = 0; i < QUEUE_DEPTH; i++)
3910 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3912 WR_HARPOON(port+hp_page_ctrl,
3913 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3917 /*---------------------------------------------------------------------
3919 * Function: FPT_ssenss
3921 * Description: Setup for the Auto Sense command.
3923 *---------------------------------------------------------------------*/
3924 static void FPT_ssenss(PSCCBcard pCurrCard)
3929 currSCCB = pCurrCard->currentSCCB;
3932 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3934 for (i = 0; i < 6; i++) {
3936 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3939 currSCCB->CdbLength = SIX_BYTE_CMD;
3940 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3941 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3942 currSCCB->Cdb[2] = 0x00;
3943 currSCCB->Cdb[3] = 0x00;
3944 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3945 currSCCB->Cdb[5] = 0x00;
3947 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3949 currSCCB->Sccb_ATC = 0x00;
3951 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3953 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3955 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3957 currSCCB->ControlByte = 0x00;
3959 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3964 /*---------------------------------------------------------------------
3966 * Function: FPT_sxfrp
3968 * Description: Transfer data into the bit bucket until the device
3969 * decides to switch phase.
3971 *---------------------------------------------------------------------*/
3973 static void FPT_sxfrp(ULONG p_port, unsigned char p_card)
3975 unsigned char curr_phz;
3978 DISABLE_AUTO(p_port);
3980 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3982 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3986 /* If the Automation handled the end of the transfer then do not
3987 match the phase or we will get out of sync with the ISR. */
3989 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3992 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3994 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3996 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3999 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4001 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4002 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
4004 if (curr_phz & (unsigned char)SCSI_IOBIT)
4006 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4008 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4010 RD_HARPOON(p_port+hp_fifodata_0);
4015 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4016 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4018 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4021 } /* End of While loop for padding data I/O phase */
4023 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4025 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4029 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4030 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4032 RD_HARPOON(p_port+hp_fifodata_0);
4035 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4037 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4038 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4040 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4041 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4046 /*---------------------------------------------------------------------
4048 * Function: FPT_schkdd
4050 * Description: Make sure data has been flushed from both FIFOs and abort
4051 * the operations if necessary.
4053 *---------------------------------------------------------------------*/
4055 static void FPT_schkdd(ULONG port, unsigned char p_card)
4057 unsigned short TimeOutLoop;
4058 unsigned char sPhase;
4062 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4065 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4066 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4072 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4075 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4077 currSCCB->Sccb_XferCnt = 1;
4079 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4080 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4081 WR_HARPOON(port+hp_xferstat, 0x00);
4087 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4089 currSCCB->Sccb_XferCnt = 0;
4092 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4093 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4095 currSCCB->HostStatus = SCCB_PARITY_ERR;
4096 WRW_HARPOON((port+hp_intstat), PARITY);
4100 FPT_hostDataXferAbort(port,p_card,currSCCB);
4103 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4107 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4109 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4112 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4115 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4118 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4122 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4123 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4124 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4125 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4126 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4129 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4131 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4133 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4134 FPT_phaseDataIn(port,p_card);
4138 FPT_phaseDataOut(port,p_card);
4143 FPT_sxfrp(port,p_card);
4144 if (!(RDW_HARPOON((port+hp_intstat)) &
4145 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4147 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4148 FPT_phaseDecode(port,p_card);
4155 WR_HARPOON(port+hp_portctrl_0, 0x00);
4160 /*---------------------------------------------------------------------
4162 * Function: FPT_sinits
4164 * Description: Setup SCCB manager fields in this SCCB.
4166 *---------------------------------------------------------------------*/
4168 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
4170 PSCCBMgr_tar_info currTar_Info;
4172 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4176 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4178 p_sccb->Sccb_XferState = 0x00;
4179 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4181 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4182 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4184 p_sccb->Sccb_SGoffset = 0;
4185 p_sccb->Sccb_XferState = F_SG_XFER;
4186 p_sccb->Sccb_XferCnt = 0x00;
4189 if (p_sccb->DataLength == 0x00)
4191 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4193 if (p_sccb->ControlByte & F_USE_CMD_Q)
4195 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4196 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4199 currTar_Info->TarStatus |= TAG_Q_TRYING;
4202 /* For !single SCSI device in system & device allow Disconnect
4203 or command is tag_q type then send Cmd with Disconnect Enable
4204 else send Cmd with Disconnect Disable */
4207 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4208 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4209 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4211 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4212 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4213 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4218 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4221 p_sccb->HostStatus = 0x00;
4222 p_sccb->TargetStatus = 0x00;
4223 p_sccb->Sccb_tag = 0x00;
4224 p_sccb->Sccb_MGRFlags = 0x00;
4225 p_sccb->Sccb_sgseg = 0x00;
4226 p_sccb->Sccb_ATC = 0x00;
4227 p_sccb->Sccb_savedATC = 0x00;
4229 p_sccb->SccbVirtDataPtr = 0x00;
4230 p_sccb->Sccb_forwardlink = NULL;
4231 p_sccb->Sccb_backlink = NULL;
4233 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4234 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4235 p_sccb->Sccb_scsimsg = SMNO_OP;
4240 /*---------------------------------------------------------------------
4242 * Function: Phase Decode
4244 * Description: Determine the phase and call the appropriate function.
4246 *---------------------------------------------------------------------*/
4248 static void FPT_phaseDecode(ULONG p_port, unsigned char p_card)
4250 unsigned char phase_ref;
4251 void (*phase) (ULONG, unsigned char);
4254 DISABLE_AUTO(p_port);
4256 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4258 phase = FPT_s_PhaseTbl[phase_ref];
4260 (*phase)(p_port, p_card); /* Call the correct phase func */
4265 /*---------------------------------------------------------------------
4267 * Function: Data Out Phase
4269 * Description: Start up both the BusMaster and Xbow.
4271 *---------------------------------------------------------------------*/
4273 static void FPT_phaseDataOut(ULONG port, unsigned char p_card)
4278 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4279 if (currSCCB == NULL)
4281 return; /* Exit if No SCCB record */
4284 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4285 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4287 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4289 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4291 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4293 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4295 if (currSCCB->Sccb_XferCnt == 0) {
4298 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4299 (currSCCB->HostStatus == SCCB_COMPLETE))
4300 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4302 FPT_sxfrp(port,p_card);
4303 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4304 FPT_phaseDecode(port,p_card);
4309 /*---------------------------------------------------------------------
4311 * Function: Data In Phase
4313 * Description: Startup the BusMaster and the XBOW.
4315 *---------------------------------------------------------------------*/
4317 static void FPT_phaseDataIn(ULONG port, unsigned char p_card)
4322 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4324 if (currSCCB == NULL)
4326 return; /* Exit if No SCCB record */
4330 currSCCB->Sccb_scsistat = DATA_IN_ST;
4331 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4332 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4334 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4336 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4338 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4340 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4342 if (currSCCB->Sccb_XferCnt == 0) {
4345 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4346 (currSCCB->HostStatus == SCCB_COMPLETE))
4347 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4349 FPT_sxfrp(port,p_card);
4350 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4351 FPT_phaseDecode(port,p_card);
4356 /*---------------------------------------------------------------------
4358 * Function: Command Phase
4360 * Description: Load the CDB into the automation and start it up.
4362 *---------------------------------------------------------------------*/
4364 static void FPT_phaseCommand(ULONG p_port, unsigned char p_card)
4370 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4372 if (currSCCB->OperationCode == RESET_COMMAND) {
4374 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4375 currSCCB->CdbLength = SIX_BYTE_CMD;
4378 WR_HARPOON(p_port+hp_scsisig, 0x00);
4380 ARAM_ACCESS(p_port);
4383 cdb_reg = p_port + CMD_STRT;
4385 for (i=0; i < currSCCB->CdbLength; i++) {
4387 if (currSCCB->OperationCode == RESET_COMMAND)
4389 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4392 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4396 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4397 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4399 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4401 currSCCB->Sccb_scsistat = COMMAND_ST;
4403 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4404 SGRAM_ACCESS(p_port);
4408 /*---------------------------------------------------------------------
4410 * Function: Status phase
4412 * Description: Bring in the status and command complete message bytes
4414 *---------------------------------------------------------------------*/
4416 static void FPT_phaseStatus(ULONG port, unsigned char p_card)
4418 /* Start-up the automation to finish off this command and let the
4419 isr handle the interrupt for command complete when it comes in.
4420 We could wait here for the interrupt to be generated?
4423 WR_HARPOON(port+hp_scsisig, 0x00);
4425 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4429 /*---------------------------------------------------------------------
4431 * Function: Phase Message Out
4433 * Description: Send out our message (if we have one) and handle whatever
4436 *---------------------------------------------------------------------*/
4438 static void FPT_phaseMsgOut(ULONG port, unsigned char p_card)
4440 unsigned char message,scsiID;
4442 PSCCBMgr_tar_info currTar_Info;
4444 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4446 if (currSCCB != NULL) {
4448 message = currSCCB->Sccb_scsimsg;
4449 scsiID = currSCCB->TargID;
4451 if (message == SMDEV_RESET)
4455 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4456 currTar_Info->TarSyncCtrl = 0;
4457 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4459 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4462 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4466 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4469 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4473 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4474 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4476 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4478 currSCCB->HostStatus = SCCB_COMPLETE;
4479 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4481 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4482 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4487 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4491 if(message == SMNO_OP)
4493 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4495 FPT_ssel(port,p_card);
4503 if (message == SMABORT)
4505 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4514 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4517 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4519 WR_HARPOON(port+hp_scsidata_0,message);
4521 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4525 WR_HARPOON(port+hp_portctrl_0, 0x00);
4527 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4528 (message == SMABORT_TAG) )
4531 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4533 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4535 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4537 if (currSCCB != NULL)
4540 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4541 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4542 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4544 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4546 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4551 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4558 FPT_sxfrp(port,p_card);
4565 if(message == SMPARITY)
4567 currSCCB->Sccb_scsimsg = SMNO_OP;
4568 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4572 FPT_sxfrp(port,p_card);
4578 /*---------------------------------------------------------------------
4580 * Function: Message In phase
4582 * Description: Bring in the message and determine what to do with it.
4584 *---------------------------------------------------------------------*/
4586 static void FPT_phaseMsgIn(ULONG port, unsigned char p_card)
4588 unsigned char message;
4591 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4593 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4596 FPT_phaseChkFifo(port, p_card);
4599 message = RD_HARPOON(port+hp_scsidata_0);
4600 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4603 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4610 message = FPT_sfm(port,currSCCB);
4615 FPT_sdecm(message,port,p_card);
4620 if(currSCCB->Sccb_scsimsg != SMPARITY)
4622 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4629 /*---------------------------------------------------------------------
4631 * Function: Illegal phase
4633 * Description: Target switched to some illegal phase, so all we can do
4634 * is report an error back to the host (if that is possible)
4635 * and send an ABORT message to the misbehaving target.
4637 *---------------------------------------------------------------------*/
4639 static void FPT_phaseIllegal(ULONG port, unsigned char p_card)
4643 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4645 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4646 if (currSCCB != NULL) {
4648 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4649 currSCCB->Sccb_scsistat = ABORT_ST;
4650 currSCCB->Sccb_scsimsg = SMABORT;
4653 ACCEPT_MSG_ATN(port);
4658 /*---------------------------------------------------------------------
4660 * Function: Phase Check FIFO
4662 * Description: Make sure data has been flushed from both FIFOs and abort
4663 * the operations if necessary.
4665 *---------------------------------------------------------------------*/
4667 static void FPT_phaseChkFifo(ULONG port, unsigned char p_card)
4672 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4674 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4677 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4678 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4681 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4683 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4685 currSCCB->Sccb_XferCnt = 0;
4687 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4688 (currSCCB->HostStatus == SCCB_COMPLETE))
4690 currSCCB->HostStatus = SCCB_PARITY_ERR;
4691 WRW_HARPOON((port+hp_intstat), PARITY);
4694 FPT_hostDataXferAbort(port,p_card,currSCCB);
4696 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4698 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4699 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4702 } /*End Data In specific code. */
4706 GET_XFER_CNT(port,xfercnt);
4709 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4712 WR_HARPOON(port+hp_portctrl_0, 0x00);
4714 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4716 currSCCB->Sccb_XferCnt = xfercnt;
4718 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4719 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4721 currSCCB->HostStatus = SCCB_PARITY_ERR;
4722 WRW_HARPOON((port+hp_intstat), PARITY);
4726 FPT_hostDataXferAbort(port,p_card,currSCCB);
4729 WR_HARPOON(port+hp_fifowrite, 0x00);
4730 WR_HARPOON(port+hp_fiforead, 0x00);
4731 WR_HARPOON(port+hp_xferstat, 0x00);
4733 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4737 /*---------------------------------------------------------------------
4739 * Function: Phase Bus Free
4741 * Description: We just went bus free so figure out if it was
4742 * because of command complete or from a disconnect.
4744 *---------------------------------------------------------------------*/
4745 static void FPT_phaseBusFree(ULONG port, unsigned char p_card)
4749 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4751 if (currSCCB != NULL)
4757 if (currSCCB->OperationCode == RESET_COMMAND)
4760 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4761 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4762 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4766 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4768 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4772 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4774 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4775 (unsigned char)SYNC_SUPPORTED;
4776 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4779 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4781 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4782 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4783 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4785 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4788 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4790 /* Make sure this is not a phony BUS_FREE. If we were
4791 reselected or if BUSY is NOT on then this is a
4792 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4794 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4795 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4797 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4798 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4810 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4812 if (!currSCCB->HostStatus)
4814 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4817 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4818 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4819 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4821 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4823 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4828 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4830 } /*end if !=null */
4836 /*---------------------------------------------------------------------
4838 * Function: Auto Load Default Map
4840 * Description: Load the Automation RAM with the defualt map values.
4842 *---------------------------------------------------------------------*/
4843 static void FPT_autoLoadDefaultMap(ULONG p_port)
4847 ARAM_ACCESS(p_port);
4848 map_addr = p_port + hp_aramBase;
4850 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4852 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4854 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4856 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4874 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4876 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4878 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4880 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4882 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4884 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4885 map_addr +=2; /*This means AYNC DATA IN */
4886 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4888 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4890 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4892 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4894 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4896 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4898 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4900 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4902 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4904 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4906 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4908 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4910 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4912 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4914 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4916 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4918 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4920 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4929 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4930 map_addr +=2; /* DIDN'T GET ONE */
4931 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4933 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4935 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4939 SGRAM_ACCESS(p_port);
4942 /*---------------------------------------------------------------------
4944 * Function: Auto Command Complete
4946 * Description: Post command back to host and find another command
4949 *---------------------------------------------------------------------*/
4951 static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card)
4954 unsigned char status_byte;
4956 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4958 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4960 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4962 if (status_byte != SSGOOD) {
4964 if (status_byte == SSQ_FULL) {
4967 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4968 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4970 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4971 if(FPT_BL_Card[p_card].discQCount != 0)
4972 FPT_BL_Card[p_card].discQCount--;
4973 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4977 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4978 if(currSCCB->Sccb_tag)
4980 if(FPT_BL_Card[p_card].discQCount != 0)
4981 FPT_BL_Card[p_card].discQCount--;
4982 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4985 if(FPT_BL_Card[p_card].discQCount != 0)
4986 FPT_BL_Card[p_card].discQCount--;
4987 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4991 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4993 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4998 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5000 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
5001 (unsigned char)SYNC_SUPPORTED;
5003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5004 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5006 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5007 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5009 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5010 if(FPT_BL_Card[p_card].discQCount != 0)
5011 FPT_BL_Card[p_card].discQCount--;
5012 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5016 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5017 if(currSCCB->Sccb_tag)
5019 if(FPT_BL_Card[p_card].discQCount != 0)
5020 FPT_BL_Card[p_card].discQCount--;
5021 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5024 if(FPT_BL_Card[p_card].discQCount != 0)
5025 FPT_BL_Card[p_card].discQCount--;
5026 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5033 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5036 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5037 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5038 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5040 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5041 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5043 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5044 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5046 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5047 if(FPT_BL_Card[p_card].discQCount != 0)
5048 FPT_BL_Card[p_card].discQCount--;
5049 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5053 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5054 if(currSCCB->Sccb_tag)
5056 if(FPT_BL_Card[p_card].discQCount != 0)
5057 FPT_BL_Card[p_card].discQCount--;
5058 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5061 if(FPT_BL_Card[p_card].discQCount != 0)
5062 FPT_BL_Card[p_card].discQCount--;
5063 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5070 if (status_byte == SSCHECK)
5072 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5074 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5076 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5078 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5080 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5085 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5087 currSCCB->SccbStatus = SCCB_ERROR;
5088 currSCCB->TargetStatus = status_byte;
5090 if (status_byte == SSCHECK) {
5092 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5096 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5098 if (currSCCB->RequestSenseLength == 0)
5099 currSCCB->RequestSenseLength = 14;
5101 FPT_ssenss(&FPT_BL_Card[p_card]);
5102 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5104 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5105 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5107 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5108 if(FPT_BL_Card[p_card].discQCount != 0)
5109 FPT_BL_Card[p_card].discQCount--;
5110 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5114 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5115 if(currSCCB->Sccb_tag)
5117 if(FPT_BL_Card[p_card].discQCount != 0)
5118 FPT_BL_Card[p_card].discQCount--;
5119 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5122 if(FPT_BL_Card[p_card].discQCount != 0)
5123 FPT_BL_Card[p_card].discQCount--;
5124 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5134 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5135 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5136 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5138 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5141 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5144 #define SHORT_WAIT 0x0000000F
5145 #define LONG_WAIT 0x0000FFFFL
5148 /*---------------------------------------------------------------------
5150 * Function: Data Transfer Processor
5152 * Description: This routine performs two tasks.
5153 * (1) Start data transfer by calling HOST_DATA_XFER_START
5154 * function. Once data transfer is started, (2) Depends
5155 * on the type of data transfer mode Scatter/Gather mode
5156 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5157 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5158 * data transfer done. In Scatter/Gather mode, this routine
5159 * checks bus master command complete and dual rank busy
5160 * bit to keep chaining SC transfer command. Similarly,
5161 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5162 * (F_HOST_XFER_ACT bit) for data transfer done.
5164 *---------------------------------------------------------------------*/
5166 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
5170 currSCCB = pCurrCard->currentSCCB;
5172 if (currSCCB->Sccb_XferState & F_SG_XFER)
5174 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5177 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5178 currSCCB->Sccb_SGoffset = 0x00;
5180 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5182 FPT_busMstrSGDataXferStart(port, currSCCB);
5187 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5189 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5191 FPT_busMstrDataXferStart(port, currSCCB);
5197 /*---------------------------------------------------------------------
5199 * Function: BusMaster Scatter Gather Data Transfer Start
5203 *---------------------------------------------------------------------*/
5204 static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5206 ULONG count,addr,tmpSGCnt;
5207 unsigned int sg_index;
5208 unsigned char sg_count, i;
5212 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5214 count = ((ULONG) HOST_RD_CMD)<<24;
5218 count = ((ULONG) HOST_WRT_CMD)<<24;
5223 sg_index = pcurrSCCB->Sccb_sgseg;
5224 reg_offset = hp_aramBase;
5227 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5230 WR_HARPOON(p_port+hp_page_ctrl, i);
5232 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5233 ((ULONG)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5235 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5238 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5241 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5242 ((sg_index * 2) + 1));
5245 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5247 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5248 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5250 tmpSGCnt = count & 0x00FFFFFFL;
5253 WR_HARP32(p_port,reg_offset,addr);
5256 WR_HARP32(p_port,reg_offset,count);
5259 count &= 0xFF000000L;
5265 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5267 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5269 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5271 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5274 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5275 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5281 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5282 (tmpSGCnt & 0x000000001))
5285 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5290 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5292 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5293 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5297 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5302 /*---------------------------------------------------------------------
5304 * Function: BusMaster Data Transfer Start
5308 *---------------------------------------------------------------------*/
5309 static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5313 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5315 count = pcurrSCCB->Sccb_XferCnt;
5317 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5321 addr = pcurrSCCB->SensePointer;
5322 count = pcurrSCCB->RequestSenseLength;
5326 HP_SETUP_ADDR_CNT(p_port,addr,count);
5329 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5331 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5332 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5334 WR_HARPOON(p_port+hp_xfer_cmd,
5335 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5340 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5341 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5343 WR_HARPOON(p_port+hp_xfer_cmd,
5344 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5350 /*---------------------------------------------------------------------
5352 * Function: BusMaster Timeout Handler
5354 * Description: This function is called after a bus master command busy time
5355 * out is detected. This routines issue halt state machine
5356 * with a software time out for command busy. If command busy
5357 * is still asserted at the end of the time out, it issues
5358 * hard abort with another software time out. It hard abort
5359 * command busy is also time out, it'll just give up.
5361 *---------------------------------------------------------------------*/
5362 static unsigned char FPT_busMstrTimeOut(ULONG p_port)
5366 timeout = LONG_WAIT;
5368 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5370 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5374 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5375 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5377 timeout = LONG_WAIT;
5378 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5381 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5383 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5393 /*---------------------------------------------------------------------
5395 * Function: Host Data Transfer Abort
5397 * Description: Abort any in progress transfer.
5399 *---------------------------------------------------------------------*/
5400 static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
5405 unsigned int sg_ptr;
5407 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5409 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5412 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5414 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5415 timeout = LONG_WAIT;
5417 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5419 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5421 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5423 if (FPT_busMstrTimeOut(port)) {
5425 if (pCurrSCCB->HostStatus == 0x00)
5427 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5431 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5433 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5435 if (pCurrSCCB->HostStatus == 0x00)
5438 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5444 else if (pCurrSCCB->Sccb_XferCnt) {
5446 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5449 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5452 WR_HARPOON(port+hp_sg_addr,0x00);
5454 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5456 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5458 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5461 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5463 while (remain_cnt < 0x01000000L) {
5467 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5468 DataPointer) + (sg_ptr * 2)))) {
5470 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5471 DataPointer) + (sg_ptr * 2)));
5482 if (remain_cnt < 0x01000000L) {
5485 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5487 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5490 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5491 && (remain_cnt == 0))
5493 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5499 if (pCurrSCCB->HostStatus == 0x00) {
5501 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5507 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5510 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5512 FPT_busMstrTimeOut(port);
5517 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5519 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5521 if (pCurrSCCB->HostStatus == 0x00) {
5523 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5534 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5536 timeout = SHORT_WAIT;
5538 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5539 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5543 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5545 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5548 timeout = LONG_WAIT;
5550 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5553 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5557 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5559 if (pCurrSCCB->HostStatus == 0x00) {
5561 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5564 FPT_busMstrTimeOut(port);
5568 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5570 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5572 if (pCurrSCCB->HostStatus == 0x00) {
5574 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5585 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5587 timeout = LONG_WAIT;
5589 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5591 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5593 if (pCurrSCCB->HostStatus == 0x00) {
5595 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5598 FPT_busMstrTimeOut(port);
5603 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5605 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5607 if (pCurrSCCB->HostStatus == 0x00) {
5609 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5615 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5617 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5620 WR_HARPOON(port+hp_sg_addr,0x00);
5622 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5624 pCurrSCCB->Sccb_SGoffset = 0x00;
5627 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5628 pCurrSCCB->DataLength) {
5630 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5632 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5639 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5641 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5645 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5650 /*---------------------------------------------------------------------
5652 * Function: Host Data Transfer Restart
5654 * Description: Reset the available count due to a restore data
5657 *---------------------------------------------------------------------*/
5658 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5661 unsigned int sg_index;
5664 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5666 currSCCB->Sccb_XferCnt = 0;
5668 sg_index = 0xffff; /*Index by long words into sg list. */
5669 data_count = 0; /*Running count of SG xfer counts. */
5671 sg_ptr = (ULONG *)currSCCB->DataPointer;
5673 while (data_count < currSCCB->Sccb_ATC) {
5676 data_count += *(sg_ptr+(sg_index * 2));
5679 if (data_count == currSCCB->Sccb_ATC) {
5681 currSCCB->Sccb_SGoffset = 0;
5686 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5689 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5693 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5699 /*---------------------------------------------------------------------
5701 * Function: FPT_scini
5703 * Description: Setup all data structures necessary for SCAM selection.
5705 *---------------------------------------------------------------------*/
5707 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5710 unsigned char loser,assigned_id;
5713 unsigned char i,k,ScamFlg ;
5715 PNVRamInfo pCurrNvRam;
5717 currCard = &FPT_BL_Card[p_card];
5718 p_port = currCard->ioPort;
5719 pCurrNvRam = currCard->pNvRamInfo;
5723 ScamFlg = pCurrNvRam->niScamConf;
5724 i = pCurrNvRam->niSysConf;
5727 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5728 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5730 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5733 FPT_inisci(p_card,p_port, p_our_id);
5735 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5736 too slow to return to SCAM selection */
5739 FPT_Wait1Second(p_port);
5741 FPT_Wait(p_port, TO_250ms); */
5743 FPT_Wait1Second(p_port);
5745 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5747 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5752 FPT_scxferc(p_port,SYNC_PTRN);
5753 FPT_scxferc(p_port,DOM_MSTR);
5754 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5755 } while ( loser == 0xFF );
5759 if ((p_power_up) && (!loser))
5761 FPT_sresb(p_port,p_card);
5762 FPT_Wait(p_port, TO_250ms);
5764 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5769 FPT_scxferc(p_port, SYNC_PTRN);
5770 FPT_scxferc(p_port, DOM_MSTR);
5771 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5773 } while ( loser == 0xFF );
5788 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5791 if (ScamFlg & SCAM_ENABLED)
5794 for (i=0; i < MAX_SCSI_TAR; i++)
5796 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5797 (FPT_scamInfo[i].state == ID_UNUSED))
5799 if (FPT_scsell(p_port,i))
5801 FPT_scamInfo[i].state = LEGACY;
5802 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5803 (FPT_scamInfo[i].id_string[1] != 0xFA))
5806 FPT_scamInfo[i].id_string[0] = 0xFF;
5807 FPT_scamInfo[i].id_string[1] = 0xFA;
5808 if(pCurrNvRam == NULL)
5809 currCard->globalFlags |= F_UPDATE_EEPROM;
5815 FPT_sresb(p_port,p_card);
5816 FPT_Wait1Second(p_port);
5817 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5819 FPT_scasid(p_card, p_port);
5824 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5826 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5828 FPT_scwtsel(p_port);
5831 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5833 i = FPT_scxferc(p_port,0x00);
5836 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5838 i = FPT_scxferc(p_port,0x00);
5841 k = FPT_scxferc(p_port,0x00);
5846 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5847 FPT_inisci(p_card, p_port, p_our_id);
5848 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5849 FPT_scamInfo[currCard->ourId].id_string[0]
5857 else if (i == SET_P_FLAG)
5859 if (!(FPT_scsendi(p_port,
5860 &FPT_scamInfo[p_our_id].id_string[0])))
5861 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5863 }while (!assigned_id);
5865 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5868 if (ScamFlg & SCAM_ENABLED)
5871 if (currCard->globalFlags & F_UPDATE_EEPROM)
5873 FPT_scsavdi(p_card, p_port);
5874 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5880 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5882 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5883 (FPT_scamInfo[i].state == LEGACY))
5888 currCard->globalFlags |= F_SINGLE_DEVICE;
5890 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5895 /*---------------------------------------------------------------------
5897 * Function: FPT_scarb
5899 * Description: Gain control of the bus and wait SCAM select time (250ms)
5901 *---------------------------------------------------------------------*/
5903 static int FPT_scarb(ULONG p_port, unsigned char p_sel_type)
5905 if (p_sel_type == INIT_SELTD)
5908 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5911 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5914 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5917 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5919 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5921 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5927 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5929 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5931 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5932 ~(SCSI_BSY | SCSI_SEL)));
5938 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5940 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5941 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5942 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5943 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5945 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5947 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5950 FPT_Wait(p_port,TO_250ms);
5956 /*---------------------------------------------------------------------
5958 * Function: FPT_scbusf
5960 * Description: Release the SCSI bus and disable SCAM selection.
5962 *---------------------------------------------------------------------*/
5964 static void FPT_scbusf(ULONG p_port)
5966 WR_HARPOON(p_port+hp_page_ctrl,
5967 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5970 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5972 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5975 WR_HARPOON(p_port+hp_scsisig, 0x00);
5978 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5981 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5984 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5986 WR_HARPOON(p_port+hp_page_ctrl,
5987 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5992 /*---------------------------------------------------------------------
5994 * Function: FPT_scasid
5996 * Description: Assign an ID to all the SCAM devices.
5998 *---------------------------------------------------------------------*/
6000 static void FPT_scasid(unsigned char p_card, ULONG p_port)
6002 unsigned char temp_id_string[ID_STRING_LENGTH];
6004 unsigned char i,k,scam_id;
6005 unsigned char crcBytes[3];
6006 PNVRamInfo pCurrNvRam;
6007 ushort_ptr pCrcBytes;
6009 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6016 for (k=0; k < ID_STRING_LENGTH; k++)
6018 temp_id_string[k] = (unsigned char) 0x00;
6021 FPT_scxferc(p_port,SYNC_PTRN);
6022 FPT_scxferc(p_port,ASSIGN_ID);
6024 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6027 pCrcBytes = (ushort_ptr)&crcBytes[0];
6028 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6029 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6030 temp_id_string[1] = crcBytes[2];
6031 temp_id_string[2] = crcBytes[0];
6032 temp_id_string[3] = crcBytes[1];
6033 for(k = 4; k < ID_STRING_LENGTH; k++)
6034 temp_id_string[k] = (unsigned char) 0x00;
6036 i = FPT_scmachid(p_card,temp_id_string);
6038 if (i == CLR_PRIORITY)
6040 FPT_scxferc(p_port,MISC_CODE);
6041 FPT_scxferc(p_port,CLR_P_FLAG);
6042 i = 0; /*Not the last ID yet. */
6045 else if (i != NO_ID_AVAIL)
6048 FPT_scxferc(p_port,ID_0_7);
6050 FPT_scxferc(p_port,ID_8_F);
6052 scam_id = (i & (unsigned char) 0x07);
6055 for (k=1; k < 0x08; k <<= 1)
6057 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6059 FPT_scxferc(p_port,scam_id);
6061 i = 0; /*Not the last ID yet. */
6072 FPT_scxferc(p_port,SYNC_PTRN);
6073 FPT_scxferc(p_port,CFG_CMPLT);
6080 /*---------------------------------------------------------------------
6082 * Function: FPT_scsel
6084 * Description: Select all the SCAM devices.
6086 *---------------------------------------------------------------------*/
6088 static void FPT_scsel(ULONG p_port)
6091 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6092 FPT_scwiros(p_port, SCSI_MSG);
6094 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6098 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6099 (unsigned char)(BIT(7)+BIT(6))));
6102 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6103 FPT_scwiros(p_port, SCSI_SEL);
6105 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6106 ~(unsigned char)BIT(6)));
6107 FPT_scwirod(p_port, BIT(6));
6109 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6114 /*---------------------------------------------------------------------
6116 * Function: FPT_scxferc
6118 * Description: Handshake the p_data (DB4-0) across the bus.
6120 *---------------------------------------------------------------------*/
6122 static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data)
6124 unsigned char curr_data, ret_data;
6126 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6128 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6130 curr_data &= ~BIT(7);
6132 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6134 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6135 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6137 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6139 curr_data |= BIT(6);
6141 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6143 curr_data &= ~BIT(5);
6145 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6147 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6149 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6150 curr_data |= BIT(7);
6152 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6154 curr_data &= ~BIT(6);
6156 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6158 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6164 /*---------------------------------------------------------------------
6166 * Function: FPT_scsendi
6168 * Description: Transfer our Identification string to determine if we
6169 * will be the dominant master.
6171 *---------------------------------------------------------------------*/
6173 static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[])
6175 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6179 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6181 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6184 ret_data = FPT_scxferc(p_port,00);
6186 else if (p_id_string[byte_cnt] & bit_cnt)
6188 ret_data = FPT_scxferc(p_port,02);
6192 ret_data = FPT_scxferc(p_port,01);
6197 if ((ret_data & 0x1C) == 0x10)
6198 return(0x00); /*End of isolation stage, we won! */
6200 if (ret_data & 0x1C)
6203 if ((defer) && (!(ret_data & 0x1F)))
6204 return(0x01); /*End of isolation stage, we lost. */
6211 return(0x01); /*We lost */
6213 return(0); /*We WON! Yeeessss! */
6218 /*---------------------------------------------------------------------
6220 * Function: FPT_sciso
6222 * Description: Transfer the Identification string.
6224 *---------------------------------------------------------------------*/
6226 static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[])
6228 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6232 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6234 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6236 ret_data = FPT_scxferc(p_port,0);
6238 if (ret_data & 0xFC)
6244 if (ret_data & BIT(1)) {
6249 if ((ret_data & 0x1F) == 0)
6252 if(bit_cnt != 0 || bit_cnt != 8)
6256 FPT_scxferc(p_port, SYNC_PTRN);
6257 FPT_scxferc(p_port, ASSIGN_ID);
6269 p_id_string[byte_cnt] = the_data;
6278 /*---------------------------------------------------------------------
6280 * Function: FPT_scwirod
6282 * Description: Sample the SCSI data bus making sure the signal has been
6283 * deasserted for the correct number of consecutive samples.
6285 *---------------------------------------------------------------------*/
6287 static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit)
6292 while ( i < MAX_SCSI_TAR ) {
6294 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6307 /*---------------------------------------------------------------------
6309 * Function: FPT_scwiros
6311 * Description: Sample the SCSI Signal lines making sure the signal has been
6312 * deasserted for the correct number of consecutive samples.
6314 *---------------------------------------------------------------------*/
6316 static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit)
6321 while ( i < MAX_SCSI_TAR ) {
6323 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6335 /*---------------------------------------------------------------------
6337 * Function: FPT_scvalq
6339 * Description: Make sure we received a valid data byte.
6341 *---------------------------------------------------------------------*/
6343 static unsigned char FPT_scvalq(unsigned char p_quintet)
6345 unsigned char count;
6347 for (count=1; count < 0x08; count<<=1) {
6348 if (!(p_quintet & count))
6352 if (p_quintet & 0x18)
6360 /*---------------------------------------------------------------------
6362 * Function: FPT_scsell
6364 * Description: Select the specified device ID using a selection timeout
6365 * less than 4ms. If somebody responds then it is a legacy
6366 * drive and this ID must be marked as such.
6368 *---------------------------------------------------------------------*/
6370 static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id)
6374 WR_HARPOON(p_port+hp_page_ctrl,
6375 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6377 ARAM_ACCESS(p_port);
6379 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6380 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6383 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6384 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6386 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6388 WRW_HARPOON((p_port+hp_intstat),
6389 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6391 WR_HARPOON(p_port+hp_select_id, targ_id);
6393 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6394 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6395 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6398 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6399 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6401 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6402 FPT_Wait(p_port, TO_250ms);
6404 DISABLE_AUTO(p_port);
6406 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6407 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6409 SGRAM_ACCESS(p_port);
6411 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6413 WRW_HARPOON((p_port+hp_intstat),
6414 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6416 WR_HARPOON(p_port+hp_page_ctrl,
6417 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6419 return(0); /*No legacy device */
6424 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6425 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6427 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6432 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6434 WR_HARPOON(p_port+hp_page_ctrl,
6435 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6437 return(1); /*Found one of them oldies! */
6441 /*---------------------------------------------------------------------
6443 * Function: FPT_scwtsel
6445 * Description: Wait to be selected by another SCAM initiator.
6447 *---------------------------------------------------------------------*/
6449 static void FPT_scwtsel(ULONG p_port)
6451 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6455 /*---------------------------------------------------------------------
6457 * Function: FPT_inisci
6459 * Description: Setup the data Structure with the info from the EEPROM.
6461 *---------------------------------------------------------------------*/
6463 static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id)
6465 unsigned char i,k,max_id;
6466 unsigned short ee_data;
6467 PNVRamInfo pCurrNvRam;
6469 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6471 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6478 for(i = 0; i < max_id; i++){
6480 for(k = 0; k < 4; k++)
6481 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6482 for(k = 4; k < ID_STRING_LENGTH; k++)
6483 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6485 if(FPT_scamInfo[i].id_string[0] == 0x00)
6486 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6488 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6492 for (i=0; i < max_id; i++)
6494 for (k=0; k < ID_STRING_LENGTH; k+=2)
6496 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6497 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6498 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6500 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6503 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6504 (FPT_scamInfo[i].id_string[0] == 0xFF))
6506 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6509 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6513 for(k = 0; k < ID_STRING_LENGTH; k++)
6514 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6518 /*---------------------------------------------------------------------
6520 * Function: FPT_scmachid
6522 * Description: Match the Device ID string with our values stored in
6525 *---------------------------------------------------------------------*/
6527 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6530 unsigned char i,k,match;
6533 for (i=0; i < MAX_SCSI_TAR; i++) {
6537 for (k=0; k < ID_STRING_LENGTH; k++)
6539 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6545 FPT_scamInfo[i].state = ID_ASSIGNED;
6553 if (p_id_string[0] & BIT(5))
6558 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6559 match = p_id_string[1] & (unsigned char) 0x1F;
6567 if (FPT_scamInfo[match].state == ID_UNUSED)
6569 for (k=0; k < ID_STRING_LENGTH; k++)
6571 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6574 FPT_scamInfo[match].state = ID_ASSIGNED;
6576 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6577 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6587 if (p_id_string[0] & BIT(5))
6590 match = MAX_SCSI_TAR-1;
6596 if (p_id_string[0] & BIT(7))
6598 return(CLR_PRIORITY);
6602 if (p_id_string[0] & BIT(5))
6607 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6608 match = p_id_string[1] & (unsigned char) 0x1F;
6617 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6619 for (k=0; k < ID_STRING_LENGTH; k++)
6621 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6624 FPT_scamInfo[match].id_string[0] |= BIT(7);
6625 FPT_scamInfo[match].state = ID_ASSIGNED;
6626 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6627 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6637 if (p_id_string[0] & BIT(5))
6640 match = MAX_SCSI_TAR-1;
6644 return(NO_ID_AVAIL);
6648 /*---------------------------------------------------------------------
6650 * Function: FPT_scsavdi
6652 * Description: Save off the device SCAM ID strings.
6654 *---------------------------------------------------------------------*/
6656 static void FPT_scsavdi(unsigned char p_card, ULONG p_port)
6658 unsigned char i,k,max_id;
6659 unsigned short ee_data,sum_data;
6664 for (i = 1; i < EE_SCAMBASE/2; i++)
6666 sum_data += FPT_utilEERead(p_port, i);
6670 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6672 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6678 for (i=0; i < max_id; i++)
6681 for (k=0; k < ID_STRING_LENGTH; k+=2)
6683 ee_data = FPT_scamInfo[i].id_string[k+1];
6685 ee_data |= FPT_scamInfo[i].id_string[k];
6686 sum_data += ee_data;
6687 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6688 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6693 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6694 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6697 /*---------------------------------------------------------------------
6699 * Function: FPT_XbowInit
6701 * Description: Setup the Xbow for normal operation.
6703 *---------------------------------------------------------------------*/
6705 static void FPT_XbowInit(ULONG port, unsigned char ScamFlg)
6709 i = RD_HARPOON(port+hp_page_ctrl);
6710 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6712 WR_HARPOON(port+hp_scsireset,0x00);
6713 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6715 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6718 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6720 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6722 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6723 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6725 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6727 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6728 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6730 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6731 FPT_default_intena |= SCAM_SEL;
6733 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6735 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6737 /* Turn on SCSI_MODE8 for narrow cards to fix the
6738 strapping issue with the DUAL CHANNEL card */
6739 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6740 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6742 WR_HARPOON(port+hp_page_ctrl, i);
6747 /*---------------------------------------------------------------------
6749 * Function: FPT_BusMasterInit
6751 * Description: Initialize the BusMaster for normal operations.
6753 *---------------------------------------------------------------------*/
6755 static void FPT_BusMasterInit(ULONG p_port)
6759 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6760 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6762 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6765 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6767 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6770 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6771 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6772 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6777 /*---------------------------------------------------------------------
6779 * Function: FPT_DiagEEPROM
6781 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6784 *---------------------------------------------------------------------*/
6786 static void FPT_DiagEEPROM(ULONG p_port)
6788 unsigned short index,temp,max_wd_cnt;
6790 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6791 max_wd_cnt = EEPROM_WD_CNT;
6793 max_wd_cnt = EEPROM_WD_CNT * 2;
6795 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6797 if (temp == 0x4641) {
6799 for (index = 2; index < max_wd_cnt; index++) {
6801 temp += FPT_utilEERead(p_port, index);
6805 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6807 return; /*EEPROM is Okay so return now! */
6812 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6814 for (index = 0; index < max_wd_cnt; index++) {
6816 FPT_utilEEWrite(p_port, 0x0000, index);
6821 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6823 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6825 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6827 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6829 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6831 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6833 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6835 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6838 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6840 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6842 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6851 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6853 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6855 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6857 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6859 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6863 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6865 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6867 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6869 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6871 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6873 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6875 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6877 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6880 index = ((EE_SCAMBASE/2)+(7*16));
6881 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6882 temp += (0x0700+TYPE_CODE0);
6884 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6885 temp += 0x5542; /* BUSLOGIC */
6887 FPT_utilEEWrite(p_port, 0x4C53, index);
6890 FPT_utilEEWrite(p_port, 0x474F, index);
6893 FPT_utilEEWrite(p_port, 0x4349, index);
6896 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6897 temp += 0x5442; /* BT- 930 */
6899 FPT_utilEEWrite(p_port, 0x202D, index);
6902 FPT_utilEEWrite(p_port, 0x3339, index);
6904 index++; /*Serial # */
6905 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6908 FPT_utilEEWrite(p_port, 0x5453, index);
6911 FPT_utilEEWrite(p_port, 0x5645, index);
6914 FPT_utilEEWrite(p_port, 0x2045, index);
6917 FPT_utilEEWrite(p_port, 0x202F, index);
6920 FPT_utilEEWrite(p_port, 0x4F4A, index);
6923 FPT_utilEEWrite(p_port, 0x204E, index);
6926 FPT_utilEEWrite(p_port, 0x3539, index);
6931 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6933 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6938 /*---------------------------------------------------------------------
6940 * Function: Queue Search Select
6942 * Description: Try to find a new command to execute.
6944 *---------------------------------------------------------------------*/
6946 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6948 unsigned char scan_ptr, lun;
6949 PSCCBMgr_tar_info currTar_Info;
6952 scan_ptr = pCurrCard->scanIndex;
6955 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6956 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6957 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6959 if (currTar_Info->TarSelQ_Cnt != 0)
6963 if (scan_ptr == MAX_SCSI_TAR)
6966 for(lun=0; lun < MAX_LUN; lun++)
6968 if(currTar_Info->TarLUNBusy[lun] == 0)
6971 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6974 while((pCurrCard->currentSCCB != NULL) &&
6975 (lun != pCurrCard->currentSCCB->Lun))
6977 pOldSccb = pCurrCard->currentSCCB;
6978 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6981 if(pCurrCard->currentSCCB == NULL)
6983 if(pOldSccb != NULL)
6985 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6987 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6989 currTar_Info->TarSelQ_Cnt--;
6993 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6995 if (currTar_Info->TarSelQ_Head == NULL)
6997 currTar_Info->TarSelQ_Tail = NULL;
6998 currTar_Info->TarSelQ_Cnt = 0;
7002 currTar_Info->TarSelQ_Cnt--;
7003 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7006 pCurrCard->scanIndex = scan_ptr;
7008 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7018 if (scan_ptr == MAX_SCSI_TAR) {
7026 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7027 (currTar_Info->TarLUNBusy[0] == 0))
7030 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7032 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7034 if (currTar_Info->TarSelQ_Head == NULL)
7036 currTar_Info->TarSelQ_Tail = NULL;
7037 currTar_Info->TarSelQ_Cnt = 0;
7041 currTar_Info->TarSelQ_Cnt--;
7042 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7046 if (scan_ptr == MAX_SCSI_TAR)
7049 pCurrCard->scanIndex = scan_ptr;
7051 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7059 if (scan_ptr == MAX_SCSI_TAR)
7065 } while (scan_ptr != pCurrCard->scanIndex);
7069 /*---------------------------------------------------------------------
7071 * Function: Queue Select Fail
7073 * Description: Add the current SCCB to the head of the Queue.
7075 *---------------------------------------------------------------------*/
7077 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7079 unsigned char thisTarg;
7080 PSCCBMgr_tar_info currTar_Info;
7082 if (pCurrCard->currentSCCB != NULL)
7084 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7085 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7087 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7089 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7091 if (currTar_Info->TarSelQ_Cnt == 0)
7093 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7098 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7102 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7104 pCurrCard->currentSCCB = NULL;
7105 currTar_Info->TarSelQ_Cnt++;
7108 /*---------------------------------------------------------------------
7110 * Function: Queue Command Complete
7112 * Description: Call the callback function with the current SCCB.
7114 *---------------------------------------------------------------------*/
7116 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7117 unsigned char p_card)
7120 unsigned char i, SCSIcmd;
7121 CALL_BK_FN callback;
7122 PSCCBMgr_tar_info currTar_Info;
7124 SCSIcmd = p_sccb->Cdb[0];
7127 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7129 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7130 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7131 (p_sccb->TargetStatus != SSCHECK))
7133 if ((SCSIcmd == SCSI_READ) ||
7134 (SCSIcmd == SCSI_WRITE) ||
7135 (SCSIcmd == SCSI_READ_EXTENDED) ||
7136 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7137 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7138 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7139 (pCurrCard->globalFlags & F_NO_FILTER)
7141 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7145 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7147 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7148 p_sccb->SccbStatus = SCCB_ERROR;
7150 p_sccb->SccbStatus = SCCB_SUCCESS;
7153 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7155 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7156 for (i=0; i < 6; i++) {
7157 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7161 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7162 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7164 FPT_utilUpdateResidual(p_sccb);
7167 pCurrCard->cmdCounter--;
7168 if (!pCurrCard->cmdCounter) {
7170 if (pCurrCard->globalFlags & F_GREEN_PC) {
7171 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7172 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7175 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7176 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7180 if(pCurrCard->discQCount != 0)
7182 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7183 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7184 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7186 pCurrCard->discQCount--;
7187 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7191 if(p_sccb->Sccb_tag)
7193 pCurrCard->discQCount--;
7194 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7197 pCurrCard->discQCount--;
7198 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7204 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7206 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7207 pCurrCard->currentSCCB = NULL;
7211 /*---------------------------------------------------------------------
7213 * Function: Queue Disconnect
7215 * Description: Add SCCB to our disconnect array.
7217 *---------------------------------------------------------------------*/
7218 static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
7220 PSCCBMgr_tar_info currTar_Info;
7222 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7224 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7225 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7227 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7231 if (p_sccb->Sccb_tag)
7233 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7234 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7235 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7238 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7241 FPT_BL_Card[p_card].currentSCCB = NULL;
7245 /*---------------------------------------------------------------------
7247 * Function: Queue Flush SCCB
7249 * Description: Flush all SCCB's back to the host driver for this target.
7251 *---------------------------------------------------------------------*/
7253 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7255 unsigned char qtag,thisTarg;
7257 PSCCBMgr_tar_info currTar_Info;
7259 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7260 if(currSCCB != NULL)
7262 thisTarg = (unsigned char)currSCCB->TargID;
7263 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7265 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7267 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7268 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7271 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7273 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7275 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7276 currTar_Info->TarTagQ_Cnt--;
7284 /*---------------------------------------------------------------------
7286 * Function: Queue Flush Target SCCB
7288 * Description: Flush all SCCB's back to the host driver for this target.
7290 *---------------------------------------------------------------------*/
7292 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7293 unsigned char error_code)
7296 PSCCBMgr_tar_info currTar_Info;
7298 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7300 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7302 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7303 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7306 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7308 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7310 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7311 currTar_Info->TarTagQ_Cnt--;
7322 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
7324 PSCCBMgr_tar_info currTar_Info;
7325 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7327 p_SCCB->Sccb_forwardlink = NULL;
7329 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7331 if (currTar_Info->TarSelQ_Cnt == 0) {
7333 currTar_Info->TarSelQ_Head = p_SCCB;
7338 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7342 currTar_Info->TarSelQ_Tail = p_SCCB;
7343 currTar_Info->TarSelQ_Cnt++;
7347 /*---------------------------------------------------------------------
7349 * Function: Queue Find SCCB
7351 * Description: Search the target select Queue for this SCCB, and
7352 * remove it if found.
7354 *---------------------------------------------------------------------*/
7356 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
7359 PSCCBMgr_tar_info currTar_Info;
7361 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7363 q_ptr = currTar_Info->TarSelQ_Head;
7365 while(q_ptr != NULL) {
7367 if (q_ptr == p_SCCB) {
7370 if (currTar_Info->TarSelQ_Head == q_ptr) {
7372 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7375 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7377 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7380 if (q_ptr->Sccb_forwardlink != NULL) {
7381 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7384 if (q_ptr->Sccb_backlink != NULL) {
7385 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7388 currTar_Info->TarSelQ_Cnt--;
7394 q_ptr = q_ptr->Sccb_forwardlink;
7404 /*---------------------------------------------------------------------
7406 * Function: Utility Update Residual Count
7408 * Description: Update the XferCnt to the remaining byte count.
7409 * If we transferred all the data then just write zero.
7410 * If Non-SG transfer then report Total Cnt - Actual Transfer
7411 * Cnt. For SG transfers add the count fields of all
7412 * remaining SG elements, as well as any partial remaining
7415 *---------------------------------------------------------------------*/
7417 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7420 unsigned int sg_index;
7423 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7425 p_SCCB->DataLength = 0x0000;
7428 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7430 partial_cnt = 0x0000;
7432 sg_index = p_SCCB->Sccb_sgseg;
7434 sg_ptr = (ULONG *)p_SCCB->DataPointer;
7436 if (p_SCCB->Sccb_SGoffset) {
7438 partial_cnt = p_SCCB->Sccb_SGoffset;
7442 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7443 p_SCCB->DataLength ) {
7445 partial_cnt += *(sg_ptr+(sg_index * 2));
7449 p_SCCB->DataLength = partial_cnt;
7454 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7459 /*---------------------------------------------------------------------
7461 * Function: Wait 1 Second
7463 * Description: Wait for 1 second.
7465 *---------------------------------------------------------------------*/
7467 static void FPT_Wait1Second(ULONG p_port)
7471 for(i=0; i < 4; i++) {
7473 FPT_Wait(p_port, TO_250ms);
7475 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7478 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7484 /*---------------------------------------------------------------------
7486 * Function: FPT_Wait
7488 * Description: Wait the desired delay.
7490 *---------------------------------------------------------------------*/
7492 static void FPT_Wait(ULONG p_port, unsigned char p_delay)
7494 unsigned char old_timer;
7495 unsigned char green_flag;
7497 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7499 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7500 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7502 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7503 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7504 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7507 WR_HARPOON(p_port+hp_portctrl_0,
7508 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7510 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7512 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7515 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7519 WR_HARPOON(p_port+hp_portctrl_0,
7520 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7522 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7523 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7525 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7527 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7531 /*---------------------------------------------------------------------
7533 * Function: Enable/Disable Write to EEPROM
7535 * Description: The EEPROM must first be enabled for writes
7536 * A total of 9 clocks are needed.
7538 *---------------------------------------------------------------------*/
7540 static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode)
7542 unsigned char ee_value;
7544 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7548 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7553 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7555 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7556 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7560 /*---------------------------------------------------------------------
7562 * Function: Write EEPROM
7564 * Description: Write a word to the EEPROM at the specified
7567 *---------------------------------------------------------------------*/
7569 static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr)
7572 unsigned char ee_value;
7575 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7580 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7583 ee_value |= (SEE_MS + SEE_CS);
7585 for(i = 0x8000; i != 0; i>>=1) {
7590 ee_value &= ~SEE_DO;
7592 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7593 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7594 ee_value |= SEE_CLK; /* Clock data! */
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 ee_value &= ~SEE_CLK;
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7601 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7602 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7604 FPT_Wait(p_port, TO_10ms);
7606 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7607 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7608 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7611 /*---------------------------------------------------------------------
7613 * Function: Read EEPROM
7615 * Description: Read a word from the EEPROM at the desired
7618 *---------------------------------------------------------------------*/
7620 static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr)
7622 unsigned short i, ee_data1, ee_data2;
7625 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7628 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7630 if(ee_data1 == ee_data2)
7633 ee_data1 = ee_data2;
7641 /*---------------------------------------------------------------------
7643 * Function: Read EEPROM Original
7645 * Description: Read a word from the EEPROM at the desired
7648 *---------------------------------------------------------------------*/
7650 static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr)
7653 unsigned char ee_value;
7654 unsigned short i, ee_data;
7656 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7660 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7663 ee_value |= (SEE_MS + SEE_CS);
7666 for(i = 1; i <= 16; i++) {
7668 ee_value |= SEE_CLK; /* Clock data! */
7669 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7671 ee_value &= ~SEE_CLK;
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7677 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7681 ee_value &= ~(SEE_MS + SEE_CS);
7682 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7683 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7689 /*---------------------------------------------------------------------
7691 * Function: Send EE command and Address to the EEPROM
7693 * Description: Transfers the correct command and sends the address
7696 *---------------------------------------------------------------------*/
7698 static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr)
7700 unsigned char ee_value;
7701 unsigned char narrow_flg;
7706 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7710 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7712 ee_value |= SEE_CS; /* Set CS to EEPROM */
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 for(i = 0x04; i != 0; i>>=1) {
7721 ee_value &= ~SEE_DO;
7723 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7724 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7725 ee_value |= SEE_CLK; /* Clock data! */
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 ee_value &= ~SEE_CLK;
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7746 ee_value &= ~SEE_DO;
7748 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 ee_value |= SEE_CLK; /* Clock data! */
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 ee_value &= ~SEE_CLK;
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7761 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7763 unsigned short crc=0;
7766 for (i=0; i < ID_STRING_LENGTH; i++)
7768 ch = (unsigned short) buffer[i];
7769 for(j=0; j < 8; j++)
7772 crc = (crc >> 1) ^ CRCMASK;
7781 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7786 for(i = 0; i < ID_STRING_LENGTH; i++)
7794 The following inline definitions avoid type conflicts.
7797 static inline unsigned char
7798 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7800 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7804 static inline FlashPoint_CardHandle_T
7805 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7807 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7811 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7813 FlashPoint_ReleaseHostAdapter(CardHandle);
7818 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7820 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7825 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7827 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7831 static inline boolean
7832 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7834 return FlashPoint_InterruptPending(CardHandle);
7839 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7841 return FlashPoint_HandleInterrupt(CardHandle);
7845 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7846 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7847 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7848 #define FlashPoint_StartCCB FlashPoint__StartCCB
7849 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7850 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7851 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7854 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7858 Define prototypes for the FlashPoint SCCB Manager Functions.
7861 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7862 extern FlashPoint_CardHandle_T
7863 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7864 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7865 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7866 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7867 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7868 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7871 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */