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
45 typedef unsigned short * ushort_ptr;
52 #define u08bits unsigned s08bits
53 #define u16bits unsigned s16bits
54 #define u32bits unsigned s32bits
58 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
59 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
64 typedef struct _SCCB *PSCCB;
65 typedef void (*CALL_BK_FN)(PSCCB);
68 typedef struct SCCBMgr_info {
69 unsigned long si_baseaddr;
70 unsigned char si_present;
71 unsigned char si_intvect;
74 unsigned short si_fw_revision;
75 unsigned short si_per_targ_init_sync;
76 unsigned short si_per_targ_fast_nego;
77 unsigned short si_per_targ_ultra_nego;
78 unsigned short si_per_targ_no_disc;
79 unsigned short si_per_targ_wide_nego;
80 unsigned short si_flags;
81 unsigned char si_card_family;
82 unsigned char si_bustype;
83 unsigned char si_card_model[3];
84 unsigned char si_relative_cardnum;
85 unsigned char si_reserved[4];
86 unsigned long si_OS_reserved;
87 unsigned char si_XlatInfo[4];
88 unsigned long si_reserved2[5];
89 unsigned long si_secondary_range;
92 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
95 #define SCSI_PARITY_ENA 0x0001
96 #define LOW_BYTE_TERM 0x0010
97 #define HIGH_BYTE_TERM 0x0020
98 #define BUSTYPE_PCI 0x3
100 #define SUPPORT_16TAR_32LUN 0x0002
101 #define SOFT_RESET 0x0004
102 #define EXTENDED_TRANSLATION 0x0008
103 #define POST_ALL_UNDERRRUNS 0x0040
104 #define FLAG_SCAM_ENABLED 0x0080
105 #define FLAG_SCAM_LEVEL2 0x0100
110 #define HARPOON_FAMILY 0x02
114 /* SCCB struct used for both SCCB and UCB manager compiles!
115 * The UCB Manager treats the SCCB as it's 'native hardware structure'
120 typedef struct _SCCB {
121 unsigned char OperationCode;
122 unsigned char ControlByte;
123 unsigned char CdbLength;
124 unsigned char RequestSenseLength;
125 unsigned long DataLength;
126 unsigned long DataPointer;
127 unsigned char CcbRes[2];
128 unsigned char HostStatus;
129 unsigned char TargetStatus;
130 unsigned char TargID;
132 unsigned char Cdb[12];
133 unsigned char CcbRes1;
134 unsigned char Reserved1;
135 unsigned long Reserved2;
136 unsigned long SensePointer;
139 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
140 unsigned long SccbIOPort; /* Identifies board base port */
141 unsigned char SccbStatus;
142 unsigned char SCCBRes2;
143 unsigned short SccbOSFlags;
146 unsigned long Sccb_XferCnt; /* actual transfer count */
147 unsigned long Sccb_ATC;
148 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
149 unsigned long Sccb_res1;
150 unsigned short Sccb_MGRFlags;
151 unsigned short Sccb_sgseg;
152 unsigned char Sccb_scsimsg; /* identify msg for selection */
153 unsigned char Sccb_tag;
154 unsigned char Sccb_scsistat;
155 unsigned char Sccb_idmsg; /* image of last msg in */
156 PSCCB Sccb_forwardlink;
158 unsigned long Sccb_savedATC;
159 unsigned char Save_Cdb[6];
160 unsigned char Save_CdbLen;
161 unsigned char Sccb_XferState;
162 unsigned long Sccb_SGoffset;
170 #define SCATTER_GATHER_COMMAND 0x02
171 #define RESIDUAL_COMMAND 0x03
172 #define RESIDUAL_SG_COMMAND 0x04
173 #define RESET_COMMAND 0x81
176 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
177 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
178 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
179 #define SCCB_DATA_XFER_IN 0x08 /* Read */
182 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
185 #define BUS_FREE_ST 0
187 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
188 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
189 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
190 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
192 #define DATA_OUT_ST 7
194 #define DISCONNECT_ST 9
198 #define F_HOST_XFER_DIR 0x01
199 #define F_ALL_XFERRED 0x02
200 #define F_SG_XFER 0x04
201 #define F_AUTO_SENSE 0x08
202 #define F_ODD_BALL_CNT 0x10
203 #define F_NO_DATA_YET 0x80
206 #define F_STATUSLOADED 0x01
207 #define F_DEV_SELECTED 0x04
210 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
211 #define SCCB_DATA_UNDER_RUN 0x0C
212 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
213 #define SCCB_DATA_OVER_RUN 0x12
214 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
216 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
217 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
218 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
224 #define SCCB_IN_PROCESS 0x00
225 #define SCCB_SUCCESS 0x01
226 #define SCCB_ABORT 0x02
227 #define SCCB_ERROR 0x04
231 #define ORION_FW_REV 3110
235 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
237 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
240 #define MAX_SCSI_TAR 16
242 #define LUN_MASK 0x1f
244 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
246 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
249 #define RD_HARPOON(ioport) inb((u32bits)ioport)
250 #define RDW_HARPOON(ioport) inw((u32bits)ioport)
251 #define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
252 #define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
253 #define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
254 #define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
257 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
258 #define SYNC_TRYING BIT(6)
259 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
261 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
262 #define WIDE_ENABLED BIT(4)
263 #define WIDE_NEGOCIATED BIT(5)
265 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
266 #define TAG_Q_TRYING BIT(2)
267 #define TAG_Q_REJECT BIT(3)
269 #define TAR_ALLOW_DISC BIT(0)
272 #define EE_SYNC_MASK (BIT(0)+BIT(1))
273 #define EE_SYNC_5MB BIT(0)
274 #define EE_SYNC_10MB BIT(1)
275 #define EE_SYNC_20MB (BIT(0)+BIT(1))
277 #define EE_WIDE_SCSI BIT(7)
280 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
283 typedef struct SCCBMgr_tar_info {
287 unsigned char TarLUN_CA; /*Contingent Allgiance */
288 unsigned char TarTagQ_Cnt;
289 unsigned char TarSelQ_Cnt;
290 unsigned char TarStatus;
291 unsigned char TarEEValue;
292 unsigned char TarSyncCtrl;
293 unsigned char TarReserved[2]; /* for alignment */
294 unsigned char LunDiscQ_Idx[MAX_LUN];
295 unsigned char TarLUNBusy[MAX_LUN];
298 typedef struct NVRAMInfo {
299 unsigned char niModel; /* Model No. of card */
300 unsigned char niCardNo; /* Card no. */
301 unsigned long niBaseAddr; /* Port Address of card */
302 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
303 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
304 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
305 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
306 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
307 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
310 typedef NVRAMINFO *PNVRamInfo;
318 typedef struct SCCBcard {
320 PSCCBMGR_INFO cardInfo;
322 unsigned long ioPort;
324 unsigned short cmdCounter;
325 unsigned char discQCount;
326 unsigned char tagQ_Lst;
327 unsigned char cardIndex;
328 unsigned char scanIndex;
329 unsigned char globalFlags;
331 PNVRamInfo pNvRamInfo;
332 PSCCB discQ_Tbl[QUEUE_DEPTH];
336 typedef struct SCCBcard *PSCCBcard;
339 #define F_TAG_STARTED 0x01
340 #define F_CONLUN_IO 0x02
341 #define F_DO_RENEGO 0x04
342 #define F_NO_FILTER 0x08
343 #define F_GREEN_PC 0x10
344 #define F_HOST_XFER_ACT 0x20
345 #define F_NEW_SCCB_CMD 0x40
346 #define F_UPDATE_EEPROM 0x80
349 #define ID_STRING_LENGTH 32
350 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
353 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
355 #define ASSIGN_ID 0x00
356 #define SET_P_FLAG 0x01
357 #define CFG_CMPLT 0x03
358 #define DOM_MSTR 0x0F
359 #define SYNC_PTRN 0x1F
363 #define MISC_CODE 0x14
364 #define CLR_P_FLAG 0x18
368 #define INIT_SELTD 0x01
369 #define LEVEL2_TAR 0x02
372 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
373 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
374 CLR_PRIORITY,NO_ID_AVAIL };
376 typedef struct SCCBscam_info {
378 unsigned char id_string[ID_STRING_LENGTH];
379 enum scam_id_st state;
384 #define SCSI_REQUEST_SENSE 0x03
385 #define SCSI_READ 0x08
386 #define SCSI_WRITE 0x0A
387 #define SCSI_START_STOP_UNIT 0x1B
388 #define SCSI_READ_EXTENDED 0x28
389 #define SCSI_WRITE_EXTENDED 0x2A
390 #define SCSI_WRITE_AND_VERIFY 0x2E
396 #define SSQ_FULL 0x28
401 #define SMCMD_COMP 0x00
403 #define SMSAVE_DATA_PTR 0x02
404 #define SMREST_DATA_PTR 0x03
407 #define SMREJECT 0x07
409 #define SMPARITY 0x09
410 #define SMDEV_RESET 0x0C
411 #define SMABORT_TAG 0x0D
412 #define SMINIT_RECOVERY 0x0F
413 #define SMREL_RECOVERY 0x10
416 #define DISC_PRIV 0x40
423 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
432 #define SIX_BYTE_CMD 0x06
433 #define TWELVE_BYTE_CMD 0x0C
436 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
439 #define EEPROM_WD_CNT 256
441 #define EEPROM_CHECK_SUM 0
442 #define FW_SIGNATURE 2
443 #define MODEL_NUMB_0 4
444 #define MODEL_NUMB_2 6
445 #define MODEL_NUMB_4 8
446 #define SYSTEM_CONFIG 16
447 #define SCSI_CONFIG 17
448 #define BIOS_CONFIG 18
449 #define SCAM_CONFIG 20
450 #define ADAPTER_SCSI_ID 24
453 #define IGNORE_B_SCAN 32
454 #define SEND_START_ENA 34
455 #define DEVICE_ENABLE 36
457 #define SYNC_RATE_TBL 38
458 #define SYNC_RATE_TBL01 38
459 #define SYNC_RATE_TBL23 40
460 #define SYNC_RATE_TBL45 42
461 #define SYNC_RATE_TBL67 44
462 #define SYNC_RATE_TBL89 46
463 #define SYNC_RATE_TBLab 48
464 #define SYNC_RATE_TBLcd 50
465 #define SYNC_RATE_TBLef 52
469 #define EE_SCAMBASE 256
473 #define SCAM_ENABLED BIT(2)
474 #define SCAM_LEVEL2 BIT(3)
477 #define RENEGO_ENA BITW(10)
478 #define CONNIO_ENA BITW(11)
479 #define GREEN_PC_ENA BITW(12)
482 #define AUTO_RATE_00 00
483 #define AUTO_RATE_05 01
484 #define AUTO_RATE_10 02
485 #define AUTO_RATE_20 03
487 #define WIDE_NEGO_BIT BIT(7)
488 #define DISC_ENABLE_BIT BIT(6)
492 #define hp_vendor_id_0 0x00 /* LSB */
493 #define ORION_VEND_0 0x4B
495 #define hp_vendor_id_1 0x01 /* MSB */
496 #define ORION_VEND_1 0x10
498 #define hp_device_id_0 0x02 /* LSB */
499 #define ORION_DEV_0 0x30
501 #define hp_device_id_1 0x03 /* MSB */
502 #define ORION_DEV_1 0x81
504 /* Sub Vendor ID and Sub Device ID only available in
505 Harpoon Version 2 and higher */
507 #define hp_sub_device_id_0 0x06 /* LSB */
511 #define hp_semaphore 0x0C
512 #define SCCB_MGR_ACTIVE BIT(0)
513 #define TICKLE_ME BIT(1)
514 #define SCCB_MGR_PRESENT BIT(3)
515 #define BIOS_IN_USE BIT(4)
519 #define hp_sys_ctrl 0x0F
521 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
522 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
523 #define HALT_MACH BIT(3) /*Halt State Machine */
524 #define HARD_ABORT BIT(4) /*Hard Abort */
534 #define hp_host_blk_cnt 0x13
536 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
538 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
542 #define hp_int_mask 0x17
544 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
545 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
548 #define hp_xfer_cnt_lo 0x18
549 #define hp_xfer_cnt_hi 0x1A
550 #define hp_xfer_cmd 0x1B
552 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
553 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
556 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
558 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
560 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
562 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
563 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
565 #define hp_host_addr_lo 0x1C
566 #define hp_host_addr_hmi 0x1E
568 #define hp_ee_ctrl 0x22
570 #define EXT_ARB_ACK BIT(7)
571 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
572 #define SEE_MS BIT(5)
573 #define SEE_CS BIT(3)
574 #define SEE_CLK BIT(2)
575 #define SEE_DO BIT(1)
576 #define SEE_DI BIT(0)
579 #define EE_WRITE 0x05
581 #define EWEN_ADDR 0x03C0
583 #define EWDS_ADDR 0x0000
591 #define hp_bm_ctrl 0x26
593 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
594 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
595 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
596 #define FAST_SINGLE BIT(6) /*?? */
598 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
601 #define hp_sg_addr 0x28
602 #define hp_page_ctrl 0x29
604 #define SCATTER_EN BIT(0)
605 #define SGRAM_ARAM BIT(1)
606 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
607 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
612 #define hp_pci_stat_cfg 0x2D
614 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
623 #define hp_rev_num 0x33
626 #define hp_stack_data 0x34
627 #define hp_stack_addr 0x35
629 #define hp_ext_status 0x36
631 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
632 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
633 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
634 #define CMD_ABORTED BIT(4) /*Command aborted */
635 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
636 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
637 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
638 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
639 BM_PARITY_ERR | PIO_OVERRUN)
641 #define hp_int_status 0x37
643 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
644 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
645 #define INT_ASSERTED BIT(5) /* */
648 #define hp_fifo_cnt 0x38
653 #define hp_intena 0x40
655 #define RESET BITW(7)
656 #define PROG_HLT BITW(6)
657 #define PARITY BITW(5)
660 #define SCAM_SEL BITW(2)
662 #define TIMEOUT BITW(0)
663 #define BUS_FREE BITW(15)
664 #define XFER_CNT_0 BITW(14)
665 #define PHASE BITW(13)
666 #define IUNKWN BITW(12)
667 #define ICMD_COMP BITW(11)
668 #define ITICKLE BITW(10)
669 #define IDO_STRT BITW(9)
670 #define ITAR_DISC BITW(8)
671 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
672 #define CLR_ALL_INT 0xFFFF
673 #define CLR_ALL_INT_1 0xFF00
675 #define hp_intstat 0x42
677 #define hp_scsisig 0x44
679 #define SCSI_SEL BIT(7)
680 #define SCSI_BSY BIT(6)
681 #define SCSI_REQ BIT(5)
682 #define SCSI_ACK BIT(4)
683 #define SCSI_ATN BIT(3)
684 #define SCSI_CD BIT(2)
685 #define SCSI_MSG BIT(1)
686 #define SCSI_IOBIT BIT(0)
688 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
689 #define S_MSGO_PH (BIT(2)+BIT(1) )
690 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
691 #define S_DATAI_PH ( BIT(0))
692 #define S_DATAO_PH 0x00
693 #define S_ILL_PH ( BIT(1) )
695 #define hp_scsictrl_0 0x45
697 #define SEL_TAR BIT(6)
698 #define ENA_ATN BIT(4)
699 #define ENA_RESEL BIT(2)
700 #define SCSI_RST BIT(1)
701 #define ENA_SCAM_SEL BIT(0)
705 #define hp_portctrl_0 0x46
707 #define SCSI_PORT BIT(7)
708 #define SCSI_INBIT BIT(6)
709 #define DMA_PORT BIT(5)
710 #define DMA_RD BIT(4)
711 #define HOST_PORT BIT(3)
712 #define HOST_WRT BIT(2)
713 #define SCSI_BUS_EN BIT(1)
714 #define START_TO BIT(0)
716 #define hp_scsireset 0x47
718 #define SCSI_INI BIT(6)
719 #define SCAM_EN BIT(5)
720 #define DMA_RESET BIT(3)
721 #define HPSCSI_RESET BIT(2)
722 #define PROG_RESET BIT(1)
723 #define FIFO_CLR BIT(0)
725 #define hp_xfercnt_0 0x48
726 #define hp_xfercnt_2 0x4A
728 #define hp_fifodata_0 0x4C
729 #define hp_addstat 0x4E
731 #define SCAM_TIMER BIT(7)
732 #define SCSI_MODE8 BIT(3)
733 #define SCSI_PAR_ERR BIT(0)
735 #define hp_prgmcnt_0 0x4F
738 #define hp_selfid_0 0x50
739 #define hp_selfid_1 0x51
740 #define hp_arb_id 0x52
743 #define hp_select_id 0x53
746 #define hp_synctarg_base 0x54
747 #define hp_synctarg_12 0x54
748 #define hp_synctarg_13 0x55
749 #define hp_synctarg_14 0x56
750 #define hp_synctarg_15 0x57
752 #define hp_synctarg_8 0x58
753 #define hp_synctarg_9 0x59
754 #define hp_synctarg_10 0x5A
755 #define hp_synctarg_11 0x5B
757 #define hp_synctarg_4 0x5C
758 #define hp_synctarg_5 0x5D
759 #define hp_synctarg_6 0x5E
760 #define hp_synctarg_7 0x5F
762 #define hp_synctarg_0 0x60
763 #define hp_synctarg_1 0x61
764 #define hp_synctarg_2 0x62
765 #define hp_synctarg_3 0x63
767 #define NARROW_SCSI BIT(4)
768 #define DEFAULT_OFFSET 0x0F
770 #define hp_autostart_0 0x64
771 #define hp_autostart_1 0x65
772 #define hp_autostart_3 0x67
776 #define AUTO_IMMED BIT(5)
777 #define SELECT BIT(6)
778 #define END_DATA (BIT(7)+BIT(6))
780 #define hp_gp_reg_0 0x68
781 #define hp_gp_reg_1 0x69
782 #define hp_gp_reg_3 0x6B
784 #define hp_seltimeout 0x6C
787 #define TO_4ms 0x67 /* 3.9959ms */
789 #define TO_5ms 0x03 /* 4.9152ms */
790 #define TO_10ms 0x07 /* 11.xxxms */
791 #define TO_250ms 0x99 /* 250.68ms */
792 #define TO_290ms 0xB1 /* 289.99ms */
794 #define hp_clkctrl_0 0x6D
796 #define PWR_DWN BIT(6)
797 #define ACTdeassert BIT(4)
798 #define CLK_40MHZ (BIT(1) + BIT(0))
800 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
802 #define hp_fiforead 0x6E
803 #define hp_fifowrite 0x6F
805 #define hp_offsetctr 0x70
806 #define hp_xferstat 0x71
808 #define FIFO_EMPTY BIT(6)
810 #define hp_portctrl_1 0x72
812 #define CHK_SCSI_P BIT(3)
813 #define HOST_MODE8 BIT(0)
815 #define hp_xfer_pad 0x73
817 #define ID_UNLOCK BIT(3)
819 #define hp_scsidata_0 0x74
820 #define hp_scsidata_1 0x75
824 #define hp_aramBase 0x80
825 #define BIOS_DATA_OFFSET 0x60
826 #define BIOS_RELATIVE_CARD 0x64
831 #define AR3 (BITW(9) + BITW(8))
832 #define SDATA BITW(10)
835 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
837 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
841 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
843 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
846 #define ADATA_OUT 0x00
847 #define ADATA_IN BITW(8)
848 #define ACOMMAND BITW(10)
849 #define ASTATUS (BITW(10)+BITW(8))
850 #define AMSG_OUT (BITW(10)+BITW(9))
851 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
854 #define BRH_OP BITW(13) /* Branch */
858 #define EQUAL BITW(8)
859 #define NOT_EQ BITW(9)
861 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
864 #define FIFO_0 BITW(10)
867 #define MPM_OP BITW(15) /* Match phase and move data */
870 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
873 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
878 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
888 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
890 #define SSI_OP (BITW(15)+BITW(11))
893 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
894 #define SSI_IDO_STRT (IDO_STRT >> 8)
896 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
897 #define SSI_ITICKLE (ITICKLE >> 8)
899 #define SSI_IUNKWN (IUNKWN >> 8)
900 #define SSI_INO_CC (IUNKWN >> 8)
901 #define SSI_IRFAIL (IUNKWN >> 8)
904 #define NP 0x10 /*Next Phase */
905 #define NTCMD 0x02 /*Non- Tagged Command start */
906 #define CMDPZ 0x04 /*Command phase */
907 #define DINT 0x12 /*Data Out/In interrupt */
908 #define DI 0x13 /*Data Out */
909 #define DC 0x19 /*Disconnect Message */
910 #define ST 0x1D /*Status Phase */
911 #define UNKNWN 0x24 /*Unknown bus action */
912 #define CC 0x25 /*Command Completion failure */
913 #define TICK 0x26 /*New target reselected us. */
914 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
917 #define ID_MSG_STRT hp_aramBase + 0x00
918 #define NON_TAG_ID_MSG hp_aramBase + 0x06
919 #define CMD_STRT hp_aramBase + 0x08
920 #define SYNC_MSGS hp_aramBase + 0x08
926 #define TAG_STRT 0x00
927 #define DISCONNECT_START 0x10/2
928 #define END_DATA_START 0x14/2
929 #define CMD_ONLY_STRT CMDPZ/2
930 #define SELCHK_STRT SELCHK/2
940 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
941 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
943 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
945 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
947 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
948 WR_HARP32(port,hp_xfercnt_0,count),\
949 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
951 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
953 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
954 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
957 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
958 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
962 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
963 WR_HARPOON(port+hp_scsireset, 0x00))
965 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
966 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
968 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
969 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
971 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
972 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
974 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
975 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
980 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
981 static void FPT_ssel(unsigned long port, unsigned char p_card);
982 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
983 static void FPT_shandem(unsigned long port, unsigned char p_card,PSCCB pCurrSCCB);
984 static void FPT_stsyncn(unsigned long port, unsigned char p_card);
985 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
986 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
987 PSCCBMgr_tar_info currTar_Info);
988 static void FPT_sresb(unsigned long port, unsigned char p_card);
989 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
990 static void FPT_schkdd(unsigned long port, unsigned char p_card);
991 static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
992 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
993 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
995 static void FPT_SendMsg(unsigned long port, unsigned char message);
996 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
997 unsigned char error_code);
999 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
1000 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1002 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
1003 static void FPT_stwidn(unsigned long port, unsigned char p_card);
1004 static void FPT_siwidr(unsigned long port, unsigned char width);
1007 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1008 static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
1009 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1010 unsigned char p_card);
1011 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1012 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1013 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1014 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
1015 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1016 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1017 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1020 static void FPT_Wait1Second(unsigned long p_port);
1021 static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1022 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1023 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1024 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1025 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1026 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
1030 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1031 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1032 static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1033 static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1034 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1035 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1036 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
1038 static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1039 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1040 static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
1045 static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1046 static void FPT_BusMasterInit(unsigned long p_port);
1047 static void FPT_DiagEEPROM(unsigned long p_port);
1052 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1053 static void FPT_busMstrSGDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1054 static void FPT_busMstrDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1055 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB);
1056 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1059 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
1060 PSCCBcard pCurrCard, unsigned short p_int);
1062 static void FPT_SccbMgrTableInitAll(void);
1063 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1064 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1068 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1070 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1071 static void FPT_scbusf(unsigned long p_port);
1072 static void FPT_scsel(unsigned long p_port);
1073 static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1074 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1075 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1076 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1077 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1078 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
1079 static unsigned char FPT_scvalq(unsigned char p_quintet);
1080 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1081 static void FPT_scwtsel(unsigned long p_port);
1082 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1083 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
1084 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1087 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1088 static void FPT_autoLoadDefaultMap(unsigned long p_port);
1093 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1094 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1095 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1096 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1099 static unsigned char FPT_mbCards = 0;
1100 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1101 ' ', 'B', 'T', '-', '9', '3', '0', \
1102 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1103 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1105 static unsigned short FPT_default_intena = 0;
1108 static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
1111 /*---------------------------------------------------------------------
1113 * Function: FlashPoint_ProbeHostAdapter
1115 * Description: Setup and/or Search for cards and return info to caller.
1117 *---------------------------------------------------------------------*/
1119 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1121 static unsigned char first_time = 1;
1123 unsigned char i,j,id,ScamFlg;
1124 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1125 unsigned long ioport;
1126 PNVRamInfo pCurrNvRam;
1128 ioport = pCardInfo->si_baseaddr;
1131 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1132 return((int)FAILURE);
1134 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1135 return((int)FAILURE);
1137 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1138 return((int)FAILURE);
1140 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1141 return((int)FAILURE);
1144 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1146 /* For new Harpoon then check for sub_device ID LSB
1147 the bits(0-3) must be all ZERO for compatible with
1148 current version of SCCBMgr, else skip this Harpoon
1151 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1152 return((int)FAILURE);
1157 FPT_SccbMgrTableInitAll();
1162 if(FPT_RdStack(ioport, 0) != 0x00) {
1163 if(FPT_ChkIfChipInitialized(ioport) == 0)
1166 WR_HARPOON(ioport+hp_semaphore, 0x00);
1167 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1168 FPT_DiagEEPROM(ioport);
1172 if(FPT_mbCards < MAX_MB_CARDS) {
1173 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1175 pCurrNvRam->niBaseAddr = ioport;
1176 FPT_RNVRamData(pCurrNvRam);
1178 return((int) FAILURE);
1183 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1184 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1187 pCardInfo->si_id = pCurrNvRam->niAdapId;
1189 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1190 (unsigned char)0x0FF);
1192 pCardInfo->si_lun = 0x00;
1193 pCardInfo->si_fw_revision = ORION_FW_REV;
1200 for (id = 0; id < (16/2); id++) {
1203 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1204 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1205 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1207 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1209 for (i = 0; i < 2; temp >>=8,i++) {
1218 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1219 temp6 |= 0x8000; /* Fall through */
1220 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1221 temp5 |= 0x8000; /* Fall through */
1222 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1223 temp2 |= 0x8000; /* Fall through */
1224 case AUTO_RATE_00: /* Asynchronous */
1228 if (temp & DISC_ENABLE_BIT)
1231 if (temp & WIDE_NEGO_BIT)
1237 pCardInfo->si_per_targ_init_sync = temp2;
1238 pCardInfo->si_per_targ_no_disc = temp3;
1239 pCardInfo->si_per_targ_wide_nego = temp4;
1240 pCardInfo->si_per_targ_fast_nego = temp5;
1241 pCardInfo->si_per_targ_ultra_nego = temp6;
1244 i = pCurrNvRam->niSysConf;
1246 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1249 ScamFlg = pCurrNvRam->niScamConf;
1251 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1253 pCardInfo->si_flags = 0x0000;
1256 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1259 pCardInfo->si_flags |= SOFT_RESET;
1262 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1264 if (ScamFlg & SCAM_ENABLED)
1265 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1267 if (ScamFlg & SCAM_LEVEL2)
1268 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1270 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1272 j |= SCSI_TERM_ENA_L;
1274 WR_HARPOON(ioport+hp_bm_ctrl, j );
1276 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1278 j |= SCSI_TERM_ENA_H;
1280 WR_HARPOON(ioport+hp_ee_ctrl, j );
1282 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1284 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1286 pCardInfo->si_card_family = HARPOON_FAMILY;
1287 pCardInfo->si_bustype = BUSTYPE_PCI;
1290 pCardInfo->si_card_model[0] = '9';
1291 switch(pCurrNvRam->niModel & 0x0f){
1293 pCardInfo->si_card_model[1] = '3';
1294 pCardInfo->si_card_model[2] = '0';
1297 pCardInfo->si_card_model[1] = '5';
1298 pCardInfo->si_card_model[2] = '0';
1301 pCardInfo->si_card_model[1] = '3';
1302 pCardInfo->si_card_model[2] = '2';
1305 pCardInfo->si_card_model[1] = '5';
1306 pCardInfo->si_card_model[2] = '2';
1310 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1311 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1312 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1314 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1315 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1318 if (pCardInfo->si_card_model[1] == '3')
1320 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1321 pCardInfo->si_flags |= LOW_BYTE_TERM;
1323 else if (pCardInfo->si_card_model[2] == '0')
1325 temp = RD_HARPOON(ioport+hp_xfer_pad);
1326 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1327 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1328 pCardInfo->si_flags |= LOW_BYTE_TERM;
1329 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1330 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1331 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1332 WR_HARPOON(ioport+hp_xfer_pad, temp);
1336 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1337 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1338 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1339 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1341 for (i = 0; i < 8; i++)
1344 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1346 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1347 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1349 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1350 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1351 if (!(temp3 & BIT(7)))
1352 pCardInfo->si_flags |= LOW_BYTE_TERM;
1353 if (!(temp3 & BIT(6)))
1354 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1358 ARAM_ACCESS(ioport);
1360 for ( i = 0; i < 4; i++ ) {
1362 pCardInfo->si_XlatInfo[i] =
1363 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1366 /* return with -1 if no sort, else return with
1367 logical card number sorted by BIOS (zero-based) */
1369 pCardInfo->si_relative_cardnum =
1370 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1372 SGRAM_ACCESS(ioport);
1374 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1375 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1376 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1377 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1378 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1379 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1380 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1381 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1383 pCardInfo->si_present = 0x01;
1389 /*---------------------------------------------------------------------
1391 * Function: FlashPoint_HardwareResetHostAdapter
1393 * Description: Setup adapter for normal operation (hard reset).
1395 *---------------------------------------------------------------------*/
1397 static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1399 PSCCBcard CurrCard = NULL;
1400 PNVRamInfo pCurrNvRam;
1401 unsigned char i,j,thisCard, ScamFlg;
1402 unsigned short temp,sync_bit_map,id;
1403 unsigned long ioport;
1405 ioport = pCardInfo->si_baseaddr;
1407 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1409 if (thisCard == MAX_CARDS) {
1414 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1416 CurrCard = &FPT_BL_Card[thisCard];
1417 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1421 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1423 FPT_BL_Card[thisCard].ioPort = ioport;
1424 CurrCard = &FPT_BL_Card[thisCard];
1427 for(i = 0; i < FPT_mbCards; i++){
1428 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1429 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1431 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1432 CurrCard->cardIndex = thisCard;
1433 CurrCard->cardInfo = pCardInfo;
1439 pCurrNvRam = CurrCard->pNvRamInfo;
1442 ScamFlg = pCurrNvRam->niScamConf;
1445 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1449 FPT_BusMasterInit(ioport);
1450 FPT_XbowInit(ioport, ScamFlg);
1452 FPT_autoLoadDefaultMap(ioport);
1455 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1457 WR_HARPOON(ioport+hp_selfid_0, id);
1458 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1459 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1460 CurrCard->ourId = pCardInfo->si_id;
1462 i = (unsigned char) pCardInfo->si_flags;
1463 if (i & SCSI_PARITY_ENA)
1464 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1466 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1467 if (i & LOW_BYTE_TERM)
1468 j |= SCSI_TERM_ENA_L;
1469 WR_HARPOON(ioport+hp_bm_ctrl, j);
1471 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1472 if (i & HIGH_BYTE_TERM)
1473 j |= SCSI_TERM_ENA_H;
1474 WR_HARPOON(ioport+hp_ee_ctrl, j );
1477 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1479 FPT_sresb(ioport,thisCard);
1481 FPT_scini(thisCard, pCardInfo->si_id, 0);
1486 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1487 CurrCard->globalFlags |= F_NO_FILTER;
1490 if(pCurrNvRam->niSysConf & 0x10)
1491 CurrCard->globalFlags |= F_GREEN_PC;
1494 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1495 CurrCard->globalFlags |= F_GREEN_PC;
1498 /* Set global flag to indicate Re-Negotiation to be done on all
1501 if(pCurrNvRam->niScsiConf & 0x04)
1502 CurrCard->globalFlags |= F_DO_RENEGO;
1505 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1506 CurrCard->globalFlags |= F_DO_RENEGO;
1510 if(pCurrNvRam->niScsiConf & 0x08)
1511 CurrCard->globalFlags |= F_CONLUN_IO;
1514 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1515 CurrCard->globalFlags |= F_CONLUN_IO;
1519 temp = pCardInfo->si_per_targ_no_disc;
1521 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1524 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1527 sync_bit_map = 0x0001;
1529 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1532 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1533 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1534 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1536 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1538 for (i = 0; i < 2; temp >>=8,i++) {
1540 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1542 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1546 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1547 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1548 (unsigned char)(temp & ~EE_SYNC_MASK);
1551 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1554 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1556 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1560 else { /* NARROW SCSI */
1561 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1572 WR_HARPOON((ioport+hp_semaphore),
1573 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1575 return((unsigned long)CurrCard);
1578 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1581 unsigned long portBase;
1582 unsigned long regOffset;
1583 unsigned long scamData;
1584 unsigned long *pScamTbl;
1585 PNVRamInfo pCurrNvRam;
1587 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1590 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1591 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1596 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1597 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1599 portBase = pCurrNvRam->niBaseAddr;
1601 for(i = 0; i < MAX_SCSI_TAR; i++){
1602 regOffset = hp_aramBase + 64 + i*4;
1603 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
1604 scamData = *pScamTbl;
1605 WR_HARP32(portBase, regOffset, scamData);
1609 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1614 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1617 unsigned long portBase;
1618 unsigned long regOffset;
1619 unsigned long scamData;
1620 unsigned long *pScamTbl;
1622 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1623 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1624 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1625 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1626 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1628 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1629 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1631 portBase = pNvRamInfo->niBaseAddr;
1633 for(i = 0; i < MAX_SCSI_TAR; i++){
1634 regOffset = hp_aramBase + 64 + i*4;
1635 RD_HARP32(portBase, regOffset, scamData);
1636 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
1637 *pScamTbl = scamData;
1642 static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1644 WR_HARPOON(portBase + hp_stack_addr, index);
1645 return(RD_HARPOON(portBase + hp_stack_data));
1648 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
1650 WR_HARPOON(portBase + hp_stack_addr, index);
1651 WR_HARPOON(portBase + hp_stack_data, data);
1655 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1657 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1659 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1662 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1663 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1668 /*---------------------------------------------------------------------
1670 * Function: FlashPoint_StartCCB
1672 * Description: Start a command pointed to by p_Sccb. When the
1673 * command is completed it will be returned via the
1674 * callback function.
1676 *---------------------------------------------------------------------*/
1677 static void FlashPoint_StartCCB(unsigned long pCurrCard, PSCCB p_Sccb)
1679 unsigned long ioport;
1680 unsigned char thisCard, lun;
1682 CALL_BK_FN callback;
1684 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1685 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1687 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1690 p_Sccb->HostStatus = SCCB_COMPLETE;
1691 p_Sccb->SccbStatus = SCCB_ERROR;
1692 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1699 FPT_sinits(p_Sccb,thisCard);
1702 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1704 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1705 | SCCB_MGR_ACTIVE));
1707 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1709 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1710 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1714 ((PSCCBcard)pCurrCard)->cmdCounter++;
1716 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1718 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1720 if(p_Sccb->OperationCode == RESET_COMMAND)
1722 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1723 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1724 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1725 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1729 FPT_queueAddSccb(p_Sccb,thisCard);
1733 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1735 if(p_Sccb->OperationCode == RESET_COMMAND)
1737 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1738 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1739 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1740 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1744 FPT_queueAddSccb(p_Sccb,thisCard);
1750 MDISABLE_INT(ioport);
1752 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1753 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1757 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1758 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1759 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1762 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1763 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1768 if(p_Sccb->OperationCode == RESET_COMMAND)
1770 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1771 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1772 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1773 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1777 FPT_queueAddSccb(p_Sccb,thisCard);
1782 MENABLE_INT(ioport);
1788 /*---------------------------------------------------------------------
1790 * Function: FlashPoint_AbortCCB
1792 * Description: Abort the command pointed to by p_Sccb. When the
1793 * command is completed it will be returned via the
1794 * callback function.
1796 *---------------------------------------------------------------------*/
1797 static int FlashPoint_AbortCCB(unsigned long pCurrCard, PSCCB p_Sccb)
1799 unsigned long ioport;
1801 unsigned char thisCard;
1802 CALL_BK_FN callback;
1805 PSCCBMgr_tar_info currTar_Info;
1808 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1810 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1812 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1815 if (FPT_queueFindSccb(p_Sccb,thisCard))
1818 ((PSCCBcard)pCurrCard)->cmdCounter--;
1820 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1821 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1822 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1824 p_Sccb->SccbStatus = SCCB_ABORT;
1825 callback = p_Sccb->SccbCallback;
1833 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1835 p_Sccb->SccbStatus = SCCB_ABORT;
1843 TID = p_Sccb->TargID;
1846 if(p_Sccb->Sccb_tag)
1848 MDISABLE_INT(ioport);
1849 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1851 p_Sccb->SccbStatus = SCCB_ABORT;
1852 p_Sccb->Sccb_scsistat = ABORT_ST;
1853 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1855 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1857 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1858 FPT_ssel(ioport, thisCard);
1862 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1863 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1864 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1865 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1868 MENABLE_INT(ioport);
1873 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1875 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1878 p_Sccb->SccbStatus = SCCB_ABORT;
1889 /*---------------------------------------------------------------------
1891 * Function: FlashPoint_InterruptPending
1893 * Description: Do a quick check to determine if there is a pending
1894 * interrupt for this card and disable the IRQ Pin if so.
1896 *---------------------------------------------------------------------*/
1897 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1899 unsigned long ioport;
1901 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1903 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1915 /*---------------------------------------------------------------------
1917 * Function: FlashPoint_HandleInterrupt
1919 * Description: This is our entry point when an interrupt is generated
1920 * by the card and the upper level driver passes it on to
1923 *---------------------------------------------------------------------*/
1924 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1927 unsigned char thisCard,result,bm_status, bm_int_st;
1928 unsigned short hp_int;
1929 unsigned char i, target;
1930 unsigned long ioport;
1932 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1933 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1935 MDISABLE_INT(ioport);
1937 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1938 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1942 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1944 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1948 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1950 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1951 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1952 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1957 MENABLE_INT(ioport);
1963 else if (hp_int & ICMD_COMP) {
1965 if ( !(hp_int & BUS_FREE) ) {
1966 /* Wait for the BusFree before starting a new command. We
1967 must also check for being reselected since the BusFree
1968 may not show up if another device reselects us in 1.5us or
1969 less. SRR Wednesday, 3/8/1995.
1971 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1974 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1976 FPT_phaseChkFifo(ioport, thisCard);
1978 /* WRW_HARPOON((ioport+hp_intstat),
1979 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1982 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1984 FPT_autoCmdCmplt(ioport,thisCard);
1989 else if (hp_int & ITAR_DISC)
1992 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1994 FPT_phaseChkFifo(ioport, thisCard);
1998 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2000 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2001 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2003 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2006 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2007 FPT_queueDisconnect(currSCCB,thisCard);
2009 /* Wait for the BusFree before starting a new command. We
2010 must also check for being reselected since the BusFree
2011 may not show up if another device reselects us in 1.5us or
2012 less. SRR Wednesday, 3/8/1995.
2014 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2015 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2016 RD_HARPOON((ioport+hp_scsisig)) ==
2017 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2020 The additional loop exit condition above detects a timing problem
2021 with the revision D/E harpoon chips. The caller should reset the
2022 host adapter to recover when 0xFE is returned.
2024 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2026 MENABLE_INT(ioport);
2030 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2033 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2038 else if (hp_int & RSEL) {
2040 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2042 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2044 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2046 FPT_phaseChkFifo(ioport, thisCard);
2049 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2051 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2052 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2053 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2056 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2057 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2058 FPT_queueDisconnect(currSCCB,thisCard);
2061 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2062 FPT_phaseDecode(ioport,thisCard);
2067 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2070 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2071 FPT_phaseDecode(ioport,thisCard);
2076 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2078 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2079 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2081 FPT_phaseDecode(ioport,thisCard);
2085 /* Harpoon problem some SCSI target device respond to selection
2086 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2087 to latch the correct Target ID into reg. x53.
2088 The work around require to correct this reg. But when write to this
2089 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2090 need to read this reg first then restore it later. After update to 0x53 */
2092 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2093 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2094 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2095 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2096 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2097 WR_HARPOON(ioport+hp_fifowrite, i);
2098 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2102 else if (hp_int & XFER_CNT_0) {
2104 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2106 FPT_schkdd(ioport,thisCard);
2111 else if (hp_int & BUS_FREE) {
2113 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2115 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2117 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2120 FPT_phaseBusFree(ioport,thisCard);
2124 else if (hp_int & ITICKLE) {
2126 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2127 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2132 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2135 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2138 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2140 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2143 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2144 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2145 FPT_ssel(ioport,thisCard);
2154 MENABLE_INT(ioport);
2159 /*---------------------------------------------------------------------
2161 * Function: Sccb_bad_isr
2163 * Description: Some type of interrupt has occurred which is slightly
2164 * out of the ordinary. We will now decode it fully, in
2165 * this routine. This is broken up in an attempt to save
2168 *---------------------------------------------------------------------*/
2169 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
2170 PSCCBcard pCurrCard, unsigned short p_int)
2172 unsigned char temp, ScamFlg;
2173 PSCCBMgr_tar_info currTar_Info;
2174 PNVRamInfo pCurrNvRam;
2177 if (RD_HARPOON(p_port+hp_ext_status) &
2178 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2181 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2184 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2187 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2190 WR_HARPOON(p_port+hp_pci_stat_cfg,
2191 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2193 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2197 if (pCurrCard->currentSCCB != NULL)
2200 if (!pCurrCard->currentSCCB->HostStatus)
2201 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2203 FPT_sxfrp(p_port,p_card);
2205 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2206 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2207 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2208 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2210 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2212 FPT_phaseDecode(p_port,p_card);
2218 else if (p_int & RESET)
2221 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2222 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2223 if (pCurrCard->currentSCCB != NULL) {
2225 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2227 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2231 DISABLE_AUTO(p_port);
2233 FPT_sresb(p_port,p_card);
2235 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2237 pCurrNvRam = pCurrCard->pNvRamInfo;
2239 ScamFlg = pCurrNvRam->niScamConf;
2242 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2245 FPT_XbowInit(p_port, ScamFlg);
2247 FPT_scini(p_card, pCurrCard->ourId, 0);
2253 else if (p_int & FIFO) {
2255 WRW_HARPOON((p_port+hp_intstat), FIFO);
2257 if (pCurrCard->currentSCCB != NULL)
2258 FPT_sxfrp(p_port,p_card);
2261 else if (p_int & TIMEOUT)
2264 DISABLE_AUTO(p_port);
2266 WRW_HARPOON((p_port+hp_intstat),
2267 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2269 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2272 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2273 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2274 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2275 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2277 currTar_Info->TarLUNBusy[0] = 0;
2280 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2282 currTar_Info->TarSyncCtrl = 0;
2283 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2286 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2288 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2291 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2293 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2297 else if (p_int & SCAM_SEL)
2300 FPT_scarb(p_port,LEVEL2_TAR);
2302 FPT_scasid(p_card, p_port);
2306 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2313 /*---------------------------------------------------------------------
2315 * Function: SccbMgrTableInit
2317 * Description: Initialize all Sccb manager data structures.
2319 *---------------------------------------------------------------------*/
2321 static void FPT_SccbMgrTableInitAll()
2323 unsigned char thisCard;
2325 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2327 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2329 FPT_BL_Card[thisCard].ioPort = 0x00;
2330 FPT_BL_Card[thisCard].cardInfo = NULL;
2331 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2332 FPT_BL_Card[thisCard].ourId = 0x00;
2333 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2338 /*---------------------------------------------------------------------
2340 * Function: SccbMgrTableInit
2342 * Description: Initialize all Sccb manager data structures.
2344 *---------------------------------------------------------------------*/
2346 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2348 unsigned char scsiID, qtag;
2350 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2352 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2355 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2357 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2358 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2359 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2362 pCurrCard->scanIndex = 0x00;
2363 pCurrCard->currentSCCB = NULL;
2364 pCurrCard->globalFlags = 0x00;
2365 pCurrCard->cmdCounter = 0x00;
2366 pCurrCard->tagQ_Lst = 0x01;
2367 pCurrCard->discQCount = 0;
2373 /*---------------------------------------------------------------------
2375 * Function: SccbMgrTableInit
2377 * Description: Initialize all Sccb manager data structures.
2379 *---------------------------------------------------------------------*/
2381 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2384 unsigned char lun, qtag;
2385 PSCCBMgr_tar_info currTar_Info;
2387 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2389 currTar_Info->TarSelQ_Cnt = 0;
2390 currTar_Info->TarSyncCtrl = 0;
2392 currTar_Info->TarSelQ_Head = NULL;
2393 currTar_Info->TarSelQ_Tail = NULL;
2394 currTar_Info->TarTagQ_Cnt = 0;
2395 currTar_Info->TarLUN_CA = 0;
2398 for (lun = 0; lun < MAX_LUN; lun++)
2400 currTar_Info->TarLUNBusy[lun] = 0;
2401 currTar_Info->LunDiscQ_Idx[lun] = 0;
2404 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2406 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2408 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2410 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2411 FPT_BL_Card[p_card].discQCount--;
2418 /*---------------------------------------------------------------------
2422 * Description: Read in a message byte from the SCSI bus, and check
2423 * for a parity error.
2425 *---------------------------------------------------------------------*/
2427 static unsigned char FPT_sfm(unsigned long port, PSCCB pCurrSCCB)
2429 unsigned char message;
2430 unsigned short TimeOutLoop;
2433 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2434 (TimeOutLoop++ < 20000) ){}
2437 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2439 message = RD_HARPOON(port+hp_scsidata_0);
2441 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2444 if (TimeOutLoop > 20000)
2445 message = 0x00; /* force message byte = 0 if Time Out on Req */
2447 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2448 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2450 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2451 WR_HARPOON(port+hp_xferstat, 0);
2452 WR_HARPOON(port+hp_fiforead, 0);
2453 WR_HARPOON(port+hp_fifowrite, 0);
2454 if (pCurrSCCB != NULL)
2456 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2461 ACCEPT_MSG_ATN(port);
2463 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2464 (TimeOutLoop++ < 20000) ){}
2465 if (TimeOutLoop > 20000)
2467 WRW_HARPOON((port+hp_intstat), PARITY);
2470 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2472 WRW_HARPOON((port+hp_intstat), PARITY);
2475 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2477 RD_HARPOON(port+hp_scsidata_0);
2479 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2484 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2485 WR_HARPOON(port+hp_xferstat, 0);
2486 WR_HARPOON(port+hp_fiforead, 0);
2487 WR_HARPOON(port+hp_fifowrite, 0);
2492 /*---------------------------------------------------------------------
2494 * Function: FPT_ssel
2496 * Description: Load up automation and select target device.
2498 *---------------------------------------------------------------------*/
2500 static void FPT_ssel(unsigned long port, unsigned char p_card)
2503 unsigned char auto_loaded, i, target, *theCCB;
2505 unsigned long cdb_reg;
2508 PSCCBMgr_tar_info currTar_Info;
2509 unsigned char lastTag, lun;
2511 CurrCard = &FPT_BL_Card[p_card];
2512 currSCCB = CurrCard->currentSCCB;
2513 target = currSCCB->TargID;
2514 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2515 lastTag = CurrCard->tagQ_Lst;
2520 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2521 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2523 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2524 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2526 lun = currSCCB->Lun;
2531 if (CurrCard->globalFlags & F_TAG_STARTED)
2533 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2535 if ((currTar_Info->TarLUN_CA == 0)
2536 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2540 if (currTar_Info->TarTagQ_Cnt !=0)
2542 currTar_Info->TarLUNBusy[lun] = 1;
2543 FPT_queueSelectFail(CurrCard,p_card);
2549 currTar_Info->TarLUNBusy[lun] = 1;
2552 } /*End non-tagged */
2555 currTar_Info->TarLUNBusy[lun] = 1;
2558 } /*!Use cmd Q Tagged */
2561 if (currTar_Info->TarLUN_CA == 1)
2563 FPT_queueSelectFail(CurrCard,p_card);
2568 currTar_Info->TarLUNBusy[lun] = 1;
2570 } /*else use cmd Q tagged */
2572 } /*if glob tagged started */
2575 currTar_Info->TarLUNBusy[lun] = 1;
2580 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2581 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2582 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2584 if(CurrCard->discQCount >= QUEUE_DEPTH)
2586 currTar_Info->TarLUNBusy[lun] = 1;
2587 FPT_queueSelectFail(CurrCard,p_card);
2591 for (i = 1; i < QUEUE_DEPTH; i++)
2593 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2594 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2596 CurrCard->tagQ_Lst = lastTag;
2597 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2598 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2599 CurrCard->discQCount++;
2603 if(i == QUEUE_DEPTH)
2605 currTar_Info->TarLUNBusy[lun] = 1;
2606 FPT_queueSelectFail(CurrCard,p_card);
2616 WR_HARPOON(port+hp_select_id, target);
2617 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2619 if (currSCCB->OperationCode == RESET_COMMAND) {
2620 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2621 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2623 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2625 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2627 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2629 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2631 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2633 currTar_Info->TarSyncCtrl = 0;
2634 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2637 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2639 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2642 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2643 FPT_SccbMgrTableInitTarget(p_card, target);
2647 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2649 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2650 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2652 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2654 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2655 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2656 >> 6) | (unsigned char)0x20)));
2657 WRW_HARPOON((port+SYNC_MSGS+2),
2658 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2659 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2661 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2666 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2667 auto_loaded = FPT_siwidn(port,p_card);
2668 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2671 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2672 == SYNC_SUPPORTED)) {
2673 auto_loaded = FPT_sisyncn(port,p_card, 0);
2674 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2681 if (currSCCB->ControlByte & F_USE_CMD_Q)
2684 CurrCard->globalFlags |= F_TAG_STARTED;
2686 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2689 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2691 /* Fix up the start instruction with a jump to
2692 Non-Tag-CMD handling */
2693 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2695 WRW_HARPOON((port+NON_TAG_ID_MSG),
2696 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2698 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2700 /* Setup our STATE so we know what happend when
2701 the wheels fall off. */
2702 currSCCB->Sccb_scsistat = SELECT_ST;
2704 currTar_Info->TarLUNBusy[lun] = 1;
2709 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2711 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2712 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2713 >> 6) | (unsigned char)0x20)));
2715 for (i = 1; i < QUEUE_DEPTH; i++)
2717 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2718 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2720 WRW_HARPOON((port+ID_MSG_STRT+6),
2721 (MPM_OP+AMSG_OUT+lastTag));
2722 CurrCard->tagQ_Lst = lastTag;
2723 currSCCB->Sccb_tag = lastTag;
2724 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2725 CurrCard->discQCount++;
2731 if ( i == QUEUE_DEPTH )
2733 currTar_Info->TarLUNBusy[lun] = 1;
2734 FPT_queueSelectFail(CurrCard,p_card);
2739 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2741 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2748 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2750 WRW_HARPOON((port+NON_TAG_ID_MSG),
2751 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2753 currSCCB->Sccb_scsistat = SELECT_ST;
2755 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2759 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2761 cdb_reg = port + CMD_STRT;
2763 for (i=0; i < currSCCB->CdbLength; i++)
2765 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2770 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2771 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2775 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2776 WR_HARPOON(port+hp_xferstat, 0x00);
2778 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2780 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2783 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2785 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2790 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2791 auto_loaded |= AUTO_IMMED; */
2792 auto_loaded = AUTO_IMMED;
2796 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2803 /*---------------------------------------------------------------------
2805 * Function: FPT_sres
2807 * Description: Hookup the correct CCB and handle the incoming messages.
2809 *---------------------------------------------------------------------*/
2811 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
2814 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2817 PSCCBMgr_tar_info currTar_Info;
2823 if(pCurrCard->currentSCCB != NULL)
2825 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2829 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2832 currSCCB = pCurrCard->currentSCCB;
2833 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2835 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2836 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2838 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2840 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2841 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2843 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2844 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2846 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2847 if(currSCCB->Sccb_scsistat != ABORT_ST)
2849 pCurrCard->discQCount--;
2850 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2856 currTar_Info->TarLUNBusy[0] = 0;
2857 if(currSCCB->Sccb_tag)
2859 if(currSCCB->Sccb_scsistat != ABORT_ST)
2861 pCurrCard->discQCount--;
2862 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2866 if(currSCCB->Sccb_scsistat != ABORT_ST)
2868 pCurrCard->discQCount--;
2869 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2874 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2877 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2880 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2881 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2888 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2892 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2894 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2897 WRW_HARPOON((port+hp_intstat), PHASE);
2902 WRW_HARPOON((port+hp_intstat), PHASE);
2903 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2906 message = FPT_sfm(port,pCurrCard->currentSCCB);
2910 if (message <= (0x80 | LUN_MASK))
2912 lun = message & (unsigned char)LUN_MASK;
2914 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2916 if (currTar_Info->TarTagQ_Cnt != 0)
2919 if (!(currTar_Info->TarLUN_CA))
2921 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2924 message = FPT_sfm(port,pCurrCard->currentSCCB);
2935 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2943 } /*End Q cnt != 0 */
2945 } /*End Tag cmds supported! */
2947 } /*End valid ID message. */
2952 ACCEPT_MSG_ATN(port);
2955 } /* End good id message. */
2965 ACCEPT_MSG_ATN(port);
2967 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2968 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2969 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2977 if(msgRetryCount == 1)
2979 FPT_SendMsg(port, SMPARITY);
2983 FPT_SendMsg(port, SMDEV_RESET);
2985 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2987 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2990 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2994 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2997 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
3001 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3002 FPT_SccbMgrTableInitTarget(p_card,our_target);
3006 }while(message == 0);
3010 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3011 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3013 currTar_Info->TarLUNBusy[lun] = 1;
3014 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3015 if(pCurrCard->currentSCCB != NULL)
3021 ACCEPT_MSG_ATN(port);
3026 currTar_Info->TarLUNBusy[0] = 1;
3031 if (pCurrCard->discQ_Tbl[tag] != NULL)
3033 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3034 currTar_Info->TarTagQ_Cnt--;
3039 ACCEPT_MSG_ATN(port);
3043 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3044 if(pCurrCard->currentSCCB != NULL)
3050 ACCEPT_MSG_ATN(port);
3055 if(pCurrCard->currentSCCB != NULL)
3057 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3059 /* During Abort Tag command, the target could have got re-selected
3060 and completed the command. Check the select Q and remove the CCB
3061 if it is in the Select Q */
3062 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3067 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3068 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3069 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3072 static void FPT_SendMsg(unsigned long port, unsigned char message)
3074 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3076 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3079 WRW_HARPOON((port+hp_intstat), PHASE);
3084 WRW_HARPOON((port+hp_intstat), PHASE);
3085 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3087 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3090 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3092 WR_HARPOON(port+hp_scsidata_0,message);
3094 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3098 WR_HARPOON(port+hp_portctrl_0, 0x00);
3100 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3101 (message == SMABORT_TAG) )
3103 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3105 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3107 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3113 /*---------------------------------------------------------------------
3115 * Function: FPT_sdecm
3117 * Description: Determine the proper responce to the message from the
3120 *---------------------------------------------------------------------*/
3121 static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
3125 PSCCBMgr_tar_info currTar_Info;
3127 CurrCard = &FPT_BL_Card[p_card];
3128 currSCCB = CurrCard->currentSCCB;
3130 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3132 if (message == SMREST_DATA_PTR)
3134 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3136 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3138 FPT_hostDataXferRestart(currSCCB);
3142 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3145 else if (message == SMCMD_COMP)
3149 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3151 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3152 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3159 else if ((message == SMNO_OP) || (message >= SMIDENT)
3160 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3164 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3167 else if (message == SMREJECT)
3170 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3171 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3172 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3173 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3176 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3181 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3182 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3184 if(currSCCB->Lun == 0x00)
3186 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3189 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3191 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3194 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3198 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3199 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3201 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3205 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3207 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3208 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3211 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3212 CurrCard->discQCount--;
3213 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3214 currSCCB->Sccb_tag = 0x00;
3219 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3223 if(currSCCB->Lun == 0x00)
3225 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3226 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3233 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3234 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3235 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3237 currTar_Info->TarLUNBusy[0] = 1;
3240 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3242 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3251 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3252 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3254 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3256 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3261 else if (message == SMEXT)
3265 FPT_shandem(port,p_card,currSCCB);
3268 else if (message == SMIGNORWR)
3271 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3273 message = FPT_sfm(port,currSCCB);
3275 if(currSCCB->Sccb_scsimsg != SMPARITY)
3277 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3284 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3285 currSCCB->Sccb_scsimsg = SMREJECT;
3287 ACCEPT_MSG_ATN(port);
3288 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3293 /*---------------------------------------------------------------------
3295 * Function: FPT_shandem
3297 * Description: Decide what to do with the extended message.
3299 *---------------------------------------------------------------------*/
3300 static void FPT_shandem(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
3302 unsigned char length,message;
3304 length = FPT_sfm(port,pCurrSCCB);
3309 message = FPT_sfm(port,pCurrSCCB);
3313 if (message == SMSYNC)
3320 FPT_stsyncn(port,p_card);
3325 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3326 ACCEPT_MSG_ATN(port);
3329 else if (message == SMWDTR)
3336 FPT_stwidn(port,p_card);
3341 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3342 ACCEPT_MSG_ATN(port);
3344 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3350 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3351 ACCEPT_MSG_ATN(port);
3353 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3358 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3360 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3364 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3365 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3370 /*---------------------------------------------------------------------
3372 * Function: FPT_sisyncn
3374 * Description: Read in a message byte from the SCSI bus, and check
3375 * for a parity error.
3377 *---------------------------------------------------------------------*/
3379 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
3382 PSCCBMgr_tar_info currTar_Info;
3384 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3385 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3387 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3390 WRW_HARPOON((port+ID_MSG_STRT),
3391 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3393 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3395 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3396 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3397 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3400 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3402 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3404 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3406 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3408 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3410 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3413 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3416 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3417 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3418 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3423 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3424 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3425 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3429 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3438 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3439 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3446 /*---------------------------------------------------------------------
3448 * Function: FPT_stsyncn
3450 * Description: The has sent us a Sync Nego message so handle it as
3453 *---------------------------------------------------------------------*/
3454 static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3456 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3458 PSCCBMgr_tar_info currTar_Info;
3460 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3461 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3463 sync_msg = FPT_sfm(port,currSCCB);
3465 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3467 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3474 offset = FPT_sfm(port,currSCCB);
3476 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3478 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3482 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3484 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3486 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3488 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3490 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3492 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3495 our_sync_msg = 0; /* Message = Async */
3497 if (sync_msg < our_sync_msg) {
3498 sync_msg = our_sync_msg; /*if faster, then set to max. */
3501 if (offset == ASYNC)
3504 if (offset > MAX_OFFSET)
3505 offset = MAX_OFFSET;
3511 sync_reg = 0x20; /* Use 10MB/s */
3515 sync_reg = 0x40; /* Use 6.6MB/s */
3519 sync_reg = 0x60; /* Use 5MB/s */
3523 sync_reg = 0x80; /* Use 4MB/s */
3527 sync_reg = 0xA0; /* Use 3.33MB/s */
3531 sync_reg = 0xC0; /* Use 2.85MB/s */
3535 sync_reg = 0xE0; /* Use 2.5MB/s */
3537 if (sync_msg > 100) {
3539 sync_reg = 0x00; /* Use ASYNC */
3544 if (currTar_Info->TarStatus & WIDE_ENABLED)
3550 sync_reg |= (offset | NARROW_SCSI);
3552 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3555 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3560 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3561 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3563 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3569 ACCEPT_MSG_ATN(port);
3571 FPT_sisyncr(port,sync_msg,offset);
3573 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3574 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3579 /*---------------------------------------------------------------------
3581 * Function: FPT_sisyncr
3583 * Description: Answer the targets sync message.
3585 *---------------------------------------------------------------------*/
3586 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
3589 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3590 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3591 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3592 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3593 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3594 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3595 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3598 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3599 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3601 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3603 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3608 /*---------------------------------------------------------------------
3610 * Function: FPT_siwidn
3612 * Description: Read in a message byte from the SCSI bus, and check
3613 * for a parity error.
3615 *---------------------------------------------------------------------*/
3617 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3620 PSCCBMgr_tar_info currTar_Info;
3622 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3623 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3625 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3628 WRW_HARPOON((port+ID_MSG_STRT),
3629 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3631 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3633 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3634 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3635 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3636 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3637 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3638 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3640 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3643 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3644 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3651 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3652 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3654 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3661 /*---------------------------------------------------------------------
3663 * Function: FPT_stwidn
3665 * Description: The has sent us a Wide Nego message so handle it as
3668 *---------------------------------------------------------------------*/
3669 static void FPT_stwidn(unsigned long port, unsigned char p_card)
3671 unsigned char width;
3673 PSCCBMgr_tar_info currTar_Info;
3675 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3676 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3678 width = FPT_sfm(port,currSCCB);
3680 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3682 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3687 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3691 currTar_Info->TarStatus |= WIDE_ENABLED;
3695 width = NARROW_SCSI;
3696 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3700 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3703 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3708 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3710 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3712 ACCEPT_MSG_ATN(port);
3714 FPT_sisyncn(port,p_card, 1);
3715 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3721 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3728 ACCEPT_MSG_ATN(port);
3730 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3735 FPT_siwidr(port,width);
3737 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3742 /*---------------------------------------------------------------------
3744 * Function: FPT_siwidr
3746 * Description: Answer the targets Wide nego message.
3748 *---------------------------------------------------------------------*/
3749 static void FPT_siwidr(unsigned long port, unsigned char width)
3752 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3753 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3754 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3755 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3756 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3757 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3760 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3761 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3763 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3765 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3770 /*---------------------------------------------------------------------
3772 * Function: FPT_sssyncv
3774 * Description: Write the desired value to the Sync Register for the
3777 *---------------------------------------------------------------------*/
3778 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
3779 PSCCBMgr_tar_info currTar_Info)
3781 unsigned char index;
3788 index = 12; /* hp_synctarg_0 */
3791 index = 13; /* hp_synctarg_1 */
3794 index = 14; /* hp_synctarg_2 */
3797 index = 15; /* hp_synctarg_3 */
3800 index = 8; /* hp_synctarg_4 */
3803 index = 9; /* hp_synctarg_5 */
3806 index = 10; /* hp_synctarg_6 */
3809 index = 11; /* hp_synctarg_7 */
3812 index = 4; /* hp_synctarg_8 */
3815 index = 5; /* hp_synctarg_9 */
3818 index = 6; /* hp_synctarg_10 */
3821 index = 7; /* hp_synctarg_11 */
3824 index = 0; /* hp_synctarg_12 */
3827 index = 1; /* hp_synctarg_13 */
3830 index = 2; /* hp_synctarg_14 */
3833 index = 3; /* hp_synctarg_15 */
3837 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3839 currTar_Info->TarSyncCtrl = p_sync_value;
3843 /*---------------------------------------------------------------------
3845 * Function: FPT_sresb
3847 * Description: Reset the desired card's SCSI bus.
3849 *---------------------------------------------------------------------*/
3850 static void FPT_sresb(unsigned long port, unsigned char p_card)
3852 unsigned char scsiID, i;
3854 PSCCBMgr_tar_info currTar_Info;
3856 WR_HARPOON(port+hp_page_ctrl,
3857 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3858 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3860 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3862 scsiID = RD_HARPOON(port+hp_seltimeout);
3863 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3864 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3866 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3868 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3870 WR_HARPOON(port+hp_seltimeout,scsiID);
3872 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3874 FPT_Wait(port, TO_5ms);
3876 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3878 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3880 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3882 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3884 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3886 currTar_Info->TarSyncCtrl = 0;
3887 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3890 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3892 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3895 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3897 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3900 FPT_BL_Card[p_card].scanIndex = 0x00;
3901 FPT_BL_Card[p_card].currentSCCB = NULL;
3902 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3904 FPT_BL_Card[p_card].cmdCounter = 0x00;
3905 FPT_BL_Card[p_card].discQCount = 0x00;
3906 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3908 for(i = 0; i < QUEUE_DEPTH; i++)
3909 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3911 WR_HARPOON(port+hp_page_ctrl,
3912 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3916 /*---------------------------------------------------------------------
3918 * Function: FPT_ssenss
3920 * Description: Setup for the Auto Sense command.
3922 *---------------------------------------------------------------------*/
3923 static void FPT_ssenss(PSCCBcard pCurrCard)
3928 currSCCB = pCurrCard->currentSCCB;
3931 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3933 for (i = 0; i < 6; i++) {
3935 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3938 currSCCB->CdbLength = SIX_BYTE_CMD;
3939 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3940 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3941 currSCCB->Cdb[2] = 0x00;
3942 currSCCB->Cdb[3] = 0x00;
3943 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3944 currSCCB->Cdb[5] = 0x00;
3946 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3948 currSCCB->Sccb_ATC = 0x00;
3950 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3952 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3954 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3956 currSCCB->ControlByte = 0x00;
3958 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3963 /*---------------------------------------------------------------------
3965 * Function: FPT_sxfrp
3967 * Description: Transfer data into the bit bucket until the device
3968 * decides to switch phase.
3970 *---------------------------------------------------------------------*/
3972 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3974 unsigned char curr_phz;
3977 DISABLE_AUTO(p_port);
3979 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3981 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3985 /* If the Automation handled the end of the transfer then do not
3986 match the phase or we will get out of sync with the ISR. */
3988 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3991 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3993 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3995 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3998 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4000 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4001 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
4003 if (curr_phz & (unsigned char)SCSI_IOBIT)
4005 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4007 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4009 RD_HARPOON(p_port+hp_fifodata_0);
4014 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4015 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4017 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4020 } /* End of While loop for padding data I/O phase */
4022 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4024 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4028 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4029 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4031 RD_HARPOON(p_port+hp_fifodata_0);
4034 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4036 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4037 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4039 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4040 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4045 /*---------------------------------------------------------------------
4047 * Function: FPT_schkdd
4049 * Description: Make sure data has been flushed from both FIFOs and abort
4050 * the operations if necessary.
4052 *---------------------------------------------------------------------*/
4054 static void FPT_schkdd(unsigned long port, unsigned char p_card)
4056 unsigned short TimeOutLoop;
4057 unsigned char sPhase;
4061 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4064 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4065 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4071 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4074 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4076 currSCCB->Sccb_XferCnt = 1;
4078 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4079 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4080 WR_HARPOON(port+hp_xferstat, 0x00);
4086 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4088 currSCCB->Sccb_XferCnt = 0;
4091 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4092 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4094 currSCCB->HostStatus = SCCB_PARITY_ERR;
4095 WRW_HARPOON((port+hp_intstat), PARITY);
4099 FPT_hostDataXferAbort(port,p_card,currSCCB);
4102 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4106 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4108 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4111 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4114 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4117 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4121 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4122 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4123 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4124 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4125 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4128 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4130 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4132 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4133 FPT_phaseDataIn(port,p_card);
4137 FPT_phaseDataOut(port,p_card);
4142 FPT_sxfrp(port,p_card);
4143 if (!(RDW_HARPOON((port+hp_intstat)) &
4144 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4146 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4147 FPT_phaseDecode(port,p_card);
4154 WR_HARPOON(port+hp_portctrl_0, 0x00);
4159 /*---------------------------------------------------------------------
4161 * Function: FPT_sinits
4163 * Description: Setup SCCB manager fields in this SCCB.
4165 *---------------------------------------------------------------------*/
4167 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
4169 PSCCBMgr_tar_info currTar_Info;
4171 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4175 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4177 p_sccb->Sccb_XferState = 0x00;
4178 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4180 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4181 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4183 p_sccb->Sccb_SGoffset = 0;
4184 p_sccb->Sccb_XferState = F_SG_XFER;
4185 p_sccb->Sccb_XferCnt = 0x00;
4188 if (p_sccb->DataLength == 0x00)
4190 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4192 if (p_sccb->ControlByte & F_USE_CMD_Q)
4194 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4195 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4198 currTar_Info->TarStatus |= TAG_Q_TRYING;
4201 /* For !single SCSI device in system & device allow Disconnect
4202 or command is tag_q type then send Cmd with Disconnect Enable
4203 else send Cmd with Disconnect Disable */
4206 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4207 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4208 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4210 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4211 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4212 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4217 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4220 p_sccb->HostStatus = 0x00;
4221 p_sccb->TargetStatus = 0x00;
4222 p_sccb->Sccb_tag = 0x00;
4223 p_sccb->Sccb_MGRFlags = 0x00;
4224 p_sccb->Sccb_sgseg = 0x00;
4225 p_sccb->Sccb_ATC = 0x00;
4226 p_sccb->Sccb_savedATC = 0x00;
4228 p_sccb->SccbVirtDataPtr = 0x00;
4229 p_sccb->Sccb_forwardlink = NULL;
4230 p_sccb->Sccb_backlink = NULL;
4232 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4233 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4234 p_sccb->Sccb_scsimsg = SMNO_OP;
4239 /*---------------------------------------------------------------------
4241 * Function: Phase Decode
4243 * Description: Determine the phase and call the appropriate function.
4245 *---------------------------------------------------------------------*/
4247 static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4249 unsigned char phase_ref;
4250 void (*phase) (unsigned long, unsigned char);
4253 DISABLE_AUTO(p_port);
4255 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4257 phase = FPT_s_PhaseTbl[phase_ref];
4259 (*phase)(p_port, p_card); /* Call the correct phase func */
4264 /*---------------------------------------------------------------------
4266 * Function: Data Out Phase
4268 * Description: Start up both the BusMaster and Xbow.
4270 *---------------------------------------------------------------------*/
4272 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4277 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4278 if (currSCCB == NULL)
4280 return; /* Exit if No SCCB record */
4283 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4284 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4286 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4288 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4290 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4292 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4294 if (currSCCB->Sccb_XferCnt == 0) {
4297 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4298 (currSCCB->HostStatus == SCCB_COMPLETE))
4299 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4301 FPT_sxfrp(port,p_card);
4302 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4303 FPT_phaseDecode(port,p_card);
4308 /*---------------------------------------------------------------------
4310 * Function: Data In Phase
4312 * Description: Startup the BusMaster and the XBOW.
4314 *---------------------------------------------------------------------*/
4316 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4321 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4323 if (currSCCB == NULL)
4325 return; /* Exit if No SCCB record */
4329 currSCCB->Sccb_scsistat = DATA_IN_ST;
4330 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4331 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4333 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4335 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4337 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4339 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4341 if (currSCCB->Sccb_XferCnt == 0) {
4344 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4345 (currSCCB->HostStatus == SCCB_COMPLETE))
4346 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4348 FPT_sxfrp(port,p_card);
4349 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4350 FPT_phaseDecode(port,p_card);
4355 /*---------------------------------------------------------------------
4357 * Function: Command Phase
4359 * Description: Load the CDB into the automation and start it up.
4361 *---------------------------------------------------------------------*/
4363 static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4366 unsigned long cdb_reg;
4369 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4371 if (currSCCB->OperationCode == RESET_COMMAND) {
4373 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4374 currSCCB->CdbLength = SIX_BYTE_CMD;
4377 WR_HARPOON(p_port+hp_scsisig, 0x00);
4379 ARAM_ACCESS(p_port);
4382 cdb_reg = p_port + CMD_STRT;
4384 for (i=0; i < currSCCB->CdbLength; i++) {
4386 if (currSCCB->OperationCode == RESET_COMMAND)
4388 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4391 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4395 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4396 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4398 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4400 currSCCB->Sccb_scsistat = COMMAND_ST;
4402 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4403 SGRAM_ACCESS(p_port);
4407 /*---------------------------------------------------------------------
4409 * Function: Status phase
4411 * Description: Bring in the status and command complete message bytes
4413 *---------------------------------------------------------------------*/
4415 static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4417 /* Start-up the automation to finish off this command and let the
4418 isr handle the interrupt for command complete when it comes in.
4419 We could wait here for the interrupt to be generated?
4422 WR_HARPOON(port+hp_scsisig, 0x00);
4424 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4428 /*---------------------------------------------------------------------
4430 * Function: Phase Message Out
4432 * Description: Send out our message (if we have one) and handle whatever
4435 *---------------------------------------------------------------------*/
4437 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4439 unsigned char message,scsiID;
4441 PSCCBMgr_tar_info currTar_Info;
4443 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4445 if (currSCCB != NULL) {
4447 message = currSCCB->Sccb_scsimsg;
4448 scsiID = currSCCB->TargID;
4450 if (message == SMDEV_RESET)
4454 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4455 currTar_Info->TarSyncCtrl = 0;
4456 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4458 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4461 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4465 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4468 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4472 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4473 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4475 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4477 currSCCB->HostStatus = SCCB_COMPLETE;
4478 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4480 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4481 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4486 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4490 if(message == SMNO_OP)
4492 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4494 FPT_ssel(port,p_card);
4502 if (message == SMABORT)
4504 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4513 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4516 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4518 WR_HARPOON(port+hp_scsidata_0,message);
4520 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4524 WR_HARPOON(port+hp_portctrl_0, 0x00);
4526 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4527 (message == SMABORT_TAG) )
4530 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4532 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4534 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4536 if (currSCCB != NULL)
4539 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4540 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4541 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4543 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4545 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4550 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4557 FPT_sxfrp(port,p_card);
4564 if(message == SMPARITY)
4566 currSCCB->Sccb_scsimsg = SMNO_OP;
4567 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4571 FPT_sxfrp(port,p_card);
4577 /*---------------------------------------------------------------------
4579 * Function: Message In phase
4581 * Description: Bring in the message and determine what to do with it.
4583 *---------------------------------------------------------------------*/
4585 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4587 unsigned char message;
4590 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4592 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4595 FPT_phaseChkFifo(port, p_card);
4598 message = RD_HARPOON(port+hp_scsidata_0);
4599 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4602 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4609 message = FPT_sfm(port,currSCCB);
4614 FPT_sdecm(message,port,p_card);
4619 if(currSCCB->Sccb_scsimsg != SMPARITY)
4621 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4628 /*---------------------------------------------------------------------
4630 * Function: Illegal phase
4632 * Description: Target switched to some illegal phase, so all we can do
4633 * is report an error back to the host (if that is possible)
4634 * and send an ABORT message to the misbehaving target.
4636 *---------------------------------------------------------------------*/
4638 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4642 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4644 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4645 if (currSCCB != NULL) {
4647 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4648 currSCCB->Sccb_scsistat = ABORT_ST;
4649 currSCCB->Sccb_scsimsg = SMABORT;
4652 ACCEPT_MSG_ATN(port);
4657 /*---------------------------------------------------------------------
4659 * Function: Phase Check FIFO
4661 * Description: Make sure data has been flushed from both FIFOs and abort
4662 * the operations if necessary.
4664 *---------------------------------------------------------------------*/
4666 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4668 unsigned long xfercnt;
4671 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4673 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4676 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4677 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4680 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4682 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4684 currSCCB->Sccb_XferCnt = 0;
4686 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4687 (currSCCB->HostStatus == SCCB_COMPLETE))
4689 currSCCB->HostStatus = SCCB_PARITY_ERR;
4690 WRW_HARPOON((port+hp_intstat), PARITY);
4693 FPT_hostDataXferAbort(port,p_card,currSCCB);
4695 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4697 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4698 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4701 } /*End Data In specific code. */
4705 GET_XFER_CNT(port,xfercnt);
4708 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4711 WR_HARPOON(port+hp_portctrl_0, 0x00);
4713 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4715 currSCCB->Sccb_XferCnt = xfercnt;
4717 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4718 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4720 currSCCB->HostStatus = SCCB_PARITY_ERR;
4721 WRW_HARPOON((port+hp_intstat), PARITY);
4725 FPT_hostDataXferAbort(port,p_card,currSCCB);
4728 WR_HARPOON(port+hp_fifowrite, 0x00);
4729 WR_HARPOON(port+hp_fiforead, 0x00);
4730 WR_HARPOON(port+hp_xferstat, 0x00);
4732 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4736 /*---------------------------------------------------------------------
4738 * Function: Phase Bus Free
4740 * Description: We just went bus free so figure out if it was
4741 * because of command complete or from a disconnect.
4743 *---------------------------------------------------------------------*/
4744 static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4748 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4750 if (currSCCB != NULL)
4756 if (currSCCB->OperationCode == RESET_COMMAND)
4759 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4760 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4761 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4765 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4767 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4771 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4773 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4774 (unsigned char)SYNC_SUPPORTED;
4775 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4778 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4780 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4781 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4782 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4787 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4789 /* Make sure this is not a phony BUS_FREE. If we were
4790 reselected or if BUSY is NOT on then this is a
4791 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4793 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4794 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4796 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4797 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4809 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4811 if (!currSCCB->HostStatus)
4813 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4816 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4817 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4818 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4820 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4822 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4827 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4829 } /*end if !=null */
4835 /*---------------------------------------------------------------------
4837 * Function: Auto Load Default Map
4839 * Description: Load the Automation RAM with the defualt map values.
4841 *---------------------------------------------------------------------*/
4842 static void FPT_autoLoadDefaultMap(unsigned long p_port)
4844 unsigned long map_addr;
4846 ARAM_ACCESS(p_port);
4847 map_addr = p_port + hp_aramBase;
4849 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4851 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4853 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4855 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4857 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4873 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4875 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4881 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4883 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4884 map_addr +=2; /*This means AYNC DATA IN */
4885 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4887 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4889 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4891 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4893 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4895 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4897 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4899 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4901 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4903 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4905 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4907 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4909 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4911 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4913 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4915 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4917 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4919 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4922 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4924 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4928 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4929 map_addr +=2; /* DIDN'T GET ONE */
4930 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4932 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4934 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4938 SGRAM_ACCESS(p_port);
4941 /*---------------------------------------------------------------------
4943 * Function: Auto Command Complete
4945 * Description: Post command back to host and find another command
4948 *---------------------------------------------------------------------*/
4950 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4953 unsigned char status_byte;
4955 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4957 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4959 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4961 if (status_byte != SSGOOD) {
4963 if (status_byte == SSQ_FULL) {
4966 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4967 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4969 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4970 if(FPT_BL_Card[p_card].discQCount != 0)
4971 FPT_BL_Card[p_card].discQCount--;
4972 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4976 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4977 if(currSCCB->Sccb_tag)
4979 if(FPT_BL_Card[p_card].discQCount != 0)
4980 FPT_BL_Card[p_card].discQCount--;
4981 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4984 if(FPT_BL_Card[p_card].discQCount != 0)
4985 FPT_BL_Card[p_card].discQCount--;
4986 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4990 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4992 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4997 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4999 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
5000 (unsigned char)SYNC_SUPPORTED;
5002 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5003 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5005 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5006 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5008 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5009 if(FPT_BL_Card[p_card].discQCount != 0)
5010 FPT_BL_Card[p_card].discQCount--;
5011 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5015 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5016 if(currSCCB->Sccb_tag)
5018 if(FPT_BL_Card[p_card].discQCount != 0)
5019 FPT_BL_Card[p_card].discQCount--;
5020 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5023 if(FPT_BL_Card[p_card].discQCount != 0)
5024 FPT_BL_Card[p_card].discQCount--;
5025 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5032 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5035 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5036 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5037 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5039 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5040 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5042 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5043 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5045 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5046 if(FPT_BL_Card[p_card].discQCount != 0)
5047 FPT_BL_Card[p_card].discQCount--;
5048 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5052 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5053 if(currSCCB->Sccb_tag)
5055 if(FPT_BL_Card[p_card].discQCount != 0)
5056 FPT_BL_Card[p_card].discQCount--;
5057 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5060 if(FPT_BL_Card[p_card].discQCount != 0)
5061 FPT_BL_Card[p_card].discQCount--;
5062 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5069 if (status_byte == SSCHECK)
5071 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5073 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5075 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5077 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5079 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5084 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5086 currSCCB->SccbStatus = SCCB_ERROR;
5087 currSCCB->TargetStatus = status_byte;
5089 if (status_byte == SSCHECK) {
5091 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5095 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5097 if (currSCCB->RequestSenseLength == 0)
5098 currSCCB->RequestSenseLength = 14;
5100 FPT_ssenss(&FPT_BL_Card[p_card]);
5101 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5103 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5104 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5106 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5107 if(FPT_BL_Card[p_card].discQCount != 0)
5108 FPT_BL_Card[p_card].discQCount--;
5109 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5113 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5114 if(currSCCB->Sccb_tag)
5116 if(FPT_BL_Card[p_card].discQCount != 0)
5117 FPT_BL_Card[p_card].discQCount--;
5118 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5121 if(FPT_BL_Card[p_card].discQCount != 0)
5122 FPT_BL_Card[p_card].discQCount--;
5123 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5133 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5134 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5135 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5137 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5140 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5143 #define SHORT_WAIT 0x0000000F
5144 #define LONG_WAIT 0x0000FFFFL
5147 /*---------------------------------------------------------------------
5149 * Function: Data Transfer Processor
5151 * Description: This routine performs two tasks.
5152 * (1) Start data transfer by calling HOST_DATA_XFER_START
5153 * function. Once data transfer is started, (2) Depends
5154 * on the type of data transfer mode Scatter/Gather mode
5155 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5156 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5157 * data transfer done. In Scatter/Gather mode, this routine
5158 * checks bus master command complete and dual rank busy
5159 * bit to keep chaining SC transfer command. Similarly,
5160 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5161 * (F_HOST_XFER_ACT bit) for data transfer done.
5163 *---------------------------------------------------------------------*/
5165 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
5169 currSCCB = pCurrCard->currentSCCB;
5171 if (currSCCB->Sccb_XferState & F_SG_XFER)
5173 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5176 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5177 currSCCB->Sccb_SGoffset = 0x00;
5179 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5181 FPT_busMstrSGDataXferStart(port, currSCCB);
5186 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5188 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5190 FPT_busMstrDataXferStart(port, currSCCB);
5196 /*---------------------------------------------------------------------
5198 * Function: BusMaster Scatter Gather Data Transfer Start
5202 *---------------------------------------------------------------------*/
5203 static void FPT_busMstrSGDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
5205 unsigned long count,addr,tmpSGCnt;
5206 unsigned int sg_index;
5207 unsigned char sg_count, i;
5208 unsigned long reg_offset;
5211 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5213 count = ((unsigned long) HOST_RD_CMD)<<24;
5217 count = ((unsigned long) HOST_WRT_CMD)<<24;
5222 sg_index = pcurrSCCB->Sccb_sgseg;
5223 reg_offset = hp_aramBase;
5226 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5229 WR_HARPOON(p_port+hp_page_ctrl, i);
5231 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5232 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5234 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
5237 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
5240 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
5241 ((sg_index * 2) + 1));
5244 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5246 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5247 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5249 tmpSGCnt = count & 0x00FFFFFFL;
5252 WR_HARP32(p_port,reg_offset,addr);
5255 WR_HARP32(p_port,reg_offset,count);
5258 count &= 0xFF000000L;
5264 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5266 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5268 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5270 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5273 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5274 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5280 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5281 (tmpSGCnt & 0x000000001))
5284 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5289 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5291 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5292 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5296 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5301 /*---------------------------------------------------------------------
5303 * Function: BusMaster Data Transfer Start
5307 *---------------------------------------------------------------------*/
5308 static void FPT_busMstrDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
5310 unsigned long addr,count;
5312 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5314 count = pcurrSCCB->Sccb_XferCnt;
5316 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5320 addr = pcurrSCCB->SensePointer;
5321 count = pcurrSCCB->RequestSenseLength;
5325 HP_SETUP_ADDR_CNT(p_port,addr,count);
5328 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5330 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5331 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5333 WR_HARPOON(p_port+hp_xfer_cmd,
5334 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5339 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5340 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5342 WR_HARPOON(p_port+hp_xfer_cmd,
5343 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5349 /*---------------------------------------------------------------------
5351 * Function: BusMaster Timeout Handler
5353 * Description: This function is called after a bus master command busy time
5354 * out is detected. This routines issue halt state machine
5355 * with a software time out for command busy. If command busy
5356 * is still asserted at the end of the time out, it issues
5357 * hard abort with another software time out. It hard abort
5358 * command busy is also time out, it'll just give up.
5360 *---------------------------------------------------------------------*/
5361 static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5363 unsigned long timeout;
5365 timeout = LONG_WAIT;
5367 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5369 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5373 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5374 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5376 timeout = LONG_WAIT;
5377 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5380 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5382 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5392 /*---------------------------------------------------------------------
5394 * Function: Host Data Transfer Abort
5396 * Description: Abort any in progress transfer.
5398 *---------------------------------------------------------------------*/
5399 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
5402 unsigned long timeout;
5403 unsigned long remain_cnt;
5404 unsigned int sg_ptr;
5406 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5408 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5411 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5413 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5414 timeout = LONG_WAIT;
5416 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5418 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5420 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5422 if (FPT_busMstrTimeOut(port)) {
5424 if (pCurrSCCB->HostStatus == 0x00)
5426 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5430 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5432 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5434 if (pCurrSCCB->HostStatus == 0x00)
5437 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5443 else if (pCurrSCCB->Sccb_XferCnt) {
5445 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5448 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5451 WR_HARPOON(port+hp_sg_addr,0x00);
5453 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5455 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5457 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5460 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5462 while (remain_cnt < 0x01000000L) {
5466 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
5467 DataPointer) + (sg_ptr * 2)))) {
5469 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
5470 DataPointer) + (sg_ptr * 2)));
5481 if (remain_cnt < 0x01000000L) {
5484 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5486 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5489 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5490 && (remain_cnt == 0))
5492 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5498 if (pCurrSCCB->HostStatus == 0x00) {
5500 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5506 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5509 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5511 FPT_busMstrTimeOut(port);
5516 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5518 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5520 if (pCurrSCCB->HostStatus == 0x00) {
5522 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5533 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5535 timeout = SHORT_WAIT;
5537 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5538 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5542 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5544 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5547 timeout = LONG_WAIT;
5549 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5552 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5556 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5558 if (pCurrSCCB->HostStatus == 0x00) {
5560 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5563 FPT_busMstrTimeOut(port);
5567 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5569 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5571 if (pCurrSCCB->HostStatus == 0x00) {
5573 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5584 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5586 timeout = LONG_WAIT;
5588 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5590 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5592 if (pCurrSCCB->HostStatus == 0x00) {
5594 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5597 FPT_busMstrTimeOut(port);
5602 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5604 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5606 if (pCurrSCCB->HostStatus == 0x00) {
5608 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5614 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5616 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5619 WR_HARPOON(port+hp_sg_addr,0x00);
5621 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5623 pCurrSCCB->Sccb_SGoffset = 0x00;
5626 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5627 pCurrSCCB->DataLength) {
5629 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5631 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5638 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5640 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5644 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5649 /*---------------------------------------------------------------------
5651 * Function: Host Data Transfer Restart
5653 * Description: Reset the available count due to a restore data
5656 *---------------------------------------------------------------------*/
5657 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5659 unsigned long data_count;
5660 unsigned int sg_index;
5661 unsigned long *sg_ptr;
5663 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5665 currSCCB->Sccb_XferCnt = 0;
5667 sg_index = 0xffff; /*Index by long words into sg list. */
5668 data_count = 0; /*Running count of SG xfer counts. */
5670 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5672 while (data_count < currSCCB->Sccb_ATC) {
5675 data_count += *(sg_ptr+(sg_index * 2));
5678 if (data_count == currSCCB->Sccb_ATC) {
5680 currSCCB->Sccb_SGoffset = 0;
5685 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5688 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5692 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5698 /*---------------------------------------------------------------------
5700 * Function: FPT_scini
5702 * Description: Setup all data structures necessary for SCAM selection.
5704 *---------------------------------------------------------------------*/
5706 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5709 unsigned char loser,assigned_id;
5710 unsigned long p_port;
5712 unsigned char i,k,ScamFlg ;
5714 PNVRamInfo pCurrNvRam;
5716 currCard = &FPT_BL_Card[p_card];
5717 p_port = currCard->ioPort;
5718 pCurrNvRam = currCard->pNvRamInfo;
5722 ScamFlg = pCurrNvRam->niScamConf;
5723 i = pCurrNvRam->niSysConf;
5726 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5727 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5729 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5732 FPT_inisci(p_card,p_port, p_our_id);
5734 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5735 too slow to return to SCAM selection */
5738 FPT_Wait1Second(p_port);
5740 FPT_Wait(p_port, TO_250ms); */
5742 FPT_Wait1Second(p_port);
5744 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5746 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5751 FPT_scxferc(p_port,SYNC_PTRN);
5752 FPT_scxferc(p_port,DOM_MSTR);
5753 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5754 } while ( loser == 0xFF );
5758 if ((p_power_up) && (!loser))
5760 FPT_sresb(p_port,p_card);
5761 FPT_Wait(p_port, TO_250ms);
5763 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5768 FPT_scxferc(p_port, SYNC_PTRN);
5769 FPT_scxferc(p_port, DOM_MSTR);
5770 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5772 } while ( loser == 0xFF );
5787 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5790 if (ScamFlg & SCAM_ENABLED)
5793 for (i=0; i < MAX_SCSI_TAR; i++)
5795 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5796 (FPT_scamInfo[i].state == ID_UNUSED))
5798 if (FPT_scsell(p_port,i))
5800 FPT_scamInfo[i].state = LEGACY;
5801 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5802 (FPT_scamInfo[i].id_string[1] != 0xFA))
5805 FPT_scamInfo[i].id_string[0] = 0xFF;
5806 FPT_scamInfo[i].id_string[1] = 0xFA;
5807 if(pCurrNvRam == NULL)
5808 currCard->globalFlags |= F_UPDATE_EEPROM;
5814 FPT_sresb(p_port,p_card);
5815 FPT_Wait1Second(p_port);
5816 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5818 FPT_scasid(p_card, p_port);
5823 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5825 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5827 FPT_scwtsel(p_port);
5830 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5832 i = FPT_scxferc(p_port,0x00);
5835 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5837 i = FPT_scxferc(p_port,0x00);
5840 k = FPT_scxferc(p_port,0x00);
5845 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5846 FPT_inisci(p_card, p_port, p_our_id);
5847 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5848 FPT_scamInfo[currCard->ourId].id_string[0]
5856 else if (i == SET_P_FLAG)
5858 if (!(FPT_scsendi(p_port,
5859 &FPT_scamInfo[p_our_id].id_string[0])))
5860 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5862 }while (!assigned_id);
5864 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5867 if (ScamFlg & SCAM_ENABLED)
5870 if (currCard->globalFlags & F_UPDATE_EEPROM)
5872 FPT_scsavdi(p_card, p_port);
5873 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5879 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5881 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5882 (FPT_scamInfo[i].state == LEGACY))
5887 currCard->globalFlags |= F_SINGLE_DEVICE;
5889 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5894 /*---------------------------------------------------------------------
5896 * Function: FPT_scarb
5898 * Description: Gain control of the bus and wait SCAM select time (250ms)
5900 *---------------------------------------------------------------------*/
5902 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5904 if (p_sel_type == INIT_SELTD)
5907 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5910 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5913 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5916 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5918 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5920 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5926 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5928 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5930 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5931 ~(SCSI_BSY | SCSI_SEL)));
5937 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5939 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5940 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5941 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5942 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5944 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5946 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5949 FPT_Wait(p_port,TO_250ms);
5955 /*---------------------------------------------------------------------
5957 * Function: FPT_scbusf
5959 * Description: Release the SCSI bus and disable SCAM selection.
5961 *---------------------------------------------------------------------*/
5963 static void FPT_scbusf(unsigned long p_port)
5965 WR_HARPOON(p_port+hp_page_ctrl,
5966 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5969 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5971 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5974 WR_HARPOON(p_port+hp_scsisig, 0x00);
5977 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5980 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5983 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5985 WR_HARPOON(p_port+hp_page_ctrl,
5986 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5991 /*---------------------------------------------------------------------
5993 * Function: FPT_scasid
5995 * Description: Assign an ID to all the SCAM devices.
5997 *---------------------------------------------------------------------*/
5999 static void FPT_scasid(unsigned char p_card, unsigned long p_port)
6001 unsigned char temp_id_string[ID_STRING_LENGTH];
6003 unsigned char i,k,scam_id;
6004 unsigned char crcBytes[3];
6005 PNVRamInfo pCurrNvRam;
6006 ushort_ptr pCrcBytes;
6008 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6015 for (k=0; k < ID_STRING_LENGTH; k++)
6017 temp_id_string[k] = (unsigned char) 0x00;
6020 FPT_scxferc(p_port,SYNC_PTRN);
6021 FPT_scxferc(p_port,ASSIGN_ID);
6023 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6026 pCrcBytes = (ushort_ptr)&crcBytes[0];
6027 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6028 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6029 temp_id_string[1] = crcBytes[2];
6030 temp_id_string[2] = crcBytes[0];
6031 temp_id_string[3] = crcBytes[1];
6032 for(k = 4; k < ID_STRING_LENGTH; k++)
6033 temp_id_string[k] = (unsigned char) 0x00;
6035 i = FPT_scmachid(p_card,temp_id_string);
6037 if (i == CLR_PRIORITY)
6039 FPT_scxferc(p_port,MISC_CODE);
6040 FPT_scxferc(p_port,CLR_P_FLAG);
6041 i = 0; /*Not the last ID yet. */
6044 else if (i != NO_ID_AVAIL)
6047 FPT_scxferc(p_port,ID_0_7);
6049 FPT_scxferc(p_port,ID_8_F);
6051 scam_id = (i & (unsigned char) 0x07);
6054 for (k=1; k < 0x08; k <<= 1)
6056 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6058 FPT_scxferc(p_port,scam_id);
6060 i = 0; /*Not the last ID yet. */
6071 FPT_scxferc(p_port,SYNC_PTRN);
6072 FPT_scxferc(p_port,CFG_CMPLT);
6079 /*---------------------------------------------------------------------
6081 * Function: FPT_scsel
6083 * Description: Select all the SCAM devices.
6085 *---------------------------------------------------------------------*/
6087 static void FPT_scsel(unsigned long p_port)
6090 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6091 FPT_scwiros(p_port, SCSI_MSG);
6093 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6096 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6097 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6098 (unsigned char)(BIT(7)+BIT(6))));
6101 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6102 FPT_scwiros(p_port, SCSI_SEL);
6104 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6105 ~(unsigned char)BIT(6)));
6106 FPT_scwirod(p_port, BIT(6));
6108 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6113 /*---------------------------------------------------------------------
6115 * Function: FPT_scxferc
6117 * Description: Handshake the p_data (DB4-0) across the bus.
6119 *---------------------------------------------------------------------*/
6121 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
6123 unsigned char curr_data, ret_data;
6125 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6127 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6129 curr_data &= ~BIT(7);
6131 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6133 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6134 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6136 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6138 curr_data |= BIT(6);
6140 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6142 curr_data &= ~BIT(5);
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6146 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6148 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6149 curr_data |= BIT(7);
6151 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6153 curr_data &= ~BIT(6);
6155 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6157 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6163 /*---------------------------------------------------------------------
6165 * Function: FPT_scsendi
6167 * Description: Transfer our Identification string to determine if we
6168 * will be the dominant master.
6170 *---------------------------------------------------------------------*/
6172 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
6174 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6178 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6180 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6183 ret_data = FPT_scxferc(p_port,00);
6185 else if (p_id_string[byte_cnt] & bit_cnt)
6187 ret_data = FPT_scxferc(p_port,02);
6191 ret_data = FPT_scxferc(p_port,01);
6196 if ((ret_data & 0x1C) == 0x10)
6197 return(0x00); /*End of isolation stage, we won! */
6199 if (ret_data & 0x1C)
6202 if ((defer) && (!(ret_data & 0x1F)))
6203 return(0x01); /*End of isolation stage, we lost. */
6210 return(0x01); /*We lost */
6212 return(0); /*We WON! Yeeessss! */
6217 /*---------------------------------------------------------------------
6219 * Function: FPT_sciso
6221 * Description: Transfer the Identification string.
6223 *---------------------------------------------------------------------*/
6225 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
6227 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6231 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6233 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6235 ret_data = FPT_scxferc(p_port,0);
6237 if (ret_data & 0xFC)
6243 if (ret_data & BIT(1)) {
6248 if ((ret_data & 0x1F) == 0)
6251 if(bit_cnt != 0 || bit_cnt != 8)
6255 FPT_scxferc(p_port, SYNC_PTRN);
6256 FPT_scxferc(p_port, ASSIGN_ID);
6268 p_id_string[byte_cnt] = the_data;
6277 /*---------------------------------------------------------------------
6279 * Function: FPT_scwirod
6281 * Description: Sample the SCSI data bus making sure the signal has been
6282 * deasserted for the correct number of consecutive samples.
6284 *---------------------------------------------------------------------*/
6286 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6291 while ( i < MAX_SCSI_TAR ) {
6293 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6306 /*---------------------------------------------------------------------
6308 * Function: FPT_scwiros
6310 * Description: Sample the SCSI Signal lines making sure the signal has been
6311 * deasserted for the correct number of consecutive samples.
6313 *---------------------------------------------------------------------*/
6315 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6320 while ( i < MAX_SCSI_TAR ) {
6322 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6334 /*---------------------------------------------------------------------
6336 * Function: FPT_scvalq
6338 * Description: Make sure we received a valid data byte.
6340 *---------------------------------------------------------------------*/
6342 static unsigned char FPT_scvalq(unsigned char p_quintet)
6344 unsigned char count;
6346 for (count=1; count < 0x08; count<<=1) {
6347 if (!(p_quintet & count))
6351 if (p_quintet & 0x18)
6359 /*---------------------------------------------------------------------
6361 * Function: FPT_scsell
6363 * Description: Select the specified device ID using a selection timeout
6364 * less than 4ms. If somebody responds then it is a legacy
6365 * drive and this ID must be marked as such.
6367 *---------------------------------------------------------------------*/
6369 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6373 WR_HARPOON(p_port+hp_page_ctrl,
6374 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6376 ARAM_ACCESS(p_port);
6378 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6379 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6382 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6383 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6385 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6387 WRW_HARPOON((p_port+hp_intstat),
6388 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6390 WR_HARPOON(p_port+hp_select_id, targ_id);
6392 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6393 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6394 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6397 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6398 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6400 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6401 FPT_Wait(p_port, TO_250ms);
6403 DISABLE_AUTO(p_port);
6405 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6406 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6408 SGRAM_ACCESS(p_port);
6410 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6412 WRW_HARPOON((p_port+hp_intstat),
6413 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6415 WR_HARPOON(p_port+hp_page_ctrl,
6416 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6418 return(0); /*No legacy device */
6423 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6424 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6426 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6431 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6433 WR_HARPOON(p_port+hp_page_ctrl,
6434 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6436 return(1); /*Found one of them oldies! */
6440 /*---------------------------------------------------------------------
6442 * Function: FPT_scwtsel
6444 * Description: Wait to be selected by another SCAM initiator.
6446 *---------------------------------------------------------------------*/
6448 static void FPT_scwtsel(unsigned long p_port)
6450 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6454 /*---------------------------------------------------------------------
6456 * Function: FPT_inisci
6458 * Description: Setup the data Structure with the info from the EEPROM.
6460 *---------------------------------------------------------------------*/
6462 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
6464 unsigned char i,k,max_id;
6465 unsigned short ee_data;
6466 PNVRamInfo pCurrNvRam;
6468 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6470 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6477 for(i = 0; i < max_id; i++){
6479 for(k = 0; k < 4; k++)
6480 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6481 for(k = 4; k < ID_STRING_LENGTH; k++)
6482 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6484 if(FPT_scamInfo[i].id_string[0] == 0x00)
6485 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6487 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6491 for (i=0; i < max_id; i++)
6493 for (k=0; k < ID_STRING_LENGTH; k+=2)
6495 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6496 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6497 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6499 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6502 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6503 (FPT_scamInfo[i].id_string[0] == 0xFF))
6505 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6508 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6512 for(k = 0; k < ID_STRING_LENGTH; k++)
6513 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6517 /*---------------------------------------------------------------------
6519 * Function: FPT_scmachid
6521 * Description: Match the Device ID string with our values stored in
6524 *---------------------------------------------------------------------*/
6526 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6529 unsigned char i,k,match;
6532 for (i=0; i < MAX_SCSI_TAR; i++) {
6536 for (k=0; k < ID_STRING_LENGTH; k++)
6538 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6544 FPT_scamInfo[i].state = ID_ASSIGNED;
6552 if (p_id_string[0] & BIT(5))
6557 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6558 match = p_id_string[1] & (unsigned char) 0x1F;
6566 if (FPT_scamInfo[match].state == ID_UNUSED)
6568 for (k=0; k < ID_STRING_LENGTH; k++)
6570 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6573 FPT_scamInfo[match].state = ID_ASSIGNED;
6575 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6576 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6586 if (p_id_string[0] & BIT(5))
6589 match = MAX_SCSI_TAR-1;
6595 if (p_id_string[0] & BIT(7))
6597 return(CLR_PRIORITY);
6601 if (p_id_string[0] & BIT(5))
6606 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6607 match = p_id_string[1] & (unsigned char) 0x1F;
6616 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6618 for (k=0; k < ID_STRING_LENGTH; k++)
6620 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6623 FPT_scamInfo[match].id_string[0] |= BIT(7);
6624 FPT_scamInfo[match].state = ID_ASSIGNED;
6625 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6626 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6636 if (p_id_string[0] & BIT(5))
6639 match = MAX_SCSI_TAR-1;
6643 return(NO_ID_AVAIL);
6647 /*---------------------------------------------------------------------
6649 * Function: FPT_scsavdi
6651 * Description: Save off the device SCAM ID strings.
6653 *---------------------------------------------------------------------*/
6655 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6657 unsigned char i,k,max_id;
6658 unsigned short ee_data,sum_data;
6663 for (i = 1; i < EE_SCAMBASE/2; i++)
6665 sum_data += FPT_utilEERead(p_port, i);
6669 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6671 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6677 for (i=0; i < max_id; i++)
6680 for (k=0; k < ID_STRING_LENGTH; k+=2)
6682 ee_data = FPT_scamInfo[i].id_string[k+1];
6684 ee_data |= FPT_scamInfo[i].id_string[k];
6685 sum_data += ee_data;
6686 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6687 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6692 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6693 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6696 /*---------------------------------------------------------------------
6698 * Function: FPT_XbowInit
6700 * Description: Setup the Xbow for normal operation.
6702 *---------------------------------------------------------------------*/
6704 static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6708 i = RD_HARPOON(port+hp_page_ctrl);
6709 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6711 WR_HARPOON(port+hp_scsireset,0x00);
6712 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6714 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6717 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6719 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6721 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6722 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6724 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6726 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6727 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6729 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6730 FPT_default_intena |= SCAM_SEL;
6732 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6734 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6736 /* Turn on SCSI_MODE8 for narrow cards to fix the
6737 strapping issue with the DUAL CHANNEL card */
6738 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6739 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6741 WR_HARPOON(port+hp_page_ctrl, i);
6746 /*---------------------------------------------------------------------
6748 * Function: FPT_BusMasterInit
6750 * Description: Initialize the BusMaster for normal operations.
6752 *---------------------------------------------------------------------*/
6754 static void FPT_BusMasterInit(unsigned long p_port)
6758 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6759 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6761 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6764 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6766 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6769 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6770 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6771 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6776 /*---------------------------------------------------------------------
6778 * Function: FPT_DiagEEPROM
6780 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6783 *---------------------------------------------------------------------*/
6785 static void FPT_DiagEEPROM(unsigned long p_port)
6787 unsigned short index,temp,max_wd_cnt;
6789 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6790 max_wd_cnt = EEPROM_WD_CNT;
6792 max_wd_cnt = EEPROM_WD_CNT * 2;
6794 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6796 if (temp == 0x4641) {
6798 for (index = 2; index < max_wd_cnt; index++) {
6800 temp += FPT_utilEERead(p_port, index);
6804 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6806 return; /*EEPROM is Okay so return now! */
6811 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6813 for (index = 0; index < max_wd_cnt; index++) {
6815 FPT_utilEEWrite(p_port, 0x0000, index);
6820 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6822 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6824 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6826 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6828 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6830 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6832 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6834 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6837 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6839 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6841 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6844 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6850 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6852 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6854 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6856 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6858 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6862 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6864 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6866 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6868 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6870 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6872 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6874 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6876 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6879 index = ((EE_SCAMBASE/2)+(7*16));
6880 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6881 temp += (0x0700+TYPE_CODE0);
6883 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6884 temp += 0x5542; /* BUSLOGIC */
6886 FPT_utilEEWrite(p_port, 0x4C53, index);
6889 FPT_utilEEWrite(p_port, 0x474F, index);
6892 FPT_utilEEWrite(p_port, 0x4349, index);
6895 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6896 temp += 0x5442; /* BT- 930 */
6898 FPT_utilEEWrite(p_port, 0x202D, index);
6901 FPT_utilEEWrite(p_port, 0x3339, index);
6903 index++; /*Serial # */
6904 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6907 FPT_utilEEWrite(p_port, 0x5453, index);
6910 FPT_utilEEWrite(p_port, 0x5645, index);
6913 FPT_utilEEWrite(p_port, 0x2045, index);
6916 FPT_utilEEWrite(p_port, 0x202F, index);
6919 FPT_utilEEWrite(p_port, 0x4F4A, index);
6922 FPT_utilEEWrite(p_port, 0x204E, index);
6925 FPT_utilEEWrite(p_port, 0x3539, index);
6930 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6932 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6937 /*---------------------------------------------------------------------
6939 * Function: Queue Search Select
6941 * Description: Try to find a new command to execute.
6943 *---------------------------------------------------------------------*/
6945 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6947 unsigned char scan_ptr, lun;
6948 PSCCBMgr_tar_info currTar_Info;
6951 scan_ptr = pCurrCard->scanIndex;
6954 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6955 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6956 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6958 if (currTar_Info->TarSelQ_Cnt != 0)
6962 if (scan_ptr == MAX_SCSI_TAR)
6965 for(lun=0; lun < MAX_LUN; lun++)
6967 if(currTar_Info->TarLUNBusy[lun] == 0)
6970 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6973 while((pCurrCard->currentSCCB != NULL) &&
6974 (lun != pCurrCard->currentSCCB->Lun))
6976 pOldSccb = pCurrCard->currentSCCB;
6977 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6980 if(pCurrCard->currentSCCB == NULL)
6982 if(pOldSccb != NULL)
6984 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6986 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6988 currTar_Info->TarSelQ_Cnt--;
6992 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6994 if (currTar_Info->TarSelQ_Head == NULL)
6996 currTar_Info->TarSelQ_Tail = NULL;
6997 currTar_Info->TarSelQ_Cnt = 0;
7001 currTar_Info->TarSelQ_Cnt--;
7002 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7005 pCurrCard->scanIndex = scan_ptr;
7007 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7017 if (scan_ptr == MAX_SCSI_TAR) {
7025 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7026 (currTar_Info->TarLUNBusy[0] == 0))
7029 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7031 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7033 if (currTar_Info->TarSelQ_Head == NULL)
7035 currTar_Info->TarSelQ_Tail = NULL;
7036 currTar_Info->TarSelQ_Cnt = 0;
7040 currTar_Info->TarSelQ_Cnt--;
7041 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7045 if (scan_ptr == MAX_SCSI_TAR)
7048 pCurrCard->scanIndex = scan_ptr;
7050 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7058 if (scan_ptr == MAX_SCSI_TAR)
7064 } while (scan_ptr != pCurrCard->scanIndex);
7068 /*---------------------------------------------------------------------
7070 * Function: Queue Select Fail
7072 * Description: Add the current SCCB to the head of the Queue.
7074 *---------------------------------------------------------------------*/
7076 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7078 unsigned char thisTarg;
7079 PSCCBMgr_tar_info currTar_Info;
7081 if (pCurrCard->currentSCCB != NULL)
7083 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7084 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7086 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7088 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7090 if (currTar_Info->TarSelQ_Cnt == 0)
7092 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7097 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7101 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7103 pCurrCard->currentSCCB = NULL;
7104 currTar_Info->TarSelQ_Cnt++;
7107 /*---------------------------------------------------------------------
7109 * Function: Queue Command Complete
7111 * Description: Call the callback function with the current SCCB.
7113 *---------------------------------------------------------------------*/
7115 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7116 unsigned char p_card)
7119 unsigned char i, SCSIcmd;
7120 CALL_BK_FN callback;
7121 PSCCBMgr_tar_info currTar_Info;
7123 SCSIcmd = p_sccb->Cdb[0];
7126 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7128 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7129 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7130 (p_sccb->TargetStatus != SSCHECK))
7132 if ((SCSIcmd == SCSI_READ) ||
7133 (SCSIcmd == SCSI_WRITE) ||
7134 (SCSIcmd == SCSI_READ_EXTENDED) ||
7135 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7136 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7137 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7138 (pCurrCard->globalFlags & F_NO_FILTER)
7140 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7144 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7146 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7147 p_sccb->SccbStatus = SCCB_ERROR;
7149 p_sccb->SccbStatus = SCCB_SUCCESS;
7152 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7154 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7155 for (i=0; i < 6; i++) {
7156 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7160 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7161 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7163 FPT_utilUpdateResidual(p_sccb);
7166 pCurrCard->cmdCounter--;
7167 if (!pCurrCard->cmdCounter) {
7169 if (pCurrCard->globalFlags & F_GREEN_PC) {
7170 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7171 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7174 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7175 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7179 if(pCurrCard->discQCount != 0)
7181 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7182 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7183 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7185 pCurrCard->discQCount--;
7186 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7190 if(p_sccb->Sccb_tag)
7192 pCurrCard->discQCount--;
7193 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7196 pCurrCard->discQCount--;
7197 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7203 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7205 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7206 pCurrCard->currentSCCB = NULL;
7210 /*---------------------------------------------------------------------
7212 * Function: Queue Disconnect
7214 * Description: Add SCCB to our disconnect array.
7216 *---------------------------------------------------------------------*/
7217 static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
7219 PSCCBMgr_tar_info currTar_Info;
7221 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7223 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7224 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7226 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7230 if (p_sccb->Sccb_tag)
7232 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7233 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7234 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7237 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7240 FPT_BL_Card[p_card].currentSCCB = NULL;
7244 /*---------------------------------------------------------------------
7246 * Function: Queue Flush SCCB
7248 * Description: Flush all SCCB's back to the host driver for this target.
7250 *---------------------------------------------------------------------*/
7252 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7254 unsigned char qtag,thisTarg;
7256 PSCCBMgr_tar_info currTar_Info;
7258 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7259 if(currSCCB != NULL)
7261 thisTarg = (unsigned char)currSCCB->TargID;
7262 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7264 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7266 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7267 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7270 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7272 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7274 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7275 currTar_Info->TarTagQ_Cnt--;
7283 /*---------------------------------------------------------------------
7285 * Function: Queue Flush Target SCCB
7287 * Description: Flush all SCCB's back to the host driver for this target.
7289 *---------------------------------------------------------------------*/
7291 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7292 unsigned char error_code)
7295 PSCCBMgr_tar_info currTar_Info;
7297 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7299 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7301 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7302 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7305 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7307 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7309 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7310 currTar_Info->TarTagQ_Cnt--;
7321 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
7323 PSCCBMgr_tar_info currTar_Info;
7324 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7326 p_SCCB->Sccb_forwardlink = NULL;
7328 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7330 if (currTar_Info->TarSelQ_Cnt == 0) {
7332 currTar_Info->TarSelQ_Head = p_SCCB;
7337 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7341 currTar_Info->TarSelQ_Tail = p_SCCB;
7342 currTar_Info->TarSelQ_Cnt++;
7346 /*---------------------------------------------------------------------
7348 * Function: Queue Find SCCB
7350 * Description: Search the target select Queue for this SCCB, and
7351 * remove it if found.
7353 *---------------------------------------------------------------------*/
7355 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
7358 PSCCBMgr_tar_info currTar_Info;
7360 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7362 q_ptr = currTar_Info->TarSelQ_Head;
7364 while(q_ptr != NULL) {
7366 if (q_ptr == p_SCCB) {
7369 if (currTar_Info->TarSelQ_Head == q_ptr) {
7371 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7374 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7376 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7379 if (q_ptr->Sccb_forwardlink != NULL) {
7380 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7383 if (q_ptr->Sccb_backlink != NULL) {
7384 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7387 currTar_Info->TarSelQ_Cnt--;
7393 q_ptr = q_ptr->Sccb_forwardlink;
7403 /*---------------------------------------------------------------------
7405 * Function: Utility Update Residual Count
7407 * Description: Update the XferCnt to the remaining byte count.
7408 * If we transferred all the data then just write zero.
7409 * If Non-SG transfer then report Total Cnt - Actual Transfer
7410 * Cnt. For SG transfers add the count fields of all
7411 * remaining SG elements, as well as any partial remaining
7414 *---------------------------------------------------------------------*/
7416 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7418 unsigned long partial_cnt;
7419 unsigned int sg_index;
7420 unsigned long *sg_ptr;
7422 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7424 p_SCCB->DataLength = 0x0000;
7427 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7429 partial_cnt = 0x0000;
7431 sg_index = p_SCCB->Sccb_sgseg;
7433 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7435 if (p_SCCB->Sccb_SGoffset) {
7437 partial_cnt = p_SCCB->Sccb_SGoffset;
7441 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
7442 p_SCCB->DataLength ) {
7444 partial_cnt += *(sg_ptr+(sg_index * 2));
7448 p_SCCB->DataLength = partial_cnt;
7453 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7458 /*---------------------------------------------------------------------
7460 * Function: Wait 1 Second
7462 * Description: Wait for 1 second.
7464 *---------------------------------------------------------------------*/
7466 static void FPT_Wait1Second(unsigned long p_port)
7470 for(i=0; i < 4; i++) {
7472 FPT_Wait(p_port, TO_250ms);
7474 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7477 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7483 /*---------------------------------------------------------------------
7485 * Function: FPT_Wait
7487 * Description: Wait the desired delay.
7489 *---------------------------------------------------------------------*/
7491 static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7493 unsigned char old_timer;
7494 unsigned char green_flag;
7496 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7498 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7499 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7501 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7502 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7503 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7506 WR_HARPOON(p_port+hp_portctrl_0,
7507 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7509 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7511 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7514 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7518 WR_HARPOON(p_port+hp_portctrl_0,
7519 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7521 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7522 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7524 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7526 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7530 /*---------------------------------------------------------------------
7532 * Function: Enable/Disable Write to EEPROM
7534 * Description: The EEPROM must first be enabled for writes
7535 * A total of 9 clocks are needed.
7537 *---------------------------------------------------------------------*/
7539 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
7541 unsigned char ee_value;
7543 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7547 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7552 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7554 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7555 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7559 /*---------------------------------------------------------------------
7561 * Function: Write EEPROM
7563 * Description: Write a word to the EEPROM at the specified
7566 *---------------------------------------------------------------------*/
7568 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
7571 unsigned char ee_value;
7574 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7579 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7582 ee_value |= (SEE_MS + SEE_CS);
7584 for(i = 0x8000; i != 0; i>>=1) {
7589 ee_value &= ~SEE_DO;
7591 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7592 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7593 ee_value |= SEE_CLK; /* Clock data! */
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 ee_value &= ~SEE_CLK;
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7601 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7603 FPT_Wait(p_port, TO_10ms);
7605 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7606 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7607 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7610 /*---------------------------------------------------------------------
7612 * Function: Read EEPROM
7614 * Description: Read a word from the EEPROM at the desired
7617 *---------------------------------------------------------------------*/
7619 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
7621 unsigned short i, ee_data1, ee_data2;
7624 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7627 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7629 if(ee_data1 == ee_data2)
7632 ee_data1 = ee_data2;
7640 /*---------------------------------------------------------------------
7642 * Function: Read EEPROM Original
7644 * Description: Read a word from the EEPROM at the desired
7647 *---------------------------------------------------------------------*/
7649 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
7652 unsigned char ee_value;
7653 unsigned short i, ee_data;
7655 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7659 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7662 ee_value |= (SEE_MS + SEE_CS);
7665 for(i = 1; i <= 16; i++) {
7667 ee_value |= SEE_CLK; /* Clock data! */
7668 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7669 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7670 ee_value &= ~SEE_CLK;
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7676 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7680 ee_value &= ~(SEE_MS + SEE_CS);
7681 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7682 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7688 /*---------------------------------------------------------------------
7690 * Function: Send EE command and Address to the EEPROM
7692 * Description: Transfers the correct command and sends the address
7695 *---------------------------------------------------------------------*/
7697 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
7699 unsigned char ee_value;
7700 unsigned char narrow_flg;
7705 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7709 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7711 ee_value |= SEE_CS; /* Set CS to EEPROM */
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 for(i = 0x04; i != 0; i>>=1) {
7720 ee_value &= ~SEE_DO;
7722 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7723 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7724 ee_value |= SEE_CLK; /* Clock data! */
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 ee_value &= ~SEE_CLK;
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7745 ee_value &= ~SEE_DO;
7747 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7748 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 ee_value |= SEE_CLK; /* Clock data! */
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 ee_value &= ~SEE_CLK;
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7760 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7762 unsigned short crc=0;
7765 for (i=0; i < ID_STRING_LENGTH; i++)
7767 ch = (unsigned short) buffer[i];
7768 for(j=0; j < 8; j++)
7771 crc = (crc >> 1) ^ CRCMASK;
7780 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7785 for(i = 0; i < ID_STRING_LENGTH; i++)
7793 The following inline definitions avoid type conflicts.
7796 static inline unsigned char
7797 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7799 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7803 static inline FlashPoint_CardHandle_T
7804 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7806 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7810 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7812 FlashPoint_ReleaseHostAdapter(CardHandle);
7817 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7819 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7824 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7826 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7830 static inline boolean
7831 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7833 return FlashPoint_InterruptPending(CardHandle);
7838 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7840 return FlashPoint_HandleInterrupt(CardHandle);
7844 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7845 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7846 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7847 #define FlashPoint_StartCCB FlashPoint__StartCCB
7848 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7849 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7850 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7853 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7857 Define prototypes for the FlashPoint SCCB Manager Functions.
7860 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7861 extern FlashPoint_CardHandle_T
7862 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7863 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7864 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7865 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7866 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7867 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7870 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */