3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
19 #include <linux/config.h>
22 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
36 #define CRCMASK 0xA001
40 #define FAILURE 0xFFFFFFFFL
43 typedef unsigned char UCHAR;
44 typedef unsigned short USHORT;
45 typedef unsigned int UINT;
46 typedef unsigned long ULONG;
49 typedef unsigned short * ushort_ptr;
56 #define u08bits unsigned s08bits
57 #define u16bits unsigned s16bits
58 #define u32bits unsigned s32bits
62 #define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */
63 #define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
68 typedef struct _SCCB *PSCCB;
69 typedef void (*CALL_BK_FN)(PSCCB);
72 typedef struct SCCBMgr_info {
78 USHORT si_fw_revision;
79 USHORT si_per_targ_init_sync;
80 USHORT si_per_targ_fast_nego;
81 USHORT si_per_targ_ultra_nego;
82 USHORT si_per_targ_no_disc;
83 USHORT si_per_targ_wide_nego;
87 UCHAR si_card_model[3];
88 UCHAR si_relative_cardnum;
92 ULONG si_reserved2[5];
93 ULONG si_secondary_range;
96 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
99 #define SCSI_PARITY_ENA 0x0001
100 #define LOW_BYTE_TERM 0x0010
101 #define HIGH_BYTE_TERM 0x0020
102 #define BUSTYPE_PCI 0x3
104 #define SUPPORT_16TAR_32LUN 0x0002
105 #define SOFT_RESET 0x0004
106 #define EXTENDED_TRANSLATION 0x0008
107 #define POST_ALL_UNDERRRUNS 0x0040
108 #define FLAG_SCAM_ENABLED 0x0080
109 #define FLAG_SCAM_LEVEL2 0x0100
114 #define HARPOON_FAMILY 0x02
118 /* SCCB struct used for both SCCB and UCB manager compiles!
119 * The UCB Manager treats the SCCB as it's 'native hardware structure'
124 typedef struct _SCCB {
128 UCHAR RequestSenseLength;
143 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
144 ULONG SccbIOPort; /* Identifies board base port */
150 ULONG Sccb_XferCnt; /* actual transfer count */
152 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
154 USHORT Sccb_MGRFlags;
156 UCHAR Sccb_scsimsg; /* identify msg for selection */
159 UCHAR Sccb_idmsg; /* image of last msg in */
160 PSCCB Sccb_forwardlink;
165 UCHAR Sccb_XferState;
174 #define SCATTER_GATHER_COMMAND 0x02
175 #define RESIDUAL_COMMAND 0x03
176 #define RESIDUAL_SG_COMMAND 0x04
177 #define RESET_COMMAND 0x81
180 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
181 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
182 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
183 #define SCCB_DATA_XFER_IN 0x08 /* Read */
186 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
189 #define BUS_FREE_ST 0
191 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
192 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
193 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
194 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
196 #define DATA_OUT_ST 7
198 #define DISCONNECT_ST 9
202 #define F_HOST_XFER_DIR 0x01
203 #define F_ALL_XFERRED 0x02
204 #define F_SG_XFER 0x04
205 #define F_AUTO_SENSE 0x08
206 #define F_ODD_BALL_CNT 0x10
207 #define F_NO_DATA_YET 0x80
210 #define F_STATUSLOADED 0x01
211 #define F_DEV_SELECTED 0x04
214 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
215 #define SCCB_DATA_UNDER_RUN 0x0C
216 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
217 #define SCCB_DATA_OVER_RUN 0x12
218 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
220 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
221 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
222 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
228 #define SCCB_IN_PROCESS 0x00
229 #define SCCB_SUCCESS 0x01
230 #define SCCB_ABORT 0x02
231 #define SCCB_ERROR 0x04
235 #define ORION_FW_REV 3110
239 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
241 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
244 #define MAX_SCSI_TAR 16
246 #define LUN_MASK 0x1f
248 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
250 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
253 #define RD_HARPOON(ioport) inb((u32bits)ioport)
254 #define RDW_HARPOON(ioport) inw((u32bits)ioport)
255 #define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
256 #define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
257 #define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
258 #define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
261 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
262 #define SYNC_TRYING BIT(6)
263 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
265 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
266 #define WIDE_ENABLED BIT(4)
267 #define WIDE_NEGOCIATED BIT(5)
269 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
270 #define TAG_Q_TRYING BIT(2)
271 #define TAG_Q_REJECT BIT(3)
273 #define TAR_ALLOW_DISC BIT(0)
276 #define EE_SYNC_MASK (BIT(0)+BIT(1))
277 #define EE_SYNC_5MB BIT(0)
278 #define EE_SYNC_10MB BIT(1)
279 #define EE_SYNC_20MB (BIT(0)+BIT(1))
281 #define EE_WIDE_SCSI BIT(7)
284 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
287 typedef struct SCCBMgr_tar_info {
291 UCHAR TarLUN_CA; /*Contingent Allgiance */
297 UCHAR TarReserved[2]; /* for alignment */
298 UCHAR LunDiscQ_Idx[MAX_LUN];
299 UCHAR TarLUNBusy[MAX_LUN];
302 typedef struct NVRAMInfo {
303 UCHAR niModel; /* Model No. of card */
304 UCHAR niCardNo; /* Card no. */
305 ULONG niBaseAddr; /* Port Address of card */
306 UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
307 UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
308 UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
309 UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
310 UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
311 UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
314 typedef NVRAMINFO *PNVRamInfo;
322 typedef struct SCCBcard {
324 PSCCBMGR_INFO cardInfo;
335 PNVRamInfo pNvRamInfo;
336 PSCCB discQ_Tbl[QUEUE_DEPTH];
340 typedef struct SCCBcard *PSCCBcard;
343 #define F_TAG_STARTED 0x01
344 #define F_CONLUN_IO 0x02
345 #define F_DO_RENEGO 0x04
346 #define F_NO_FILTER 0x08
347 #define F_GREEN_PC 0x10
348 #define F_HOST_XFER_ACT 0x20
349 #define F_NEW_SCCB_CMD 0x40
350 #define F_UPDATE_EEPROM 0x80
353 #define ID_STRING_LENGTH 32
354 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
357 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
359 #define ASSIGN_ID 0x00
360 #define SET_P_FLAG 0x01
361 #define CFG_CMPLT 0x03
362 #define DOM_MSTR 0x0F
363 #define SYNC_PTRN 0x1F
367 #define MISC_CODE 0x14
368 #define CLR_P_FLAG 0x18
372 #define INIT_SELTD 0x01
373 #define LEVEL2_TAR 0x02
376 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
377 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
378 CLR_PRIORITY,NO_ID_AVAIL };
380 typedef struct SCCBscam_info {
382 UCHAR id_string[ID_STRING_LENGTH];
383 enum scam_id_st state;
388 #define SCSI_REQUEST_SENSE 0x03
389 #define SCSI_READ 0x08
390 #define SCSI_WRITE 0x0A
391 #define SCSI_START_STOP_UNIT 0x1B
392 #define SCSI_READ_EXTENDED 0x28
393 #define SCSI_WRITE_EXTENDED 0x2A
394 #define SCSI_WRITE_AND_VERIFY 0x2E
400 #define SSQ_FULL 0x28
405 #define SMCMD_COMP 0x00
407 #define SMSAVE_DATA_PTR 0x02
408 #define SMREST_DATA_PTR 0x03
411 #define SMREJECT 0x07
413 #define SMPARITY 0x09
414 #define SMDEV_RESET 0x0C
415 #define SMABORT_TAG 0x0D
416 #define SMINIT_RECOVERY 0x0F
417 #define SMREL_RECOVERY 0x10
420 #define DISC_PRIV 0x40
427 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
436 #define SIX_BYTE_CMD 0x06
437 #define TWELVE_BYTE_CMD 0x0C
440 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
443 #define EEPROM_WD_CNT 256
445 #define EEPROM_CHECK_SUM 0
446 #define FW_SIGNATURE 2
447 #define MODEL_NUMB_0 4
448 #define MODEL_NUMB_2 6
449 #define MODEL_NUMB_4 8
450 #define SYSTEM_CONFIG 16
451 #define SCSI_CONFIG 17
452 #define BIOS_CONFIG 18
453 #define SCAM_CONFIG 20
454 #define ADAPTER_SCSI_ID 24
457 #define IGNORE_B_SCAN 32
458 #define SEND_START_ENA 34
459 #define DEVICE_ENABLE 36
461 #define SYNC_RATE_TBL 38
462 #define SYNC_RATE_TBL01 38
463 #define SYNC_RATE_TBL23 40
464 #define SYNC_RATE_TBL45 42
465 #define SYNC_RATE_TBL67 44
466 #define SYNC_RATE_TBL89 46
467 #define SYNC_RATE_TBLab 48
468 #define SYNC_RATE_TBLcd 50
469 #define SYNC_RATE_TBLef 52
473 #define EE_SCAMBASE 256
477 #define SCAM_ENABLED BIT(2)
478 #define SCAM_LEVEL2 BIT(3)
481 #define RENEGO_ENA BITW(10)
482 #define CONNIO_ENA BITW(11)
483 #define GREEN_PC_ENA BITW(12)
486 #define AUTO_RATE_00 00
487 #define AUTO_RATE_05 01
488 #define AUTO_RATE_10 02
489 #define AUTO_RATE_20 03
491 #define WIDE_NEGO_BIT BIT(7)
492 #define DISC_ENABLE_BIT BIT(6)
496 #define hp_vendor_id_0 0x00 /* LSB */
497 #define ORION_VEND_0 0x4B
499 #define hp_vendor_id_1 0x01 /* MSB */
500 #define ORION_VEND_1 0x10
502 #define hp_device_id_0 0x02 /* LSB */
503 #define ORION_DEV_0 0x30
505 #define hp_device_id_1 0x03 /* MSB */
506 #define ORION_DEV_1 0x81
508 /* Sub Vendor ID and Sub Device ID only available in
509 Harpoon Version 2 and higher */
511 #define hp_sub_device_id_0 0x06 /* LSB */
515 #define hp_semaphore 0x0C
516 #define SCCB_MGR_ACTIVE BIT(0)
517 #define TICKLE_ME BIT(1)
518 #define SCCB_MGR_PRESENT BIT(3)
519 #define BIOS_IN_USE BIT(4)
523 #define hp_sys_ctrl 0x0F
525 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
526 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
527 #define HALT_MACH BIT(3) /*Halt State Machine */
528 #define HARD_ABORT BIT(4) /*Hard Abort */
538 #define hp_host_blk_cnt 0x13
540 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
542 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
546 #define hp_int_mask 0x17
548 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
549 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
552 #define hp_xfer_cnt_lo 0x18
553 #define hp_xfer_cnt_hi 0x1A
554 #define hp_xfer_cmd 0x1B
556 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
557 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
560 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
562 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
564 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
566 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
567 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
569 #define hp_host_addr_lo 0x1C
570 #define hp_host_addr_hmi 0x1E
572 #define hp_ee_ctrl 0x22
574 #define EXT_ARB_ACK BIT(7)
575 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
576 #define SEE_MS BIT(5)
577 #define SEE_CS BIT(3)
578 #define SEE_CLK BIT(2)
579 #define SEE_DO BIT(1)
580 #define SEE_DI BIT(0)
583 #define EE_WRITE 0x05
585 #define EWEN_ADDR 0x03C0
587 #define EWDS_ADDR 0x0000
595 #define hp_bm_ctrl 0x26
597 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
598 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
599 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
600 #define FAST_SINGLE BIT(6) /*?? */
602 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
605 #define hp_sg_addr 0x28
606 #define hp_page_ctrl 0x29
608 #define SCATTER_EN BIT(0)
609 #define SGRAM_ARAM BIT(1)
610 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
611 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
616 #define hp_pci_stat_cfg 0x2D
618 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
627 #define hp_rev_num 0x33
630 #define hp_stack_data 0x34
631 #define hp_stack_addr 0x35
633 #define hp_ext_status 0x36
635 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
636 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
637 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
638 #define CMD_ABORTED BIT(4) /*Command aborted */
639 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
640 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
641 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
642 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
643 BM_PARITY_ERR | PIO_OVERRUN)
645 #define hp_int_status 0x37
647 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
648 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
649 #define INT_ASSERTED BIT(5) /* */
652 #define hp_fifo_cnt 0x38
657 #define hp_intena 0x40
659 #define RESET BITW(7)
660 #define PROG_HLT BITW(6)
661 #define PARITY BITW(5)
664 #define SCAM_SEL BITW(2)
666 #define TIMEOUT BITW(0)
667 #define BUS_FREE BITW(15)
668 #define XFER_CNT_0 BITW(14)
669 #define PHASE BITW(13)
670 #define IUNKWN BITW(12)
671 #define ICMD_COMP BITW(11)
672 #define ITICKLE BITW(10)
673 #define IDO_STRT BITW(9)
674 #define ITAR_DISC BITW(8)
675 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
676 #define CLR_ALL_INT 0xFFFF
677 #define CLR_ALL_INT_1 0xFF00
679 #define hp_intstat 0x42
681 #define hp_scsisig 0x44
683 #define SCSI_SEL BIT(7)
684 #define SCSI_BSY BIT(6)
685 #define SCSI_REQ BIT(5)
686 #define SCSI_ACK BIT(4)
687 #define SCSI_ATN BIT(3)
688 #define SCSI_CD BIT(2)
689 #define SCSI_MSG BIT(1)
690 #define SCSI_IOBIT BIT(0)
692 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
693 #define S_MSGO_PH (BIT(2)+BIT(1) )
694 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
695 #define S_DATAI_PH ( BIT(0))
696 #define S_DATAO_PH 0x00
697 #define S_ILL_PH ( BIT(1) )
699 #define hp_scsictrl_0 0x45
701 #define SEL_TAR BIT(6)
702 #define ENA_ATN BIT(4)
703 #define ENA_RESEL BIT(2)
704 #define SCSI_RST BIT(1)
705 #define ENA_SCAM_SEL BIT(0)
709 #define hp_portctrl_0 0x46
711 #define SCSI_PORT BIT(7)
712 #define SCSI_INBIT BIT(6)
713 #define DMA_PORT BIT(5)
714 #define DMA_RD BIT(4)
715 #define HOST_PORT BIT(3)
716 #define HOST_WRT BIT(2)
717 #define SCSI_BUS_EN BIT(1)
718 #define START_TO BIT(0)
720 #define hp_scsireset 0x47
722 #define SCSI_INI BIT(6)
723 #define SCAM_EN BIT(5)
724 #define DMA_RESET BIT(3)
725 #define HPSCSI_RESET BIT(2)
726 #define PROG_RESET BIT(1)
727 #define FIFO_CLR BIT(0)
729 #define hp_xfercnt_0 0x48
730 #define hp_xfercnt_2 0x4A
732 #define hp_fifodata_0 0x4C
733 #define hp_addstat 0x4E
735 #define SCAM_TIMER BIT(7)
736 #define SCSI_MODE8 BIT(3)
737 #define SCSI_PAR_ERR BIT(0)
739 #define hp_prgmcnt_0 0x4F
742 #define hp_selfid_0 0x50
743 #define hp_selfid_1 0x51
744 #define hp_arb_id 0x52
747 #define hp_select_id 0x53
750 #define hp_synctarg_base 0x54
751 #define hp_synctarg_12 0x54
752 #define hp_synctarg_13 0x55
753 #define hp_synctarg_14 0x56
754 #define hp_synctarg_15 0x57
756 #define hp_synctarg_8 0x58
757 #define hp_synctarg_9 0x59
758 #define hp_synctarg_10 0x5A
759 #define hp_synctarg_11 0x5B
761 #define hp_synctarg_4 0x5C
762 #define hp_synctarg_5 0x5D
763 #define hp_synctarg_6 0x5E
764 #define hp_synctarg_7 0x5F
766 #define hp_synctarg_0 0x60
767 #define hp_synctarg_1 0x61
768 #define hp_synctarg_2 0x62
769 #define hp_synctarg_3 0x63
771 #define NARROW_SCSI BIT(4)
772 #define DEFAULT_OFFSET 0x0F
774 #define hp_autostart_0 0x64
775 #define hp_autostart_1 0x65
776 #define hp_autostart_3 0x67
780 #define AUTO_IMMED BIT(5)
781 #define SELECT BIT(6)
782 #define END_DATA (BIT(7)+BIT(6))
784 #define hp_gp_reg_0 0x68
785 #define hp_gp_reg_1 0x69
786 #define hp_gp_reg_3 0x6B
788 #define hp_seltimeout 0x6C
791 #define TO_4ms 0x67 /* 3.9959ms */
793 #define TO_5ms 0x03 /* 4.9152ms */
794 #define TO_10ms 0x07 /* 11.xxxms */
795 #define TO_250ms 0x99 /* 250.68ms */
796 #define TO_290ms 0xB1 /* 289.99ms */
798 #define hp_clkctrl_0 0x6D
800 #define PWR_DWN BIT(6)
801 #define ACTdeassert BIT(4)
802 #define CLK_40MHZ (BIT(1) + BIT(0))
804 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
806 #define hp_fiforead 0x6E
807 #define hp_fifowrite 0x6F
809 #define hp_offsetctr 0x70
810 #define hp_xferstat 0x71
812 #define FIFO_EMPTY BIT(6)
814 #define hp_portctrl_1 0x72
816 #define CHK_SCSI_P BIT(3)
817 #define HOST_MODE8 BIT(0)
819 #define hp_xfer_pad 0x73
821 #define ID_UNLOCK BIT(3)
823 #define hp_scsidata_0 0x74
824 #define hp_scsidata_1 0x75
828 #define hp_aramBase 0x80
829 #define BIOS_DATA_OFFSET 0x60
830 #define BIOS_RELATIVE_CARD 0x64
835 #define AR3 (BITW(9) + BITW(8))
836 #define SDATA BITW(10)
839 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
841 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
845 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
847 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
850 #define ADATA_OUT 0x00
851 #define ADATA_IN BITW(8)
852 #define ACOMMAND BITW(10)
853 #define ASTATUS (BITW(10)+BITW(8))
854 #define AMSG_OUT (BITW(10)+BITW(9))
855 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
858 #define BRH_OP BITW(13) /* Branch */
862 #define EQUAL BITW(8)
863 #define NOT_EQ BITW(9)
865 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
868 #define FIFO_0 BITW(10)
871 #define MPM_OP BITW(15) /* Match phase and move data */
874 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
877 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
882 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
892 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
894 #define SSI_OP (BITW(15)+BITW(11))
897 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
898 #define SSI_IDO_STRT (IDO_STRT >> 8)
900 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
901 #define SSI_ITICKLE (ITICKLE >> 8)
903 #define SSI_IUNKWN (IUNKWN >> 8)
904 #define SSI_INO_CC (IUNKWN >> 8)
905 #define SSI_IRFAIL (IUNKWN >> 8)
908 #define NP 0x10 /*Next Phase */
909 #define NTCMD 0x02 /*Non- Tagged Command start */
910 #define CMDPZ 0x04 /*Command phase */
911 #define DINT 0x12 /*Data Out/In interrupt */
912 #define DI 0x13 /*Data Out */
913 #define DC 0x19 /*Disconnect Message */
914 #define ST 0x1D /*Status Phase */
915 #define UNKNWN 0x24 /*Unknown bus action */
916 #define CC 0x25 /*Command Completion failure */
917 #define TICK 0x26 /*New target reselected us. */
918 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
921 #define ID_MSG_STRT hp_aramBase + 0x00
922 #define NON_TAG_ID_MSG hp_aramBase + 0x06
923 #define CMD_STRT hp_aramBase + 0x08
924 #define SYNC_MSGS hp_aramBase + 0x08
930 #define TAG_STRT 0x00
931 #define DISCONNECT_START 0x10/2
932 #define END_DATA_START 0x14/2
933 #define CMD_ONLY_STRT CMDPZ/2
934 #define SELCHK_STRT SELCHK/2
944 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
945 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
947 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
949 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
951 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
952 WR_HARP32(port,hp_xfercnt_0,count),\
953 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
955 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
957 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
958 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
961 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
962 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
966 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
967 WR_HARPOON(port+hp_scsireset, 0x00))
969 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
970 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
972 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
973 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
975 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
976 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
978 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
979 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
984 static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
985 static void FPT_ssel(ULONG port, UCHAR p_card);
986 static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
987 static void FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
988 static void FPT_stsyncn(ULONG port, UCHAR p_card);
989 static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
990 static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
991 PSCCBMgr_tar_info currTar_Info);
992 static void FPT_sresb(ULONG port, UCHAR p_card);
993 static void FPT_sxfrp(ULONG p_port, UCHAR p_card);
994 static void FPT_schkdd(ULONG port, UCHAR p_card);
995 static UCHAR FPT_RdStack(ULONG port, UCHAR index);
996 static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
997 static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
999 static void FPT_SendMsg(ULONG port, UCHAR message);
1000 static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1003 static void FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1004 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1006 static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
1007 static void FPT_stwidn(ULONG port, UCHAR p_card);
1008 static void FPT_siwidr(ULONG port, UCHAR width);
1011 static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
1012 static void FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
1013 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1015 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
1016 static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
1017 static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
1018 static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
1019 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1020 static USHORT FPT_CalcCrc16(UCHAR buffer[]);
1021 static UCHAR FPT_CalcLrc(UCHAR buffer[]);
1024 static void FPT_Wait1Second(ULONG p_port);
1025 static void FPT_Wait(ULONG p_port, UCHAR p_delay);
1026 static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
1027 static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1028 static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1029 static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1030 static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
1034 static void FPT_phaseDataOut(ULONG port, UCHAR p_card);
1035 static void FPT_phaseDataIn(ULONG port, UCHAR p_card);
1036 static void FPT_phaseCommand(ULONG port, UCHAR p_card);
1037 static void FPT_phaseStatus(ULONG port, UCHAR p_card);
1038 static void FPT_phaseMsgOut(ULONG port, UCHAR p_card);
1039 static void FPT_phaseMsgIn(ULONG port, UCHAR p_card);
1040 static void FPT_phaseIllegal(ULONG port, UCHAR p_card);
1042 static void FPT_phaseDecode(ULONG port, UCHAR p_card);
1043 static void FPT_phaseChkFifo(ULONG port, UCHAR p_card);
1044 static void FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
1049 static void FPT_XbowInit(ULONG port, UCHAR scamFlg);
1050 static void FPT_BusMasterInit(ULONG p_port);
1051 static void FPT_DiagEEPROM(ULONG p_port);
1056 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1057 static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1058 static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1059 static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
1060 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1063 static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1064 PSCCBcard pCurrCard, USHORT p_int);
1066 static void FPT_SccbMgrTableInitAll(void);
1067 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1068 static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
1072 static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
1074 static int FPT_scarb(ULONG p_port, UCHAR p_sel_type);
1075 static void FPT_scbusf(ULONG p_port);
1076 static void FPT_scsel(ULONG p_port);
1077 static void FPT_scasid(UCHAR p_card, ULONG p_port);
1078 static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
1079 static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
1080 static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
1081 static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
1082 static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
1083 static UCHAR FPT_scvalq(UCHAR p_quintet);
1084 static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
1085 static void FPT_scwtsel(ULONG p_port);
1086 static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
1087 static void FPT_scsavdi(UCHAR p_card, ULONG p_port);
1088 static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
1091 static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1092 static void FPT_autoLoadDefaultMap(ULONG p_port);
1097 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1098 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1099 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1100 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1103 static UCHAR FPT_mbCards = 0;
1104 static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1105 ' ', 'B', 'T', '-', '9', '3', '0', \
1106 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1107 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1109 static USHORT FPT_default_intena = 0;
1112 static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
1115 /*---------------------------------------------------------------------
1117 * Function: FlashPoint_ProbeHostAdapter
1119 * Description: Setup and/or Search for cards and return info to caller.
1121 *---------------------------------------------------------------------*/
1123 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1125 static UCHAR first_time = 1;
1127 UCHAR i,j,id,ScamFlg;
1128 USHORT temp,temp2,temp3,temp4,temp5,temp6;
1130 PNVRamInfo pCurrNvRam;
1132 ioport = pCardInfo->si_baseaddr;
1135 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1136 return((int)FAILURE);
1138 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1139 return((int)FAILURE);
1141 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1142 return((int)FAILURE);
1144 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1145 return((int)FAILURE);
1148 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1150 /* For new Harpoon then check for sub_device ID LSB
1151 the bits(0-3) must be all ZERO for compatible with
1152 current version of SCCBMgr, else skip this Harpoon
1155 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1156 return((int)FAILURE);
1161 FPT_SccbMgrTableInitAll();
1166 if(FPT_RdStack(ioport, 0) != 0x00) {
1167 if(FPT_ChkIfChipInitialized(ioport) == 0)
1170 WR_HARPOON(ioport+hp_semaphore, 0x00);
1171 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1172 FPT_DiagEEPROM(ioport);
1176 if(FPT_mbCards < MAX_MB_CARDS) {
1177 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1179 pCurrNvRam->niBaseAddr = ioport;
1180 FPT_RNVRamData(pCurrNvRam);
1182 return((int) FAILURE);
1187 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1188 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1191 pCardInfo->si_id = pCurrNvRam->niAdapId;
1193 pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1196 pCardInfo->si_lun = 0x00;
1197 pCardInfo->si_fw_revision = ORION_FW_REV;
1204 for (id = 0; id < (16/2); id++) {
1207 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1208 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1209 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1211 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1213 for (i = 0; i < 2; temp >>=8,i++) {
1222 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1223 temp6 |= 0x8000; /* Fall through */
1224 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1225 temp5 |= 0x8000; /* Fall through */
1226 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1227 temp2 |= 0x8000; /* Fall through */
1228 case AUTO_RATE_00: /* Asynchronous */
1232 if (temp & DISC_ENABLE_BIT)
1235 if (temp & WIDE_NEGO_BIT)
1241 pCardInfo->si_per_targ_init_sync = temp2;
1242 pCardInfo->si_per_targ_no_disc = temp3;
1243 pCardInfo->si_per_targ_wide_nego = temp4;
1244 pCardInfo->si_per_targ_fast_nego = temp5;
1245 pCardInfo->si_per_targ_ultra_nego = temp6;
1248 i = pCurrNvRam->niSysConf;
1250 i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1253 ScamFlg = pCurrNvRam->niScamConf;
1255 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1257 pCardInfo->si_flags = 0x0000;
1260 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1263 pCardInfo->si_flags |= SOFT_RESET;
1266 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1268 if (ScamFlg & SCAM_ENABLED)
1269 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1271 if (ScamFlg & SCAM_LEVEL2)
1272 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1274 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1276 j |= SCSI_TERM_ENA_L;
1278 WR_HARPOON(ioport+hp_bm_ctrl, j );
1280 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1282 j |= SCSI_TERM_ENA_H;
1284 WR_HARPOON(ioport+hp_ee_ctrl, j );
1286 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1288 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1290 pCardInfo->si_card_family = HARPOON_FAMILY;
1291 pCardInfo->si_bustype = BUSTYPE_PCI;
1294 pCardInfo->si_card_model[0] = '9';
1295 switch(pCurrNvRam->niModel & 0x0f){
1297 pCardInfo->si_card_model[1] = '3';
1298 pCardInfo->si_card_model[2] = '0';
1301 pCardInfo->si_card_model[1] = '5';
1302 pCardInfo->si_card_model[2] = '0';
1305 pCardInfo->si_card_model[1] = '3';
1306 pCardInfo->si_card_model[2] = '2';
1309 pCardInfo->si_card_model[1] = '5';
1310 pCardInfo->si_card_model[2] = '2';
1314 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1315 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
1316 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1318 pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
1319 pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
1322 if (pCardInfo->si_card_model[1] == '3')
1324 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1325 pCardInfo->si_flags |= LOW_BYTE_TERM;
1327 else if (pCardInfo->si_card_model[2] == '0')
1329 temp = RD_HARPOON(ioport+hp_xfer_pad);
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1331 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1332 pCardInfo->si_flags |= LOW_BYTE_TERM;
1333 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1334 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1335 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1336 WR_HARPOON(ioport+hp_xfer_pad, temp);
1340 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1341 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1342 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1343 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1345 for (i = 0; i < 8; i++)
1348 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1350 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1351 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1353 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1354 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1355 if (!(temp3 & BIT(7)))
1356 pCardInfo->si_flags |= LOW_BYTE_TERM;
1357 if (!(temp3 & BIT(6)))
1358 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1362 ARAM_ACCESS(ioport);
1364 for ( i = 0; i < 4; i++ ) {
1366 pCardInfo->si_XlatInfo[i] =
1367 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1370 /* return with -1 if no sort, else return with
1371 logical card number sorted by BIOS (zero-based) */
1373 pCardInfo->si_relative_cardnum =
1374 (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1376 SGRAM_ACCESS(ioport);
1378 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1379 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1380 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1381 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1382 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1383 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1384 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1385 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1387 pCardInfo->si_present = 0x01;
1393 /*---------------------------------------------------------------------
1395 * Function: FlashPoint_HardwareResetHostAdapter
1397 * Description: Setup adapter for normal operation (hard reset).
1399 *---------------------------------------------------------------------*/
1401 static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1403 PSCCBcard CurrCard = NULL;
1404 PNVRamInfo pCurrNvRam;
1405 UCHAR i,j,thisCard, ScamFlg;
1406 USHORT temp,sync_bit_map,id;
1409 ioport = pCardInfo->si_baseaddr;
1411 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1413 if (thisCard == MAX_CARDS) {
1418 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1420 CurrCard = &FPT_BL_Card[thisCard];
1421 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1425 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1427 FPT_BL_Card[thisCard].ioPort = ioport;
1428 CurrCard = &FPT_BL_Card[thisCard];
1431 for(i = 0; i < FPT_mbCards; i++){
1432 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1433 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1435 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1436 CurrCard->cardIndex = thisCard;
1437 CurrCard->cardInfo = pCardInfo;
1443 pCurrNvRam = CurrCard->pNvRamInfo;
1446 ScamFlg = pCurrNvRam->niScamConf;
1449 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1453 FPT_BusMasterInit(ioport);
1454 FPT_XbowInit(ioport, ScamFlg);
1456 FPT_autoLoadDefaultMap(ioport);
1459 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1461 WR_HARPOON(ioport+hp_selfid_0, id);
1462 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1463 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1464 CurrCard->ourId = pCardInfo->si_id;
1466 i = (UCHAR) pCardInfo->si_flags;
1467 if (i & SCSI_PARITY_ENA)
1468 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1470 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1471 if (i & LOW_BYTE_TERM)
1472 j |= SCSI_TERM_ENA_L;
1473 WR_HARPOON(ioport+hp_bm_ctrl, j);
1475 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1476 if (i & HIGH_BYTE_TERM)
1477 j |= SCSI_TERM_ENA_H;
1478 WR_HARPOON(ioport+hp_ee_ctrl, j );
1481 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1483 FPT_sresb(ioport,thisCard);
1485 FPT_scini(thisCard, pCardInfo->si_id, 0);
1490 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1491 CurrCard->globalFlags |= F_NO_FILTER;
1494 if(pCurrNvRam->niSysConf & 0x10)
1495 CurrCard->globalFlags |= F_GREEN_PC;
1498 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1499 CurrCard->globalFlags |= F_GREEN_PC;
1502 /* Set global flag to indicate Re-Negotiation to be done on all
1505 if(pCurrNvRam->niScsiConf & 0x04)
1506 CurrCard->globalFlags |= F_DO_RENEGO;
1509 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1510 CurrCard->globalFlags |= F_DO_RENEGO;
1514 if(pCurrNvRam->niScsiConf & 0x08)
1515 CurrCard->globalFlags |= F_CONLUN_IO;
1518 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1519 CurrCard->globalFlags |= F_CONLUN_IO;
1523 temp = pCardInfo->si_per_targ_no_disc;
1525 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1528 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1531 sync_bit_map = 0x0001;
1533 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1536 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1537 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1538 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1540 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1542 for (i = 0; i < 2; temp >>=8,i++) {
1544 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1546 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
1550 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1551 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1552 (UCHAR)(temp & ~EE_SYNC_MASK);
1555 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1558 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1560 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1564 else { /* NARROW SCSI */
1565 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1576 WR_HARPOON((ioport+hp_semaphore),
1577 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1579 return((ULONG)CurrCard);
1582 static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
1589 PNVRamInfo pCurrNvRam;
1591 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1597 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1598 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1600 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1601 FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
1603 portBase = pCurrNvRam->niBaseAddr;
1605 for(i = 0; i < MAX_SCSI_TAR; i++){
1606 regOffset = hp_aramBase + 64 + i*4;
1607 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1608 scamData = *pScamTbl;
1609 WR_HARP32(portBase, regOffset, scamData);
1613 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1618 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1626 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1627 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1628 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1629 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1630 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1632 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1633 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
1635 portBase = pNvRamInfo->niBaseAddr;
1637 for(i = 0; i < MAX_SCSI_TAR; i++){
1638 regOffset = hp_aramBase + 64 + i*4;
1639 RD_HARP32(portBase, regOffset, scamData);
1640 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1641 *pScamTbl = scamData;
1646 static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
1648 WR_HARPOON(portBase + hp_stack_addr, index);
1649 return(RD_HARPOON(portBase + hp_stack_data));
1652 static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
1654 WR_HARPOON(portBase + hp_stack_addr, index);
1655 WR_HARPOON(portBase + hp_stack_data, data);
1659 static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
1661 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1663 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1666 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1667 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1672 /*---------------------------------------------------------------------
1674 * Function: FlashPoint_StartCCB
1676 * Description: Start a command pointed to by p_Sccb. When the
1677 * command is completed it will be returned via the
1678 * callback function.
1680 *---------------------------------------------------------------------*/
1681 static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
1684 UCHAR thisCard, lun;
1686 CALL_BK_FN callback;
1688 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1689 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1691 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1694 p_Sccb->HostStatus = SCCB_COMPLETE;
1695 p_Sccb->SccbStatus = SCCB_ERROR;
1696 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1703 FPT_sinits(p_Sccb,thisCard);
1706 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1708 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1709 | SCCB_MGR_ACTIVE));
1711 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1713 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1714 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1718 ((PSCCBcard)pCurrCard)->cmdCounter++;
1720 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1722 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1724 if(p_Sccb->OperationCode == RESET_COMMAND)
1726 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1727 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1728 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1729 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1733 FPT_queueAddSccb(p_Sccb,thisCard);
1737 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1739 if(p_Sccb->OperationCode == RESET_COMMAND)
1741 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1742 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1743 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1744 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1748 FPT_queueAddSccb(p_Sccb,thisCard);
1754 MDISABLE_INT(ioport);
1756 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1757 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1761 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1762 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1763 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1766 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1767 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1772 if(p_Sccb->OperationCode == RESET_COMMAND)
1774 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1775 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1776 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1777 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1781 FPT_queueAddSccb(p_Sccb,thisCard);
1786 MENABLE_INT(ioport);
1792 /*---------------------------------------------------------------------
1794 * Function: FlashPoint_AbortCCB
1796 * Description: Abort the command pointed to by p_Sccb. When the
1797 * command is completed it will be returned via the
1798 * callback function.
1800 *---------------------------------------------------------------------*/
1801 static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
1806 CALL_BK_FN callback;
1809 PSCCBMgr_tar_info currTar_Info;
1812 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1814 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1816 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1819 if (FPT_queueFindSccb(p_Sccb,thisCard))
1822 ((PSCCBcard)pCurrCard)->cmdCounter--;
1824 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1825 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1826 & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1828 p_Sccb->SccbStatus = SCCB_ABORT;
1829 callback = p_Sccb->SccbCallback;
1837 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1839 p_Sccb->SccbStatus = SCCB_ABORT;
1847 TID = p_Sccb->TargID;
1850 if(p_Sccb->Sccb_tag)
1852 MDISABLE_INT(ioport);
1853 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1855 p_Sccb->SccbStatus = SCCB_ABORT;
1856 p_Sccb->Sccb_scsistat = ABORT_ST;
1857 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1859 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1861 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1862 FPT_ssel(ioport, thisCard);
1866 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1867 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1868 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1869 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1872 MENABLE_INT(ioport);
1877 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1879 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1882 p_Sccb->SccbStatus = SCCB_ABORT;
1893 /*---------------------------------------------------------------------
1895 * Function: FlashPoint_InterruptPending
1897 * Description: Do a quick check to determine if there is a pending
1898 * interrupt for this card and disable the IRQ Pin if so.
1900 *---------------------------------------------------------------------*/
1901 static UCHAR FlashPoint_InterruptPending(ULONG pCurrCard)
1905 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1907 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1919 /*---------------------------------------------------------------------
1921 * Function: FlashPoint_HandleInterrupt
1923 * Description: This is our entry point when an interrupt is generated
1924 * by the card and the upper level driver passes it on to
1927 *---------------------------------------------------------------------*/
1928 static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
1931 UCHAR thisCard,result,bm_status, bm_int_st;
1936 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1937 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1939 MDISABLE_INT(ioport);
1941 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1942 bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
1946 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1948 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1952 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1954 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1955 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1956 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1961 MENABLE_INT(ioport);
1967 else if (hp_int & ICMD_COMP) {
1969 if ( !(hp_int & BUS_FREE) ) {
1970 /* Wait for the BusFree before starting a new command. We
1971 must also check for being reselected since the BusFree
1972 may not show up if another device reselects us in 1.5us or
1973 less. SRR Wednesday, 3/8/1995.
1975 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1978 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1980 FPT_phaseChkFifo(ioport, thisCard);
1982 /* WRW_HARPOON((ioport+hp_intstat),
1983 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1986 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1988 FPT_autoCmdCmplt(ioport,thisCard);
1993 else if (hp_int & ITAR_DISC)
1996 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1998 FPT_phaseChkFifo(ioport, thisCard);
2002 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2004 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2005 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2007 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2010 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2011 FPT_queueDisconnect(currSCCB,thisCard);
2013 /* Wait for the BusFree before starting a new command. We
2014 must also check for being reselected since the BusFree
2015 may not show up if another device reselects us in 1.5us or
2016 less. SRR Wednesday, 3/8/1995.
2018 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2019 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2020 RD_HARPOON((ioport+hp_scsisig)) ==
2021 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2024 The additional loop exit condition above detects a timing problem
2025 with the revision D/E harpoon chips. The caller should reset the
2026 host adapter to recover when 0xFE is returned.
2028 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2030 MENABLE_INT(ioport);
2034 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2037 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2042 else if (hp_int & RSEL) {
2044 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2046 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2048 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2050 FPT_phaseChkFifo(ioport, thisCard);
2053 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2055 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2056 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2057 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2060 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2061 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2062 FPT_queueDisconnect(currSCCB,thisCard);
2065 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2066 FPT_phaseDecode(ioport,thisCard);
2071 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2074 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2075 FPT_phaseDecode(ioport,thisCard);
2080 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2082 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2083 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
2085 FPT_phaseDecode(ioport,thisCard);
2089 /* Harpoon problem some SCSI target device respond to selection
2090 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2091 to latch the correct Target ID into reg. x53.
2092 The work around require to correct this reg. But when write to this
2093 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2094 need to read this reg first then restore it later. After update to 0x53 */
2096 i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
2097 target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
2098 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
2099 WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
2100 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
2101 WR_HARPOON(ioport+hp_fifowrite, i);
2102 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2106 else if (hp_int & XFER_CNT_0) {
2108 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2110 FPT_schkdd(ioport,thisCard);
2115 else if (hp_int & BUS_FREE) {
2117 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2119 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2121 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2124 FPT_phaseBusFree(ioport,thisCard);
2128 else if (hp_int & ITICKLE) {
2130 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2131 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2136 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2139 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2142 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2144 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2147 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2148 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2149 FPT_ssel(ioport,thisCard);
2158 MENABLE_INT(ioport);
2163 /*---------------------------------------------------------------------
2165 * Function: Sccb_bad_isr
2167 * Description: Some type of interrupt has occurred which is slightly
2168 * out of the ordinary. We will now decode it fully, in
2169 * this routine. This is broken up in an attempt to save
2172 *---------------------------------------------------------------------*/
2173 static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2174 PSCCBcard pCurrCard, USHORT p_int)
2176 UCHAR temp, ScamFlg;
2177 PSCCBMgr_tar_info currTar_Info;
2178 PNVRamInfo pCurrNvRam;
2181 if (RD_HARPOON(p_port+hp_ext_status) &
2182 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2185 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2188 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2191 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2194 WR_HARPOON(p_port+hp_pci_stat_cfg,
2195 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2197 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2201 if (pCurrCard->currentSCCB != NULL)
2204 if (!pCurrCard->currentSCCB->HostStatus)
2205 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2207 FPT_sxfrp(p_port,p_card);
2209 temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
2210 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2211 WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
2212 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2214 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2216 FPT_phaseDecode(p_port,p_card);
2222 else if (p_int & RESET)
2225 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2226 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2227 if (pCurrCard->currentSCCB != NULL) {
2229 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2231 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2235 DISABLE_AUTO(p_port);
2237 FPT_sresb(p_port,p_card);
2239 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2241 pCurrNvRam = pCurrCard->pNvRamInfo;
2243 ScamFlg = pCurrNvRam->niScamConf;
2246 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2249 FPT_XbowInit(p_port, ScamFlg);
2251 FPT_scini(p_card, pCurrCard->ourId, 0);
2257 else if (p_int & FIFO) {
2259 WRW_HARPOON((p_port+hp_intstat), FIFO);
2261 if (pCurrCard->currentSCCB != NULL)
2262 FPT_sxfrp(p_port,p_card);
2265 else if (p_int & TIMEOUT)
2268 DISABLE_AUTO(p_port);
2270 WRW_HARPOON((p_port+hp_intstat),
2271 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2273 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2276 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2277 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2278 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2279 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2281 currTar_Info->TarLUNBusy[0] = 0;
2284 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2286 currTar_Info->TarSyncCtrl = 0;
2287 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2290 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2292 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2295 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2297 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2301 else if (p_int & SCAM_SEL)
2304 FPT_scarb(p_port,LEVEL2_TAR);
2306 FPT_scasid(p_card, p_port);
2310 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2317 /*---------------------------------------------------------------------
2319 * Function: SccbMgrTableInit
2321 * Description: Initialize all Sccb manager data structures.
2323 *---------------------------------------------------------------------*/
2325 static void FPT_SccbMgrTableInitAll()
2329 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2331 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2333 FPT_BL_Card[thisCard].ioPort = 0x00;
2334 FPT_BL_Card[thisCard].cardInfo = NULL;
2335 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2336 FPT_BL_Card[thisCard].ourId = 0x00;
2337 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2342 /*---------------------------------------------------------------------
2344 * Function: SccbMgrTableInit
2346 * Description: Initialize all Sccb manager data structures.
2348 *---------------------------------------------------------------------*/
2350 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
2354 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2356 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2359 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2361 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2362 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2363 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2366 pCurrCard->scanIndex = 0x00;
2367 pCurrCard->currentSCCB = NULL;
2368 pCurrCard->globalFlags = 0x00;
2369 pCurrCard->cmdCounter = 0x00;
2370 pCurrCard->tagQ_Lst = 0x01;
2371 pCurrCard->discQCount = 0;
2377 /*---------------------------------------------------------------------
2379 * Function: SccbMgrTableInit
2381 * Description: Initialize all Sccb manager data structures.
2383 *---------------------------------------------------------------------*/
2385 static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
2389 PSCCBMgr_tar_info currTar_Info;
2391 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2393 currTar_Info->TarSelQ_Cnt = 0;
2394 currTar_Info->TarSyncCtrl = 0;
2396 currTar_Info->TarSelQ_Head = NULL;
2397 currTar_Info->TarSelQ_Tail = NULL;
2398 currTar_Info->TarTagQ_Cnt = 0;
2399 currTar_Info->TarLUN_CA = 0;
2402 for (lun = 0; lun < MAX_LUN; lun++)
2404 currTar_Info->TarLUNBusy[lun] = 0;
2405 currTar_Info->LunDiscQ_Idx[lun] = 0;
2408 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2410 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2412 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2414 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2415 FPT_BL_Card[p_card].discQCount--;
2422 /*---------------------------------------------------------------------
2426 * Description: Read in a message byte from the SCSI bus, and check
2427 * for a parity error.
2429 *---------------------------------------------------------------------*/
2431 static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
2437 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2438 (TimeOutLoop++ < 20000) ){}
2441 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2443 message = RD_HARPOON(port+hp_scsidata_0);
2445 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2448 if (TimeOutLoop > 20000)
2449 message = 0x00; /* force message byte = 0 if Time Out on Req */
2451 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2452 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2454 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2455 WR_HARPOON(port+hp_xferstat, 0);
2456 WR_HARPOON(port+hp_fiforead, 0);
2457 WR_HARPOON(port+hp_fifowrite, 0);
2458 if (pCurrSCCB != NULL)
2460 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2465 ACCEPT_MSG_ATN(port);
2467 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2468 (TimeOutLoop++ < 20000) ){}
2469 if (TimeOutLoop > 20000)
2471 WRW_HARPOON((port+hp_intstat), PARITY);
2474 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2476 WRW_HARPOON((port+hp_intstat), PARITY);
2479 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2481 RD_HARPOON(port+hp_scsidata_0);
2483 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2488 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2489 WR_HARPOON(port+hp_xferstat, 0);
2490 WR_HARPOON(port+hp_fiforead, 0);
2491 WR_HARPOON(port+hp_fifowrite, 0);
2496 /*---------------------------------------------------------------------
2498 * Function: FPT_ssel
2500 * Description: Load up automation and select target device.
2502 *---------------------------------------------------------------------*/
2504 static void FPT_ssel(ULONG port, UCHAR p_card)
2507 UCHAR auto_loaded, i, target, *theCCB;
2512 PSCCBMgr_tar_info currTar_Info;
2515 CurrCard = &FPT_BL_Card[p_card];
2516 currSCCB = CurrCard->currentSCCB;
2517 target = currSCCB->TargID;
2518 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2519 lastTag = CurrCard->tagQ_Lst;
2524 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2525 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2527 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2528 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2530 lun = currSCCB->Lun;
2535 if (CurrCard->globalFlags & F_TAG_STARTED)
2537 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2539 if ((currTar_Info->TarLUN_CA == 0)
2540 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2544 if (currTar_Info->TarTagQ_Cnt !=0)
2546 currTar_Info->TarLUNBusy[lun] = 1;
2547 FPT_queueSelectFail(CurrCard,p_card);
2553 currTar_Info->TarLUNBusy[lun] = 1;
2556 } /*End non-tagged */
2559 currTar_Info->TarLUNBusy[lun] = 1;
2562 } /*!Use cmd Q Tagged */
2565 if (currTar_Info->TarLUN_CA == 1)
2567 FPT_queueSelectFail(CurrCard,p_card);
2572 currTar_Info->TarLUNBusy[lun] = 1;
2574 } /*else use cmd Q tagged */
2576 } /*if glob tagged started */
2579 currTar_Info->TarLUNBusy[lun] = 1;
2584 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2585 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2586 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2588 if(CurrCard->discQCount >= QUEUE_DEPTH)
2590 currTar_Info->TarLUNBusy[lun] = 1;
2591 FPT_queueSelectFail(CurrCard,p_card);
2595 for (i = 1; i < QUEUE_DEPTH; i++)
2597 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2598 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2600 CurrCard->tagQ_Lst = lastTag;
2601 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2602 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2603 CurrCard->discQCount++;
2607 if(i == QUEUE_DEPTH)
2609 currTar_Info->TarLUNBusy[lun] = 1;
2610 FPT_queueSelectFail(CurrCard,p_card);
2620 WR_HARPOON(port+hp_select_id, target);
2621 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2623 if (currSCCB->OperationCode == RESET_COMMAND) {
2624 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2625 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2627 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2629 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2631 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2633 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2635 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2637 currTar_Info->TarSyncCtrl = 0;
2638 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2641 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2643 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2646 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2647 FPT_SccbMgrTableInitTarget(p_card, target);
2651 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2653 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2654 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2656 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2658 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2659 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2660 >> 6) | (UCHAR)0x20)));
2661 WRW_HARPOON((port+SYNC_MSGS+2),
2662 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2663 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2665 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2670 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2671 auto_loaded = FPT_siwidn(port,p_card);
2672 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2675 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2676 == SYNC_SUPPORTED)) {
2677 auto_loaded = FPT_sisyncn(port,p_card, 0);
2678 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2685 if (currSCCB->ControlByte & F_USE_CMD_Q)
2688 CurrCard->globalFlags |= F_TAG_STARTED;
2690 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2693 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2695 /* Fix up the start instruction with a jump to
2696 Non-Tag-CMD handling */
2697 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2699 WRW_HARPOON((port+NON_TAG_ID_MSG),
2700 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2702 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2704 /* Setup our STATE so we know what happend when
2705 the wheels fall off. */
2706 currSCCB->Sccb_scsistat = SELECT_ST;
2708 currTar_Info->TarLUNBusy[lun] = 1;
2713 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2715 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2716 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2717 >> 6) | (UCHAR)0x20)));
2719 for (i = 1; i < QUEUE_DEPTH; i++)
2721 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2722 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2724 WRW_HARPOON((port+ID_MSG_STRT+6),
2725 (MPM_OP+AMSG_OUT+lastTag));
2726 CurrCard->tagQ_Lst = lastTag;
2727 currSCCB->Sccb_tag = lastTag;
2728 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2729 CurrCard->discQCount++;
2735 if ( i == QUEUE_DEPTH )
2737 currTar_Info->TarLUNBusy[lun] = 1;
2738 FPT_queueSelectFail(CurrCard,p_card);
2743 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2745 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2752 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2754 WRW_HARPOON((port+NON_TAG_ID_MSG),
2755 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2757 currSCCB->Sccb_scsistat = SELECT_ST;
2759 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2763 theCCB = (UCHAR *)&currSCCB->Cdb[0];
2765 cdb_reg = port + CMD_STRT;
2767 for (i=0; i < currSCCB->CdbLength; i++)
2769 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2774 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2775 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2779 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2780 WR_HARPOON(port+hp_xferstat, 0x00);
2782 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2784 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2787 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2789 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2794 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
2795 auto_loaded |= AUTO_IMMED; */
2796 auto_loaded = AUTO_IMMED;
2800 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2807 /*---------------------------------------------------------------------
2809 * Function: FPT_sres
2811 * Description: Hookup the correct CCB and handle the incoming messages.
2813 *---------------------------------------------------------------------*/
2815 static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
2818 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
2821 PSCCBMgr_tar_info currTar_Info;
2827 if(pCurrCard->currentSCCB != NULL)
2829 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2833 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2836 currSCCB = pCurrCard->currentSCCB;
2837 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2839 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2840 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2842 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2844 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2845 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2847 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2848 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2850 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2851 if(currSCCB->Sccb_scsistat != ABORT_ST)
2853 pCurrCard->discQCount--;
2854 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2860 currTar_Info->TarLUNBusy[0] = 0;
2861 if(currSCCB->Sccb_tag)
2863 if(currSCCB->Sccb_scsistat != ABORT_ST)
2865 pCurrCard->discQCount--;
2866 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2870 if(currSCCB->Sccb_scsistat != ABORT_ST)
2872 pCurrCard->discQCount--;
2873 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2878 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2881 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2884 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
2885 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2892 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2896 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2898 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2901 WRW_HARPOON((port+hp_intstat), PHASE);
2906 WRW_HARPOON((port+hp_intstat), PHASE);
2907 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2910 message = FPT_sfm(port,pCurrCard->currentSCCB);
2914 if (message <= (0x80 | LUN_MASK))
2916 lun = message & (UCHAR)LUN_MASK;
2918 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2920 if (currTar_Info->TarTagQ_Cnt != 0)
2923 if (!(currTar_Info->TarLUN_CA))
2925 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2928 message = FPT_sfm(port,pCurrCard->currentSCCB);
2939 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2947 } /*End Q cnt != 0 */
2949 } /*End Tag cmds supported! */
2951 } /*End valid ID message. */
2956 ACCEPT_MSG_ATN(port);
2959 } /* End good id message. */
2969 ACCEPT_MSG_ATN(port);
2971 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2972 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2973 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2981 if(msgRetryCount == 1)
2983 FPT_SendMsg(port, SMPARITY);
2987 FPT_SendMsg(port, SMDEV_RESET);
2989 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2991 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2994 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2998 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
3001 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
3005 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3006 FPT_SccbMgrTableInitTarget(p_card,our_target);
3010 }while(message == 0);
3014 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3015 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3017 currTar_Info->TarLUNBusy[lun] = 1;
3018 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3019 if(pCurrCard->currentSCCB != NULL)
3025 ACCEPT_MSG_ATN(port);
3030 currTar_Info->TarLUNBusy[0] = 1;
3035 if (pCurrCard->discQ_Tbl[tag] != NULL)
3037 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3038 currTar_Info->TarTagQ_Cnt--;
3043 ACCEPT_MSG_ATN(port);
3047 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3048 if(pCurrCard->currentSCCB != NULL)
3054 ACCEPT_MSG_ATN(port);
3059 if(pCurrCard->currentSCCB != NULL)
3061 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3063 /* During Abort Tag command, the target could have got re-selected
3064 and completed the command. Check the select Q and remove the CCB
3065 if it is in the Select Q */
3066 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3071 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3072 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3073 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3076 static void FPT_SendMsg(ULONG port, UCHAR message)
3078 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3080 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3083 WRW_HARPOON((port+hp_intstat), PHASE);
3088 WRW_HARPOON((port+hp_intstat), PHASE);
3089 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3091 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3094 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3096 WR_HARPOON(port+hp_scsidata_0,message);
3098 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3102 WR_HARPOON(port+hp_portctrl_0, 0x00);
3104 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3105 (message == SMABORT_TAG) )
3107 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3109 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3111 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3117 /*---------------------------------------------------------------------
3119 * Function: FPT_sdecm
3121 * Description: Determine the proper responce to the message from the
3124 *---------------------------------------------------------------------*/
3125 static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
3129 PSCCBMgr_tar_info currTar_Info;
3131 CurrCard = &FPT_BL_Card[p_card];
3132 currSCCB = CurrCard->currentSCCB;
3134 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3136 if (message == SMREST_DATA_PTR)
3138 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3140 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3142 FPT_hostDataXferRestart(currSCCB);
3146 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3149 else if (message == SMCMD_COMP)
3153 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3155 currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
3156 currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
3163 else if ((message == SMNO_OP) || (message >= SMIDENT)
3164 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3168 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3171 else if (message == SMREJECT)
3174 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3175 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3176 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3177 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3180 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3185 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3186 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3188 if(currSCCB->Lun == 0x00)
3190 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3193 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3195 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3198 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3202 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3203 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3205 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3209 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3211 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3212 ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3215 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3216 CurrCard->discQCount--;
3217 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3218 currSCCB->Sccb_tag = 0x00;
3223 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3227 if(currSCCB->Lun == 0x00)
3229 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3230 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3237 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3238 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3239 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3241 currTar_Info->TarLUNBusy[0] = 1;
3244 currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
3246 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3255 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3256 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3258 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3260 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3265 else if (message == SMEXT)
3269 FPT_shandem(port,p_card,currSCCB);
3272 else if (message == SMIGNORWR)
3275 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3277 message = FPT_sfm(port,currSCCB);
3279 if(currSCCB->Sccb_scsimsg != SMPARITY)
3281 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3288 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3289 currSCCB->Sccb_scsimsg = SMREJECT;
3291 ACCEPT_MSG_ATN(port);
3292 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3297 /*---------------------------------------------------------------------
3299 * Function: FPT_shandem
3301 * Description: Decide what to do with the extended message.
3303 *---------------------------------------------------------------------*/
3304 static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
3306 UCHAR length,message;
3308 length = FPT_sfm(port,pCurrSCCB);
3313 message = FPT_sfm(port,pCurrSCCB);
3317 if (message == SMSYNC)
3324 FPT_stsyncn(port,p_card);
3329 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3330 ACCEPT_MSG_ATN(port);
3333 else if (message == SMWDTR)
3340 FPT_stwidn(port,p_card);
3345 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3346 ACCEPT_MSG_ATN(port);
3348 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3354 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3355 ACCEPT_MSG_ATN(port);
3357 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3362 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3364 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3368 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3369 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3374 /*---------------------------------------------------------------------
3376 * Function: FPT_sisyncn
3378 * Description: Read in a message byte from the SCSI bus, and check
3379 * for a parity error.
3381 *---------------------------------------------------------------------*/
3383 static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
3386 PSCCBMgr_tar_info currTar_Info;
3388 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3389 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3391 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3394 WRW_HARPOON((port+ID_MSG_STRT),
3395 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3397 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3399 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3400 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3401 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3404 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3406 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3408 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3410 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3412 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3414 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3417 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3420 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3421 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3422 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3427 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3428 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3429 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
3433 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3442 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3443 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3450 /*---------------------------------------------------------------------
3452 * Function: FPT_stsyncn
3454 * Description: The has sent us a Sync Nego message so handle it as
3457 *---------------------------------------------------------------------*/
3458 static void FPT_stsyncn(ULONG port, UCHAR p_card)
3460 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
3462 PSCCBMgr_tar_info currTar_Info;
3464 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3465 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3467 sync_msg = FPT_sfm(port,currSCCB);
3469 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3471 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3478 offset = FPT_sfm(port,currSCCB);
3480 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3482 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3486 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3488 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3490 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3492 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3494 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3496 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3499 our_sync_msg = 0; /* Message = Async */
3501 if (sync_msg < our_sync_msg) {
3502 sync_msg = our_sync_msg; /*if faster, then set to max. */
3505 if (offset == ASYNC)
3508 if (offset > MAX_OFFSET)
3509 offset = MAX_OFFSET;
3515 sync_reg = 0x20; /* Use 10MB/s */
3519 sync_reg = 0x40; /* Use 6.6MB/s */
3523 sync_reg = 0x60; /* Use 5MB/s */
3527 sync_reg = 0x80; /* Use 4MB/s */
3531 sync_reg = 0xA0; /* Use 3.33MB/s */
3535 sync_reg = 0xC0; /* Use 2.85MB/s */
3539 sync_reg = 0xE0; /* Use 2.5MB/s */
3541 if (sync_msg > 100) {
3543 sync_reg = 0x00; /* Use ASYNC */
3548 if (currTar_Info->TarStatus & WIDE_ENABLED)
3554 sync_reg |= (offset | NARROW_SCSI);
3556 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3559 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3564 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3565 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3567 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3573 ACCEPT_MSG_ATN(port);
3575 FPT_sisyncr(port,sync_msg,offset);
3577 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3578 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3583 /*---------------------------------------------------------------------
3585 * Function: FPT_sisyncr
3587 * Description: Answer the targets sync message.
3589 *---------------------------------------------------------------------*/
3590 static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
3593 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3594 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3595 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3596 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3597 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3598 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3599 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3602 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3603 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3605 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3607 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3612 /*---------------------------------------------------------------------
3614 * Function: FPT_siwidn
3616 * Description: Read in a message byte from the SCSI bus, and check
3617 * for a parity error.
3619 *---------------------------------------------------------------------*/
3621 static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
3624 PSCCBMgr_tar_info currTar_Info;
3626 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3627 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3629 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3632 WRW_HARPOON((port+ID_MSG_STRT),
3633 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3635 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3637 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3638 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3639 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3640 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3641 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3642 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3644 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3647 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3648 ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
3655 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3656 ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3658 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3665 /*---------------------------------------------------------------------
3667 * Function: FPT_stwidn
3669 * Description: The has sent us a Wide Nego message so handle it as
3672 *---------------------------------------------------------------------*/
3673 static void FPT_stwidn(ULONG port, UCHAR p_card)
3677 PSCCBMgr_tar_info currTar_Info;
3679 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3680 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3682 width = FPT_sfm(port,currSCCB);
3684 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3686 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3691 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3695 currTar_Info->TarStatus |= WIDE_ENABLED;
3699 width = NARROW_SCSI;
3700 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3704 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3707 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3712 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3714 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3716 ACCEPT_MSG_ATN(port);
3718 FPT_sisyncn(port,p_card, 1);
3719 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3725 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3732 ACCEPT_MSG_ATN(port);
3734 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3739 FPT_siwidr(port,width);
3741 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3746 /*---------------------------------------------------------------------
3748 * Function: FPT_siwidr
3750 * Description: Answer the targets Wide nego message.
3752 *---------------------------------------------------------------------*/
3753 static void FPT_siwidr(ULONG port, UCHAR width)
3756 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3757 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3758 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3759 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3760 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3761 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3764 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3765 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3767 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3769 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3774 /*---------------------------------------------------------------------
3776 * Function: FPT_sssyncv
3778 * Description: Write the desired value to the Sync Register for the
3781 *---------------------------------------------------------------------*/
3782 static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
3783 PSCCBMgr_tar_info currTar_Info)
3792 index = 12; /* hp_synctarg_0 */
3795 index = 13; /* hp_synctarg_1 */
3798 index = 14; /* hp_synctarg_2 */
3801 index = 15; /* hp_synctarg_3 */
3804 index = 8; /* hp_synctarg_4 */
3807 index = 9; /* hp_synctarg_5 */
3810 index = 10; /* hp_synctarg_6 */
3813 index = 11; /* hp_synctarg_7 */
3816 index = 4; /* hp_synctarg_8 */
3819 index = 5; /* hp_synctarg_9 */
3822 index = 6; /* hp_synctarg_10 */
3825 index = 7; /* hp_synctarg_11 */
3828 index = 0; /* hp_synctarg_12 */
3831 index = 1; /* hp_synctarg_13 */
3834 index = 2; /* hp_synctarg_14 */
3837 index = 3; /* hp_synctarg_15 */
3841 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3843 currTar_Info->TarSyncCtrl = p_sync_value;
3847 /*---------------------------------------------------------------------
3849 * Function: FPT_sresb
3851 * Description: Reset the desired card's SCSI bus.
3853 *---------------------------------------------------------------------*/
3854 static void FPT_sresb(ULONG port, UCHAR p_card)
3858 PSCCBMgr_tar_info currTar_Info;
3860 WR_HARPOON(port+hp_page_ctrl,
3861 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3862 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3864 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3866 scsiID = RD_HARPOON(port+hp_seltimeout);
3867 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3868 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3870 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3872 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3874 WR_HARPOON(port+hp_seltimeout,scsiID);
3876 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3878 FPT_Wait(port, TO_5ms);
3880 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3882 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3884 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3886 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3888 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3890 currTar_Info->TarSyncCtrl = 0;
3891 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3894 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3896 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3899 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3901 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3904 FPT_BL_Card[p_card].scanIndex = 0x00;
3905 FPT_BL_Card[p_card].currentSCCB = NULL;
3906 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3908 FPT_BL_Card[p_card].cmdCounter = 0x00;
3909 FPT_BL_Card[p_card].discQCount = 0x00;
3910 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3912 for(i = 0; i < QUEUE_DEPTH; i++)
3913 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3915 WR_HARPOON(port+hp_page_ctrl,
3916 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3920 /*---------------------------------------------------------------------
3922 * Function: FPT_ssenss
3924 * Description: Setup for the Auto Sense command.
3926 *---------------------------------------------------------------------*/
3927 static void FPT_ssenss(PSCCBcard pCurrCard)
3932 currSCCB = pCurrCard->currentSCCB;
3935 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3937 for (i = 0; i < 6; i++) {
3939 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3942 currSCCB->CdbLength = SIX_BYTE_CMD;
3943 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3944 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
3945 currSCCB->Cdb[2] = 0x00;
3946 currSCCB->Cdb[3] = 0x00;
3947 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3948 currSCCB->Cdb[5] = 0x00;
3950 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3952 currSCCB->Sccb_ATC = 0x00;
3954 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3956 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3958 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
3960 currSCCB->ControlByte = 0x00;
3962 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3967 /*---------------------------------------------------------------------
3969 * Function: FPT_sxfrp
3971 * Description: Transfer data into the bit bucket until the device
3972 * decides to switch phase.
3974 *---------------------------------------------------------------------*/
3976 static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
3981 DISABLE_AUTO(p_port);
3983 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3985 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3989 /* If the Automation handled the end of the transfer then do not
3990 match the phase or we will get out of sync with the ISR. */
3992 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3995 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3997 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
3999 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4002 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4004 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4005 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
4007 if (curr_phz & (UCHAR)SCSI_IOBIT)
4009 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4011 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4013 RD_HARPOON(p_port+hp_fifodata_0);
4018 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4019 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4021 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4024 } /* End of While loop for padding data I/O phase */
4026 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4028 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4032 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4033 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4035 RD_HARPOON(p_port+hp_fifodata_0);
4038 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4040 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4041 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4043 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4044 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4049 /*---------------------------------------------------------------------
4051 * Function: FPT_schkdd
4053 * Description: Make sure data has been flushed from both FIFOs and abort
4054 * the operations if necessary.
4056 *---------------------------------------------------------------------*/
4058 static void FPT_schkdd(ULONG port, UCHAR p_card)
4065 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4068 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4069 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4075 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4078 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4080 currSCCB->Sccb_XferCnt = 1;
4082 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4083 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4084 WR_HARPOON(port+hp_xferstat, 0x00);
4090 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4092 currSCCB->Sccb_XferCnt = 0;
4095 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4096 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4098 currSCCB->HostStatus = SCCB_PARITY_ERR;
4099 WRW_HARPOON((port+hp_intstat), PARITY);
4103 FPT_hostDataXferAbort(port,p_card,currSCCB);
4106 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4110 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4112 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4115 if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
4118 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4121 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4125 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4126 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4127 (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) ||
4128 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4129 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4132 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4134 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4136 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4137 FPT_phaseDataIn(port,p_card);
4141 FPT_phaseDataOut(port,p_card);
4146 FPT_sxfrp(port,p_card);
4147 if (!(RDW_HARPOON((port+hp_intstat)) &
4148 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4150 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4151 FPT_phaseDecode(port,p_card);
4158 WR_HARPOON(port+hp_portctrl_0, 0x00);
4163 /*---------------------------------------------------------------------
4165 * Function: FPT_sinits
4167 * Description: Setup SCCB manager fields in this SCCB.
4169 *---------------------------------------------------------------------*/
4171 static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
4173 PSCCBMgr_tar_info currTar_Info;
4175 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4179 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4181 p_sccb->Sccb_XferState = 0x00;
4182 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4184 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4185 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4187 p_sccb->Sccb_SGoffset = 0;
4188 p_sccb->Sccb_XferState = F_SG_XFER;
4189 p_sccb->Sccb_XferCnt = 0x00;
4192 if (p_sccb->DataLength == 0x00)
4194 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4196 if (p_sccb->ControlByte & F_USE_CMD_Q)
4198 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4199 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4202 currTar_Info->TarStatus |= TAG_Q_TRYING;
4205 /* For !single SCSI device in system & device allow Disconnect
4206 or command is tag_q type then send Cmd with Disconnect Enable
4207 else send Cmd with Disconnect Disable */
4210 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4211 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4212 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4214 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4215 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4216 p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4221 p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun;
4224 p_sccb->HostStatus = 0x00;
4225 p_sccb->TargetStatus = 0x00;
4226 p_sccb->Sccb_tag = 0x00;
4227 p_sccb->Sccb_MGRFlags = 0x00;
4228 p_sccb->Sccb_sgseg = 0x00;
4229 p_sccb->Sccb_ATC = 0x00;
4230 p_sccb->Sccb_savedATC = 0x00;
4232 p_sccb->SccbVirtDataPtr = 0x00;
4233 p_sccb->Sccb_forwardlink = NULL;
4234 p_sccb->Sccb_backlink = NULL;
4236 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4237 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4238 p_sccb->Sccb_scsimsg = SMNO_OP;
4243 /*---------------------------------------------------------------------
4245 * Function: Phase Decode
4247 * Description: Determine the phase and call the appropriate function.
4249 *---------------------------------------------------------------------*/
4251 static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
4253 unsigned char phase_ref;
4254 void (*phase) (ULONG, UCHAR);
4257 DISABLE_AUTO(p_port);
4259 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4261 phase = FPT_s_PhaseTbl[phase_ref];
4263 (*phase)(p_port, p_card); /* Call the correct phase func */
4268 /*---------------------------------------------------------------------
4270 * Function: Data Out Phase
4272 * Description: Start up both the BusMaster and Xbow.
4274 *---------------------------------------------------------------------*/
4276 static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
4281 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4282 if (currSCCB == NULL)
4284 return; /* Exit if No SCCB record */
4287 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4288 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4290 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4292 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4294 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4296 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4298 if (currSCCB->Sccb_XferCnt == 0) {
4301 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4302 (currSCCB->HostStatus == SCCB_COMPLETE))
4303 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4305 FPT_sxfrp(port,p_card);
4306 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4307 FPT_phaseDecode(port,p_card);
4312 /*---------------------------------------------------------------------
4314 * Function: Data In Phase
4316 * Description: Startup the BusMaster and the XBOW.
4318 *---------------------------------------------------------------------*/
4320 static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
4325 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4327 if (currSCCB == NULL)
4329 return; /* Exit if No SCCB record */
4333 currSCCB->Sccb_scsistat = DATA_IN_ST;
4334 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4335 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4337 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4339 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4341 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4343 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4345 if (currSCCB->Sccb_XferCnt == 0) {
4348 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4349 (currSCCB->HostStatus == SCCB_COMPLETE))
4350 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4352 FPT_sxfrp(port,p_card);
4353 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4354 FPT_phaseDecode(port,p_card);
4359 /*---------------------------------------------------------------------
4361 * Function: Command Phase
4363 * Description: Load the CDB into the automation and start it up.
4365 *---------------------------------------------------------------------*/
4367 static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
4373 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4375 if (currSCCB->OperationCode == RESET_COMMAND) {
4377 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4378 currSCCB->CdbLength = SIX_BYTE_CMD;
4381 WR_HARPOON(p_port+hp_scsisig, 0x00);
4383 ARAM_ACCESS(p_port);
4386 cdb_reg = p_port + CMD_STRT;
4388 for (i=0; i < currSCCB->CdbLength; i++) {
4390 if (currSCCB->OperationCode == RESET_COMMAND)
4392 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4395 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4399 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4400 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4402 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4404 currSCCB->Sccb_scsistat = COMMAND_ST;
4406 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4407 SGRAM_ACCESS(p_port);
4411 /*---------------------------------------------------------------------
4413 * Function: Status phase
4415 * Description: Bring in the status and command complete message bytes
4417 *---------------------------------------------------------------------*/
4419 static void FPT_phaseStatus(ULONG port, UCHAR p_card)
4421 /* Start-up the automation to finish off this command and let the
4422 isr handle the interrupt for command complete when it comes in.
4423 We could wait here for the interrupt to be generated?
4426 WR_HARPOON(port+hp_scsisig, 0x00);
4428 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4432 /*---------------------------------------------------------------------
4434 * Function: Phase Message Out
4436 * Description: Send out our message (if we have one) and handle whatever
4439 *---------------------------------------------------------------------*/
4441 static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
4443 UCHAR message,scsiID;
4445 PSCCBMgr_tar_info currTar_Info;
4447 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4449 if (currSCCB != NULL) {
4451 message = currSCCB->Sccb_scsimsg;
4452 scsiID = currSCCB->TargID;
4454 if (message == SMDEV_RESET)
4458 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4459 currTar_Info->TarSyncCtrl = 0;
4460 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4462 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4465 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4469 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4472 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4476 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4477 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4479 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4481 currSCCB->HostStatus = SCCB_COMPLETE;
4482 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4484 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4485 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4490 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4494 if(message == SMNO_OP)
4496 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4498 FPT_ssel(port,p_card);
4506 if (message == SMABORT)
4508 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4517 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4520 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4522 WR_HARPOON(port+hp_scsidata_0,message);
4524 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4528 WR_HARPOON(port+hp_portctrl_0, 0x00);
4530 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4531 (message == SMABORT_TAG) )
4534 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4536 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4538 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4540 if (currSCCB != NULL)
4543 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4544 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4545 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4547 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4549 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4554 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4561 FPT_sxfrp(port,p_card);
4568 if(message == SMPARITY)
4570 currSCCB->Sccb_scsimsg = SMNO_OP;
4571 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4575 FPT_sxfrp(port,p_card);
4581 /*---------------------------------------------------------------------
4583 * Function: Message In phase
4585 * Description: Bring in the message and determine what to do with it.
4587 *---------------------------------------------------------------------*/
4589 static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
4594 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4596 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4599 FPT_phaseChkFifo(port, p_card);
4602 message = RD_HARPOON(port+hp_scsidata_0);
4603 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4606 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4613 message = FPT_sfm(port,currSCCB);
4618 FPT_sdecm(message,port,p_card);
4623 if(currSCCB->Sccb_scsimsg != SMPARITY)
4625 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4632 /*---------------------------------------------------------------------
4634 * Function: Illegal phase
4636 * Description: Target switched to some illegal phase, so all we can do
4637 * is report an error back to the host (if that is possible)
4638 * and send an ABORT message to the misbehaving target.
4640 *---------------------------------------------------------------------*/
4642 static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
4646 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4648 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4649 if (currSCCB != NULL) {
4651 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4652 currSCCB->Sccb_scsistat = ABORT_ST;
4653 currSCCB->Sccb_scsimsg = SMABORT;
4656 ACCEPT_MSG_ATN(port);
4661 /*---------------------------------------------------------------------
4663 * Function: Phase Check FIFO
4665 * Description: Make sure data has been flushed from both FIFOs and abort
4666 * the operations if necessary.
4668 *---------------------------------------------------------------------*/
4670 static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
4675 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4677 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4680 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4681 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4684 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4686 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4688 currSCCB->Sccb_XferCnt = 0;
4690 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4691 (currSCCB->HostStatus == SCCB_COMPLETE))
4693 currSCCB->HostStatus = SCCB_PARITY_ERR;
4694 WRW_HARPOON((port+hp_intstat), PARITY);
4697 FPT_hostDataXferAbort(port,p_card,currSCCB);
4699 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4701 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4702 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4705 } /*End Data In specific code. */
4709 GET_XFER_CNT(port,xfercnt);
4712 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4715 WR_HARPOON(port+hp_portctrl_0, 0x00);
4717 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4719 currSCCB->Sccb_XferCnt = xfercnt;
4721 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4722 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4724 currSCCB->HostStatus = SCCB_PARITY_ERR;
4725 WRW_HARPOON((port+hp_intstat), PARITY);
4729 FPT_hostDataXferAbort(port,p_card,currSCCB);
4732 WR_HARPOON(port+hp_fifowrite, 0x00);
4733 WR_HARPOON(port+hp_fiforead, 0x00);
4734 WR_HARPOON(port+hp_xferstat, 0x00);
4736 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4740 /*---------------------------------------------------------------------
4742 * Function: Phase Bus Free
4744 * Description: We just went bus free so figure out if it was
4745 * because of command complete or from a disconnect.
4747 *---------------------------------------------------------------------*/
4748 static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
4752 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4754 if (currSCCB != NULL)
4760 if (currSCCB->OperationCode == RESET_COMMAND)
4763 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4764 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4767 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4769 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4771 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4775 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4777 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4778 (UCHAR)SYNC_SUPPORTED;
4779 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4782 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4785 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4786 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4788 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4791 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4793 /* Make sure this is not a phony BUS_FREE. If we were
4794 reselected or if BUSY is NOT on then this is a
4795 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4797 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4798 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4801 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4813 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4815 if (!currSCCB->HostStatus)
4817 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4820 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4821 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4822 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4824 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4826 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4831 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4833 } /*end if !=null */
4839 /*---------------------------------------------------------------------
4841 * Function: Auto Load Default Map
4843 * Description: Load the Automation RAM with the defualt map values.
4845 *---------------------------------------------------------------------*/
4846 static void FPT_autoLoadDefaultMap(ULONG p_port)
4850 ARAM_ACCESS(p_port);
4851 map_addr = p_port + hp_aramBase;
4853 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4855 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4857 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4859 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4873 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4875 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4881 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4883 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4885 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4887 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4888 map_addr +=2; /*This means AYNC DATA IN */
4889 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4891 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4893 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4895 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4897 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4899 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4901 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4903 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4905 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4907 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4909 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4911 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4913 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4915 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4917 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4919 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4921 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4928 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4930 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4932 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4933 map_addr +=2; /* DIDN'T GET ONE */
4934 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4936 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4938 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4942 SGRAM_ACCESS(p_port);
4945 /*---------------------------------------------------------------------
4947 * Function: Auto Command Complete
4949 * Description: Post command back to host and find another command
4952 *---------------------------------------------------------------------*/
4954 static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
4959 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4961 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4963 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4965 if (status_byte != SSGOOD) {
4967 if (status_byte == SSQ_FULL) {
4970 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4971 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4973 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4974 if(FPT_BL_Card[p_card].discQCount != 0)
4975 FPT_BL_Card[p_card].discQCount--;
4976 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4980 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4981 if(currSCCB->Sccb_tag)
4983 if(FPT_BL_Card[p_card].discQCount != 0)
4984 FPT_BL_Card[p_card].discQCount--;
4985 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4988 if(FPT_BL_Card[p_card].discQCount != 0)
4989 FPT_BL_Card[p_card].discQCount--;
4990 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4994 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4996 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
5001 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
5004 (UCHAR)SYNC_SUPPORTED;
5006 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5007 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5009 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5010 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5012 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5013 if(FPT_BL_Card[p_card].discQCount != 0)
5014 FPT_BL_Card[p_card].discQCount--;
5015 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5019 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5020 if(currSCCB->Sccb_tag)
5022 if(FPT_BL_Card[p_card].discQCount != 0)
5023 FPT_BL_Card[p_card].discQCount--;
5024 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5027 if(FPT_BL_Card[p_card].discQCount != 0)
5028 FPT_BL_Card[p_card].discQCount--;
5029 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5036 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5039 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5040 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5041 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5043 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5044 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5046 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5047 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5049 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5050 if(FPT_BL_Card[p_card].discQCount != 0)
5051 FPT_BL_Card[p_card].discQCount--;
5052 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5056 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5057 if(currSCCB->Sccb_tag)
5059 if(FPT_BL_Card[p_card].discQCount != 0)
5060 FPT_BL_Card[p_card].discQCount--;
5061 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5064 if(FPT_BL_Card[p_card].discQCount != 0)
5065 FPT_BL_Card[p_card].discQCount--;
5066 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5073 if (status_byte == SSCHECK)
5075 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5077 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5079 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5081 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5083 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5088 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5090 currSCCB->SccbStatus = SCCB_ERROR;
5091 currSCCB->TargetStatus = status_byte;
5093 if (status_byte == SSCHECK) {
5095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5099 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5101 if (currSCCB->RequestSenseLength == 0)
5102 currSCCB->RequestSenseLength = 14;
5104 FPT_ssenss(&FPT_BL_Card[p_card]);
5105 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5107 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5108 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5110 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5111 if(FPT_BL_Card[p_card].discQCount != 0)
5112 FPT_BL_Card[p_card].discQCount--;
5113 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5117 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5118 if(currSCCB->Sccb_tag)
5120 if(FPT_BL_Card[p_card].discQCount != 0)
5121 FPT_BL_Card[p_card].discQCount--;
5122 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5125 if(FPT_BL_Card[p_card].discQCount != 0)
5126 FPT_BL_Card[p_card].discQCount--;
5127 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5137 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5138 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5139 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5141 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5144 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5147 #define SHORT_WAIT 0x0000000F
5148 #define LONG_WAIT 0x0000FFFFL
5151 /*---------------------------------------------------------------------
5153 * Function: Data Transfer Processor
5155 * Description: This routine performs two tasks.
5156 * (1) Start data transfer by calling HOST_DATA_XFER_START
5157 * function. Once data transfer is started, (2) Depends
5158 * on the type of data transfer mode Scatter/Gather mode
5159 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5160 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5161 * data transfer done. In Scatter/Gather mode, this routine
5162 * checks bus master command complete and dual rank busy
5163 * bit to keep chaining SC transfer command. Similarly,
5164 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5165 * (F_HOST_XFER_ACT bit) for data transfer done.
5167 *---------------------------------------------------------------------*/
5169 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
5173 currSCCB = pCurrCard->currentSCCB;
5175 if (currSCCB->Sccb_XferState & F_SG_XFER)
5177 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5180 currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
5181 currSCCB->Sccb_SGoffset = 0x00;
5183 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5185 FPT_busMstrSGDataXferStart(port, currSCCB);
5190 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5192 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5194 FPT_busMstrDataXferStart(port, currSCCB);
5200 /*---------------------------------------------------------------------
5202 * Function: BusMaster Scatter Gather Data Transfer Start
5206 *---------------------------------------------------------------------*/
5207 static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5209 ULONG count,addr,tmpSGCnt;
5215 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5217 count = ((ULONG) HOST_RD_CMD)<<24;
5221 count = ((ULONG) HOST_WRT_CMD)<<24;
5226 sg_index = pcurrSCCB->Sccb_sgseg;
5227 reg_offset = hp_aramBase;
5230 i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5233 WR_HARPOON(p_port+hp_page_ctrl, i);
5235 while ((sg_count < (UCHAR)SG_BUF_CNT) &&
5236 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5238 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5241 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5244 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5245 ((sg_index * 2) + 1));
5248 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5250 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5251 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5253 tmpSGCnt = count & 0x00FFFFFFL;
5256 WR_HARP32(p_port,reg_offset,addr);
5259 WR_HARP32(p_port,reg_offset,count);
5262 count &= 0xFF000000L;
5268 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5270 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5272 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5274 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5277 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5278 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5284 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5285 (tmpSGCnt & 0x000000001))
5288 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5293 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5295 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5296 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5300 WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
5305 /*---------------------------------------------------------------------
5307 * Function: BusMaster Data Transfer Start
5311 *---------------------------------------------------------------------*/
5312 static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5316 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5318 count = pcurrSCCB->Sccb_XferCnt;
5320 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5324 addr = pcurrSCCB->SensePointer;
5325 count = pcurrSCCB->RequestSenseLength;
5329 HP_SETUP_ADDR_CNT(p_port,addr,count);
5332 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5334 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5335 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5337 WR_HARPOON(p_port+hp_xfer_cmd,
5338 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5343 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5344 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5346 WR_HARPOON(p_port+hp_xfer_cmd,
5347 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5353 /*---------------------------------------------------------------------
5355 * Function: BusMaster Timeout Handler
5357 * Description: This function is called after a bus master command busy time
5358 * out is detected. This routines issue halt state machine
5359 * with a software time out for command busy. If command busy
5360 * is still asserted at the end of the time out, it issues
5361 * hard abort with another software time out. It hard abort
5362 * command busy is also time out, it'll just give up.
5364 *---------------------------------------------------------------------*/
5365 static UCHAR FPT_busMstrTimeOut(ULONG p_port)
5369 timeout = LONG_WAIT;
5371 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5373 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5377 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5378 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5380 timeout = LONG_WAIT;
5381 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5384 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5386 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5396 /*---------------------------------------------------------------------
5398 * Function: Host Data Transfer Abort
5400 * Description: Abort any in progress transfer.
5402 *---------------------------------------------------------------------*/
5403 static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
5410 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5412 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5415 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5417 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5418 timeout = LONG_WAIT;
5420 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5422 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5424 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5426 if (FPT_busMstrTimeOut(port)) {
5428 if (pCurrSCCB->HostStatus == 0x00)
5430 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5434 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5436 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5438 if (pCurrSCCB->HostStatus == 0x00)
5441 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5447 else if (pCurrSCCB->Sccb_XferCnt) {
5449 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5452 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5455 WR_HARPOON(port+hp_sg_addr,0x00);
5457 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5459 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5461 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5464 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5466 while (remain_cnt < 0x01000000L) {
5470 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5471 DataPointer) + (sg_ptr * 2)))) {
5473 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5474 DataPointer) + (sg_ptr * 2)));
5485 if (remain_cnt < 0x01000000L) {
5488 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5490 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5493 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5494 && (remain_cnt == 0))
5496 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5502 if (pCurrSCCB->HostStatus == 0x00) {
5504 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5510 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5513 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5515 FPT_busMstrTimeOut(port);
5520 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5522 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5524 if (pCurrSCCB->HostStatus == 0x00) {
5526 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5537 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5539 timeout = SHORT_WAIT;
5541 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5542 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5546 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5548 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5551 timeout = LONG_WAIT;
5553 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5556 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5560 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5562 if (pCurrSCCB->HostStatus == 0x00) {
5564 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5567 FPT_busMstrTimeOut(port);
5571 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5573 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5575 if (pCurrSCCB->HostStatus == 0x00) {
5577 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5588 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5590 timeout = LONG_WAIT;
5592 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5594 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5596 if (pCurrSCCB->HostStatus == 0x00) {
5598 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5601 FPT_busMstrTimeOut(port);
5606 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5608 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5610 if (pCurrSCCB->HostStatus == 0x00) {
5612 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5618 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5620 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5623 WR_HARPOON(port+hp_sg_addr,0x00);
5625 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5627 pCurrSCCB->Sccb_SGoffset = 0x00;
5630 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5631 pCurrSCCB->DataLength) {
5633 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5635 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5642 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5644 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5648 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5653 /*---------------------------------------------------------------------
5655 * Function: Host Data Transfer Restart
5657 * Description: Reset the available count due to a restore data
5660 *---------------------------------------------------------------------*/
5661 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5667 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5669 currSCCB->Sccb_XferCnt = 0;
5671 sg_index = 0xffff; /*Index by long words into sg list. */
5672 data_count = 0; /*Running count of SG xfer counts. */
5674 sg_ptr = (ULONG *)currSCCB->DataPointer;
5676 while (data_count < currSCCB->Sccb_ATC) {
5679 data_count += *(sg_ptr+(sg_index * 2));
5682 if (data_count == currSCCB->Sccb_ATC) {
5684 currSCCB->Sccb_SGoffset = 0;
5689 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5692 currSCCB->Sccb_sgseg = (USHORT)sg_index;
5696 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5702 /*---------------------------------------------------------------------
5704 * Function: FPT_scini
5706 * Description: Setup all data structures necessary for SCAM selection.
5708 *---------------------------------------------------------------------*/
5710 static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
5713 UCHAR loser,assigned_id;
5718 PNVRamInfo pCurrNvRam;
5720 currCard = &FPT_BL_Card[p_card];
5721 p_port = currCard->ioPort;
5722 pCurrNvRam = currCard->pNvRamInfo;
5726 ScamFlg = pCurrNvRam->niScamConf;
5727 i = pCurrNvRam->niSysConf;
5730 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5731 i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5733 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5736 FPT_inisci(p_card,p_port, p_our_id);
5738 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5739 too slow to return to SCAM selection */
5742 FPT_Wait1Second(p_port);
5744 FPT_Wait(p_port, TO_250ms); */
5746 FPT_Wait1Second(p_port);
5748 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5750 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5755 FPT_scxferc(p_port,SYNC_PTRN);
5756 FPT_scxferc(p_port,DOM_MSTR);
5757 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5758 } while ( loser == 0xFF );
5762 if ((p_power_up) && (!loser))
5764 FPT_sresb(p_port,p_card);
5765 FPT_Wait(p_port, TO_250ms);
5767 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5772 FPT_scxferc(p_port, SYNC_PTRN);
5773 FPT_scxferc(p_port, DOM_MSTR);
5774 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5776 } while ( loser == 0xFF );
5791 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5794 if (ScamFlg & SCAM_ENABLED)
5797 for (i=0; i < MAX_SCSI_TAR; i++)
5799 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5800 (FPT_scamInfo[i].state == ID_UNUSED))
5802 if (FPT_scsell(p_port,i))
5804 FPT_scamInfo[i].state = LEGACY;
5805 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5806 (FPT_scamInfo[i].id_string[1] != 0xFA))
5809 FPT_scamInfo[i].id_string[0] = 0xFF;
5810 FPT_scamInfo[i].id_string[1] = 0xFA;
5811 if(pCurrNvRam == NULL)
5812 currCard->globalFlags |= F_UPDATE_EEPROM;
5818 FPT_sresb(p_port,p_card);
5819 FPT_Wait1Second(p_port);
5820 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5822 FPT_scasid(p_card, p_port);
5827 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5829 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5831 FPT_scwtsel(p_port);
5834 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5836 i = FPT_scxferc(p_port,0x00);
5839 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5841 i = FPT_scxferc(p_port,0x00);
5844 k = FPT_scxferc(p_port,0x00);
5849 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
5850 FPT_inisci(p_card, p_port, p_our_id);
5851 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5852 FPT_scamInfo[currCard->ourId].id_string[0]
5860 else if (i == SET_P_FLAG)
5862 if (!(FPT_scsendi(p_port,
5863 &FPT_scamInfo[p_our_id].id_string[0])))
5864 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5866 }while (!assigned_id);
5868 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5871 if (ScamFlg & SCAM_ENABLED)
5874 if (currCard->globalFlags & F_UPDATE_EEPROM)
5876 FPT_scsavdi(p_card, p_port);
5877 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5883 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5885 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5886 (FPT_scamInfo[i].state == LEGACY))
5891 currCard->globalFlags |= F_SINGLE_DEVICE;
5893 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5898 /*---------------------------------------------------------------------
5900 * Function: FPT_scarb
5902 * Description: Gain control of the bus and wait SCAM select time (250ms)
5904 *---------------------------------------------------------------------*/
5906 static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
5908 if (p_sel_type == INIT_SELTD)
5911 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5914 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5917 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5920 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5922 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5924 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5930 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5932 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5934 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5935 ~(SCSI_BSY | SCSI_SEL)));
5941 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5943 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5944 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5945 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5946 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5948 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5950 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5953 FPT_Wait(p_port,TO_250ms);
5959 /*---------------------------------------------------------------------
5961 * Function: FPT_scbusf
5963 * Description: Release the SCSI bus and disable SCAM selection.
5965 *---------------------------------------------------------------------*/
5967 static void FPT_scbusf(ULONG p_port)
5969 WR_HARPOON(p_port+hp_page_ctrl,
5970 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5973 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5975 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5978 WR_HARPOON(p_port+hp_scsisig, 0x00);
5981 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5984 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5987 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5989 WR_HARPOON(p_port+hp_page_ctrl,
5990 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5995 /*---------------------------------------------------------------------
5997 * Function: FPT_scasid
5999 * Description: Assign an ID to all the SCAM devices.
6001 *---------------------------------------------------------------------*/
6003 static void FPT_scasid(UCHAR p_card, ULONG p_port)
6005 UCHAR temp_id_string[ID_STRING_LENGTH];
6009 PNVRamInfo pCurrNvRam;
6010 ushort_ptr pCrcBytes;
6012 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6019 for (k=0; k < ID_STRING_LENGTH; k++)
6021 temp_id_string[k] = (UCHAR) 0x00;
6024 FPT_scxferc(p_port,SYNC_PTRN);
6025 FPT_scxferc(p_port,ASSIGN_ID);
6027 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6030 pCrcBytes = (ushort_ptr)&crcBytes[0];
6031 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6032 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6033 temp_id_string[1] = crcBytes[2];
6034 temp_id_string[2] = crcBytes[0];
6035 temp_id_string[3] = crcBytes[1];
6036 for(k = 4; k < ID_STRING_LENGTH; k++)
6037 temp_id_string[k] = (UCHAR) 0x00;
6039 i = FPT_scmachid(p_card,temp_id_string);
6041 if (i == CLR_PRIORITY)
6043 FPT_scxferc(p_port,MISC_CODE);
6044 FPT_scxferc(p_port,CLR_P_FLAG);
6045 i = 0; /*Not the last ID yet. */
6048 else if (i != NO_ID_AVAIL)
6051 FPT_scxferc(p_port,ID_0_7);
6053 FPT_scxferc(p_port,ID_8_F);
6055 scam_id = (i & (UCHAR) 0x07);
6058 for (k=1; k < 0x08; k <<= 1)
6060 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6062 FPT_scxferc(p_port,scam_id);
6064 i = 0; /*Not the last ID yet. */
6075 FPT_scxferc(p_port,SYNC_PTRN);
6076 FPT_scxferc(p_port,CFG_CMPLT);
6083 /*---------------------------------------------------------------------
6085 * Function: FPT_scsel
6087 * Description: Select all the SCAM devices.
6089 *---------------------------------------------------------------------*/
6091 static void FPT_scsel(ULONG p_port)
6094 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6095 FPT_scwiros(p_port, SCSI_MSG);
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6100 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6101 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
6102 (UCHAR)(BIT(7)+BIT(6))));
6105 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6106 FPT_scwiros(p_port, SCSI_SEL);
6108 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
6110 FPT_scwirod(p_port, BIT(6));
6112 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6117 /*---------------------------------------------------------------------
6119 * Function: FPT_scxferc
6121 * Description: Handshake the p_data (DB4-0) across the bus.
6123 *---------------------------------------------------------------------*/
6125 static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
6127 UCHAR curr_data, ret_data;
6129 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6131 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6133 curr_data &= ~BIT(7);
6135 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6137 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6138 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6140 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
6142 curr_data |= BIT(6);
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6146 curr_data &= ~BIT(5);
6148 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6150 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6152 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6153 curr_data |= BIT(7);
6155 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6157 curr_data &= ~BIT(6);
6159 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6161 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6167 /*---------------------------------------------------------------------
6169 * Function: FPT_scsendi
6171 * Description: Transfer our Identification string to determine if we
6172 * will be the dominant master.
6174 *---------------------------------------------------------------------*/
6176 static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
6178 UCHAR ret_data,byte_cnt,bit_cnt,defer;
6182 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6184 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6187 ret_data = FPT_scxferc(p_port,00);
6189 else if (p_id_string[byte_cnt] & bit_cnt)
6191 ret_data = FPT_scxferc(p_port,02);
6195 ret_data = FPT_scxferc(p_port,01);
6200 if ((ret_data & 0x1C) == 0x10)
6201 return(0x00); /*End of isolation stage, we won! */
6203 if (ret_data & 0x1C)
6206 if ((defer) && (!(ret_data & 0x1F)))
6207 return(0x01); /*End of isolation stage, we lost. */
6214 return(0x01); /*We lost */
6216 return(0); /*We WON! Yeeessss! */
6221 /*---------------------------------------------------------------------
6223 * Function: FPT_sciso
6225 * Description: Transfer the Identification string.
6227 *---------------------------------------------------------------------*/
6229 static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
6231 UCHAR ret_data,the_data,byte_cnt,bit_cnt;
6235 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6237 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6239 ret_data = FPT_scxferc(p_port,0);
6241 if (ret_data & 0xFC)
6247 if (ret_data & BIT(1)) {
6252 if ((ret_data & 0x1F) == 0)
6255 if(bit_cnt != 0 || bit_cnt != 8)
6259 FPT_scxferc(p_port, SYNC_PTRN);
6260 FPT_scxferc(p_port, ASSIGN_ID);
6272 p_id_string[byte_cnt] = the_data;
6281 /*---------------------------------------------------------------------
6283 * Function: FPT_scwirod
6285 * Description: Sample the SCSI data bus making sure the signal has been
6286 * deasserted for the correct number of consecutive samples.
6288 *---------------------------------------------------------------------*/
6290 static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
6295 while ( i < MAX_SCSI_TAR ) {
6297 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6310 /*---------------------------------------------------------------------
6312 * Function: FPT_scwiros
6314 * Description: Sample the SCSI Signal lines making sure the signal has been
6315 * deasserted for the correct number of consecutive samples.
6317 *---------------------------------------------------------------------*/
6319 static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
6324 while ( i < MAX_SCSI_TAR ) {
6326 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6338 /*---------------------------------------------------------------------
6340 * Function: FPT_scvalq
6342 * Description: Make sure we received a valid data byte.
6344 *---------------------------------------------------------------------*/
6346 static UCHAR FPT_scvalq(UCHAR p_quintet)
6350 for (count=1; count < 0x08; count<<=1) {
6351 if (!(p_quintet & count))
6355 if (p_quintet & 0x18)
6363 /*---------------------------------------------------------------------
6365 * Function: FPT_scsell
6367 * Description: Select the specified device ID using a selection timeout
6368 * less than 4ms. If somebody responds then it is a legacy
6369 * drive and this ID must be marked as such.
6371 *---------------------------------------------------------------------*/
6373 static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
6377 WR_HARPOON(p_port+hp_page_ctrl,
6378 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6380 ARAM_ACCESS(p_port);
6382 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6383 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6386 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6387 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6389 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6391 WRW_HARPOON((p_port+hp_intstat),
6392 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6394 WR_HARPOON(p_port+hp_select_id, targ_id);
6396 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6397 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6398 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6401 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6402 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6404 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6405 FPT_Wait(p_port, TO_250ms);
6407 DISABLE_AUTO(p_port);
6409 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6410 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6412 SGRAM_ACCESS(p_port);
6414 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6416 WRW_HARPOON((p_port+hp_intstat),
6417 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6419 WR_HARPOON(p_port+hp_page_ctrl,
6420 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6422 return(0); /*No legacy device */
6427 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6428 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6430 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6435 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6437 WR_HARPOON(p_port+hp_page_ctrl,
6438 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6440 return(1); /*Found one of them oldies! */
6444 /*---------------------------------------------------------------------
6446 * Function: FPT_scwtsel
6448 * Description: Wait to be selected by another SCAM initiator.
6450 *---------------------------------------------------------------------*/
6452 static void FPT_scwtsel(ULONG p_port)
6454 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6458 /*---------------------------------------------------------------------
6460 * Function: FPT_inisci
6462 * Description: Setup the data Structure with the info from the EEPROM.
6464 *---------------------------------------------------------------------*/
6466 static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
6470 PNVRamInfo pCurrNvRam;
6472 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6474 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6481 for(i = 0; i < max_id; i++){
6483 for(k = 0; k < 4; k++)
6484 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6485 for(k = 4; k < ID_STRING_LENGTH; k++)
6486 FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
6488 if(FPT_scamInfo[i].id_string[0] == 0x00)
6489 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6491 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6495 for (i=0; i < max_id; i++)
6497 for (k=0; k < ID_STRING_LENGTH; k+=2)
6499 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
6500 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6501 FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
6503 FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
6506 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6507 (FPT_scamInfo[i].id_string[0] == 0xFF))
6509 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6512 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6516 for(k = 0; k < ID_STRING_LENGTH; k++)
6517 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6521 /*---------------------------------------------------------------------
6523 * Function: FPT_scmachid
6525 * Description: Match the Device ID string with our values stored in
6528 *---------------------------------------------------------------------*/
6530 static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
6536 for (i=0; i < MAX_SCSI_TAR; i++) {
6540 for (k=0; k < ID_STRING_LENGTH; k++)
6542 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6548 FPT_scamInfo[i].state = ID_ASSIGNED;
6556 if (p_id_string[0] & BIT(5))
6561 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6562 match = p_id_string[1] & (UCHAR) 0x1F;
6570 if (FPT_scamInfo[match].state == ID_UNUSED)
6572 for (k=0; k < ID_STRING_LENGTH; k++)
6574 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6577 FPT_scamInfo[match].state = ID_ASSIGNED;
6579 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6580 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6590 if (p_id_string[0] & BIT(5))
6593 match = MAX_SCSI_TAR-1;
6599 if (p_id_string[0] & BIT(7))
6601 return(CLR_PRIORITY);
6605 if (p_id_string[0] & BIT(5))
6610 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6611 match = p_id_string[1] & (UCHAR) 0x1F;
6620 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6622 for (k=0; k < ID_STRING_LENGTH; k++)
6624 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6627 FPT_scamInfo[match].id_string[0] |= BIT(7);
6628 FPT_scamInfo[match].state = ID_ASSIGNED;
6629 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6630 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6640 if (p_id_string[0] & BIT(5))
6643 match = MAX_SCSI_TAR-1;
6647 return(NO_ID_AVAIL);
6651 /*---------------------------------------------------------------------
6653 * Function: FPT_scsavdi
6655 * Description: Save off the device SCAM ID strings.
6657 *---------------------------------------------------------------------*/
6659 static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
6662 USHORT ee_data,sum_data;
6667 for (i = 1; i < EE_SCAMBASE/2; i++)
6669 sum_data += FPT_utilEERead(p_port, i);
6673 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6675 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6681 for (i=0; i < max_id; i++)
6684 for (k=0; k < ID_STRING_LENGTH; k+=2)
6686 ee_data = FPT_scamInfo[i].id_string[k+1];
6688 ee_data |= FPT_scamInfo[i].id_string[k];
6689 sum_data += ee_data;
6690 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
6691 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6696 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6697 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6700 /*---------------------------------------------------------------------
6702 * Function: FPT_XbowInit
6704 * Description: Setup the Xbow for normal operation.
6706 *---------------------------------------------------------------------*/
6708 static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
6712 i = RD_HARPOON(port+hp_page_ctrl);
6713 WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
6715 WR_HARPOON(port+hp_scsireset,0x00);
6716 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6718 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6721 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6723 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6725 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6726 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6728 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6730 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6731 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6733 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6734 FPT_default_intena |= SCAM_SEL;
6736 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6738 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6740 /* Turn on SCSI_MODE8 for narrow cards to fix the
6741 strapping issue with the DUAL CHANNEL card */
6742 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6743 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6745 WR_HARPOON(port+hp_page_ctrl, i);
6750 /*---------------------------------------------------------------------
6752 * Function: FPT_BusMasterInit
6754 * Description: Initialize the BusMaster for normal operations.
6756 *---------------------------------------------------------------------*/
6758 static void FPT_BusMasterInit(ULONG p_port)
6762 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6763 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6765 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6768 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6770 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6773 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6774 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6775 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6780 /*---------------------------------------------------------------------
6782 * Function: FPT_DiagEEPROM
6784 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6787 *---------------------------------------------------------------------*/
6789 static void FPT_DiagEEPROM(ULONG p_port)
6791 USHORT index,temp,max_wd_cnt;
6793 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6794 max_wd_cnt = EEPROM_WD_CNT;
6796 max_wd_cnt = EEPROM_WD_CNT * 2;
6798 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6800 if (temp == 0x4641) {
6802 for (index = 2; index < max_wd_cnt; index++) {
6804 temp += FPT_utilEERead(p_port, index);
6808 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6810 return; /*EEPROM is Okay so return now! */
6815 FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
6817 for (index = 0; index < max_wd_cnt; index++) {
6819 FPT_utilEEWrite(p_port, 0x0000, index);
6824 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6826 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6828 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6830 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6832 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6834 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6836 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6838 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6841 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6843 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6845 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6850 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6852 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6854 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6856 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6858 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6860 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6862 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6866 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6868 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6870 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6872 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6874 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6876 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6878 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6880 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6883 index = ((EE_SCAMBASE/2)+(7*16));
6884 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6885 temp += (0x0700+TYPE_CODE0);
6887 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6888 temp += 0x5542; /* BUSLOGIC */
6890 FPT_utilEEWrite(p_port, 0x4C53, index);
6893 FPT_utilEEWrite(p_port, 0x474F, index);
6896 FPT_utilEEWrite(p_port, 0x4349, index);
6899 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6900 temp += 0x5442; /* BT- 930 */
6902 FPT_utilEEWrite(p_port, 0x202D, index);
6905 FPT_utilEEWrite(p_port, 0x3339, index);
6907 index++; /*Serial # */
6908 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6911 FPT_utilEEWrite(p_port, 0x5453, index);
6914 FPT_utilEEWrite(p_port, 0x5645, index);
6917 FPT_utilEEWrite(p_port, 0x2045, index);
6920 FPT_utilEEWrite(p_port, 0x202F, index);
6923 FPT_utilEEWrite(p_port, 0x4F4A, index);
6926 FPT_utilEEWrite(p_port, 0x204E, index);
6929 FPT_utilEEWrite(p_port, 0x3539, index);
6934 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6936 FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
6941 /*---------------------------------------------------------------------
6943 * Function: Queue Search Select
6945 * Description: Try to find a new command to execute.
6947 *---------------------------------------------------------------------*/
6949 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
6951 UCHAR scan_ptr, lun;
6952 PSCCBMgr_tar_info currTar_Info;
6955 scan_ptr = pCurrCard->scanIndex;
6958 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6959 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6960 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6962 if (currTar_Info->TarSelQ_Cnt != 0)
6966 if (scan_ptr == MAX_SCSI_TAR)
6969 for(lun=0; lun < MAX_LUN; lun++)
6971 if(currTar_Info->TarLUNBusy[lun] == 0)
6974 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6977 while((pCurrCard->currentSCCB != NULL) &&
6978 (lun != pCurrCard->currentSCCB->Lun))
6980 pOldSccb = pCurrCard->currentSCCB;
6981 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6984 if(pCurrCard->currentSCCB == NULL)
6986 if(pOldSccb != NULL)
6988 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6990 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6992 currTar_Info->TarSelQ_Cnt--;
6996 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6998 if (currTar_Info->TarSelQ_Head == NULL)
7000 currTar_Info->TarSelQ_Tail = NULL;
7001 currTar_Info->TarSelQ_Cnt = 0;
7005 currTar_Info->TarSelQ_Cnt--;
7006 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7009 pCurrCard->scanIndex = scan_ptr;
7011 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7021 if (scan_ptr == MAX_SCSI_TAR) {
7029 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7030 (currTar_Info->TarLUNBusy[0] == 0))
7033 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7035 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7037 if (currTar_Info->TarSelQ_Head == NULL)
7039 currTar_Info->TarSelQ_Tail = NULL;
7040 currTar_Info->TarSelQ_Cnt = 0;
7044 currTar_Info->TarSelQ_Cnt--;
7045 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7049 if (scan_ptr == MAX_SCSI_TAR)
7052 pCurrCard->scanIndex = scan_ptr;
7054 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7062 if (scan_ptr == MAX_SCSI_TAR)
7068 } while (scan_ptr != pCurrCard->scanIndex);
7072 /*---------------------------------------------------------------------
7074 * Function: Queue Select Fail
7076 * Description: Add the current SCCB to the head of the Queue.
7078 *---------------------------------------------------------------------*/
7080 static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
7083 PSCCBMgr_tar_info currTar_Info;
7085 if (pCurrCard->currentSCCB != NULL)
7087 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7088 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7090 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7092 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7094 if (currTar_Info->TarSelQ_Cnt == 0)
7096 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7101 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7105 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7107 pCurrCard->currentSCCB = NULL;
7108 currTar_Info->TarSelQ_Cnt++;
7111 /*---------------------------------------------------------------------
7113 * Function: Queue Command Complete
7115 * Description: Call the callback function with the current SCCB.
7117 *---------------------------------------------------------------------*/
7119 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7124 CALL_BK_FN callback;
7125 PSCCBMgr_tar_info currTar_Info;
7127 SCSIcmd = p_sccb->Cdb[0];
7130 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7132 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7133 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7134 (p_sccb->TargetStatus != SSCHECK))
7136 if ((SCSIcmd == SCSI_READ) ||
7137 (SCSIcmd == SCSI_WRITE) ||
7138 (SCSIcmd == SCSI_READ_EXTENDED) ||
7139 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7140 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7141 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7142 (pCurrCard->globalFlags & F_NO_FILTER)
7144 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7148 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7150 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7151 p_sccb->SccbStatus = SCCB_ERROR;
7153 p_sccb->SccbStatus = SCCB_SUCCESS;
7156 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7158 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7159 for (i=0; i < 6; i++) {
7160 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7164 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7165 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7167 FPT_utilUpdateResidual(p_sccb);
7170 pCurrCard->cmdCounter--;
7171 if (!pCurrCard->cmdCounter) {
7173 if (pCurrCard->globalFlags & F_GREEN_PC) {
7174 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7175 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7178 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7179 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7183 if(pCurrCard->discQCount != 0)
7185 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7186 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7187 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7189 pCurrCard->discQCount--;
7190 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7194 if(p_sccb->Sccb_tag)
7196 pCurrCard->discQCount--;
7197 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7200 pCurrCard->discQCount--;
7201 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7207 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7209 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7210 pCurrCard->currentSCCB = NULL;
7214 /*---------------------------------------------------------------------
7216 * Function: Queue Disconnect
7218 * Description: Add SCCB to our disconnect array.
7220 *---------------------------------------------------------------------*/
7221 static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
7223 PSCCBMgr_tar_info currTar_Info;
7225 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7227 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7228 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7230 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7234 if (p_sccb->Sccb_tag)
7236 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7237 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7238 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7241 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7244 FPT_BL_Card[p_card].currentSCCB = NULL;
7248 /*---------------------------------------------------------------------
7250 * Function: Queue Flush SCCB
7252 * Description: Flush all SCCB's back to the host driver for this target.
7254 *---------------------------------------------------------------------*/
7256 static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
7258 UCHAR qtag,thisTarg;
7260 PSCCBMgr_tar_info currTar_Info;
7262 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7263 if(currSCCB != NULL)
7265 thisTarg = (UCHAR)currSCCB->TargID;
7266 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7268 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7270 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7271 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7274 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
7276 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7278 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7279 currTar_Info->TarTagQ_Cnt--;
7287 /*---------------------------------------------------------------------
7289 * Function: Queue Flush Target SCCB
7291 * Description: Flush all SCCB's back to the host driver for this target.
7293 *---------------------------------------------------------------------*/
7295 static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7299 PSCCBMgr_tar_info currTar_Info;
7301 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7303 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7305 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7306 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7309 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
7311 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7313 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7314 currTar_Info->TarTagQ_Cnt--;
7325 static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
7327 PSCCBMgr_tar_info currTar_Info;
7328 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7330 p_SCCB->Sccb_forwardlink = NULL;
7332 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7334 if (currTar_Info->TarSelQ_Cnt == 0) {
7336 currTar_Info->TarSelQ_Head = p_SCCB;
7341 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7345 currTar_Info->TarSelQ_Tail = p_SCCB;
7346 currTar_Info->TarSelQ_Cnt++;
7350 /*---------------------------------------------------------------------
7352 * Function: Queue Find SCCB
7354 * Description: Search the target select Queue for this SCCB, and
7355 * remove it if found.
7357 *---------------------------------------------------------------------*/
7359 static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
7362 PSCCBMgr_tar_info currTar_Info;
7364 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7366 q_ptr = currTar_Info->TarSelQ_Head;
7368 while(q_ptr != NULL) {
7370 if (q_ptr == p_SCCB) {
7373 if (currTar_Info->TarSelQ_Head == q_ptr) {
7375 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7378 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7380 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7383 if (q_ptr->Sccb_forwardlink != NULL) {
7384 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7387 if (q_ptr->Sccb_backlink != NULL) {
7388 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7391 currTar_Info->TarSelQ_Cnt--;
7397 q_ptr = q_ptr->Sccb_forwardlink;
7407 /*---------------------------------------------------------------------
7409 * Function: Utility Update Residual Count
7411 * Description: Update the XferCnt to the remaining byte count.
7412 * If we transferred all the data then just write zero.
7413 * If Non-SG transfer then report Total Cnt - Actual Transfer
7414 * Cnt. For SG transfers add the count fields of all
7415 * remaining SG elements, as well as any partial remaining
7418 *---------------------------------------------------------------------*/
7420 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7426 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7428 p_SCCB->DataLength = 0x0000;
7431 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7433 partial_cnt = 0x0000;
7435 sg_index = p_SCCB->Sccb_sgseg;
7437 sg_ptr = (ULONG *)p_SCCB->DataPointer;
7439 if (p_SCCB->Sccb_SGoffset) {
7441 partial_cnt = p_SCCB->Sccb_SGoffset;
7445 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7446 p_SCCB->DataLength ) {
7448 partial_cnt += *(sg_ptr+(sg_index * 2));
7452 p_SCCB->DataLength = partial_cnt;
7457 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7462 /*---------------------------------------------------------------------
7464 * Function: Wait 1 Second
7466 * Description: Wait for 1 second.
7468 *---------------------------------------------------------------------*/
7470 static void FPT_Wait1Second(ULONG p_port)
7474 for(i=0; i < 4; i++) {
7476 FPT_Wait(p_port, TO_250ms);
7478 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7481 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7487 /*---------------------------------------------------------------------
7489 * Function: FPT_Wait
7491 * Description: Wait the desired delay.
7493 *---------------------------------------------------------------------*/
7495 static void FPT_Wait(ULONG p_port, UCHAR p_delay)
7500 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7502 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7503 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7505 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7506 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7507 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7510 WR_HARPOON(p_port+hp_portctrl_0,
7511 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7513 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7515 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7518 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7522 WR_HARPOON(p_port+hp_portctrl_0,
7523 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7525 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7526 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7528 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7530 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7534 /*---------------------------------------------------------------------
7536 * Function: Enable/Disable Write to EEPROM
7538 * Description: The EEPROM must first be enabled for writes
7539 * A total of 9 clocks are needed.
7541 *---------------------------------------------------------------------*/
7543 static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
7547 ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7551 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7556 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7558 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7559 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7563 /*---------------------------------------------------------------------
7565 * Function: Write EEPROM
7567 * Description: Write a word to the EEPROM at the specified
7570 *---------------------------------------------------------------------*/
7572 static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
7578 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7583 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7586 ee_value |= (SEE_MS + SEE_CS);
7588 for(i = 0x8000; i != 0; i>>=1) {
7593 ee_value &= ~SEE_DO;
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 ee_value |= SEE_CLK; /* Clock data! */
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 ee_value &= ~SEE_CLK;
7601 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7602 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7604 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7605 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7607 FPT_Wait(p_port, TO_10ms);
7609 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7610 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7611 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7614 /*---------------------------------------------------------------------
7616 * Function: Read EEPROM
7618 * Description: Read a word from the EEPROM at the desired
7621 *---------------------------------------------------------------------*/
7623 static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
7625 USHORT i, ee_data1, ee_data2;
7628 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7631 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7633 if(ee_data1 == ee_data2)
7636 ee_data1 = ee_data2;
7644 /*---------------------------------------------------------------------
7646 * Function: Read EEPROM Original
7648 * Description: Read a word from the EEPROM at the desired
7651 *---------------------------------------------------------------------*/
7653 static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
7659 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7663 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7666 ee_value |= (SEE_MS + SEE_CS);
7669 for(i = 1; i <= 16; i++) {
7671 ee_value |= SEE_CLK; /* Clock data! */
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7674 ee_value &= ~SEE_CLK;
7675 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7676 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7680 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7684 ee_value &= ~(SEE_MS + SEE_CS);
7685 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7686 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7692 /*---------------------------------------------------------------------
7694 * Function: Send EE command and Address to the EEPROM
7696 * Description: Transfers the correct command and sends the address
7699 *---------------------------------------------------------------------*/
7701 static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
7709 narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 ee_value |= SEE_CS; /* Set CS to EEPROM */
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7719 for(i = 0x04; i != 0; i>>=1) {
7724 ee_value &= ~SEE_DO;
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 ee_value |= SEE_CLK; /* Clock data! */
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 ee_value &= ~SEE_CLK;
7732 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7733 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 ee_value &= ~SEE_DO;
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 ee_value |= SEE_CLK; /* Clock data! */
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7756 ee_value &= ~SEE_CLK;
7757 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7758 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7764 static USHORT FPT_CalcCrc16(UCHAR buffer[])
7769 for (i=0; i < ID_STRING_LENGTH; i++)
7771 ch = (USHORT) buffer[i];
7772 for(j=0; j < 8; j++)
7775 crc = (crc >> 1) ^ CRCMASK;
7784 static UCHAR FPT_CalcLrc(UCHAR buffer[])
7789 for(i = 0; i < ID_STRING_LENGTH; i++)
7797 The following inline definitions avoid type conflicts.
7800 static inline unsigned char
7801 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7803 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7807 static inline FlashPoint_CardHandle_T
7808 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7810 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7814 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7816 FlashPoint_ReleaseHostAdapter(CardHandle);
7821 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7823 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7828 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7830 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7834 static inline boolean
7835 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7837 return FlashPoint_InterruptPending(CardHandle);
7842 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7844 return FlashPoint_HandleInterrupt(CardHandle);
7848 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7849 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7850 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7851 #define FlashPoint_StartCCB FlashPoint__StartCCB
7852 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7853 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7854 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7857 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7861 Define prototypes for the FlashPoint SCCB Manager Functions.
7864 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7865 extern FlashPoint_CardHandle_T
7866 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7867 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7868 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7869 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7870 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7871 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7874 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */