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 short USHORT;
44 typedef unsigned int UINT;
45 typedef unsigned long ULONG;
48 typedef unsigned short * ushort_ptr;
55 #define u08bits unsigned s08bits
56 #define u16bits unsigned s16bits
57 #define u32bits unsigned s32bits
61 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
62 #define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
67 typedef struct _SCCB *PSCCB;
68 typedef void (*CALL_BK_FN)(PSCCB);
71 typedef struct SCCBMgr_info {
73 unsigned char si_present;
74 unsigned char si_intvect;
77 USHORT si_fw_revision;
78 USHORT si_per_targ_init_sync;
79 USHORT si_per_targ_fast_nego;
80 USHORT si_per_targ_ultra_nego;
81 USHORT si_per_targ_no_disc;
82 USHORT si_per_targ_wide_nego;
84 unsigned char si_card_family;
85 unsigned char si_bustype;
86 unsigned char si_card_model[3];
87 unsigned char si_relative_cardnum;
88 unsigned char si_reserved[4];
90 unsigned char si_XlatInfo[4];
91 ULONG si_reserved2[5];
92 ULONG si_secondary_range;
95 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
98 #define SCSI_PARITY_ENA 0x0001
99 #define LOW_BYTE_TERM 0x0010
100 #define HIGH_BYTE_TERM 0x0020
101 #define BUSTYPE_PCI 0x3
103 #define SUPPORT_16TAR_32LUN 0x0002
104 #define SOFT_RESET 0x0004
105 #define EXTENDED_TRANSLATION 0x0008
106 #define POST_ALL_UNDERRRUNS 0x0040
107 #define FLAG_SCAM_ENABLED 0x0080
108 #define FLAG_SCAM_LEVEL2 0x0100
113 #define HARPOON_FAMILY 0x02
117 /* SCCB struct used for both SCCB and UCB manager compiles!
118 * The UCB Manager treats the SCCB as it's 'native hardware structure'
123 typedef struct _SCCB {
124 unsigned char OperationCode;
125 unsigned char ControlByte;
126 unsigned char CdbLength;
127 unsigned char RequestSenseLength;
130 unsigned char CcbRes[2];
131 unsigned char HostStatus;
132 unsigned char TargetStatus;
133 unsigned char TargID;
135 unsigned char Cdb[12];
136 unsigned char CcbRes1;
137 unsigned char Reserved1;
142 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
143 ULONG SccbIOPort; /* Identifies board base port */
144 unsigned char SccbStatus;
145 unsigned char SCCBRes2;
149 ULONG Sccb_XferCnt; /* actual transfer count */
151 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
153 USHORT Sccb_MGRFlags;
155 unsigned char Sccb_scsimsg; /* identify msg for selection */
156 unsigned char Sccb_tag;
157 unsigned char Sccb_scsistat;
158 unsigned char Sccb_idmsg; /* image of last msg in */
159 PSCCB Sccb_forwardlink;
162 unsigned char Save_Cdb[6];
163 unsigned char Save_CdbLen;
164 unsigned char Sccb_XferState;
173 #define SCATTER_GATHER_COMMAND 0x02
174 #define RESIDUAL_COMMAND 0x03
175 #define RESIDUAL_SG_COMMAND 0x04
176 #define RESET_COMMAND 0x81
179 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
180 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
181 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
182 #define SCCB_DATA_XFER_IN 0x08 /* Read */
185 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
188 #define BUS_FREE_ST 0
190 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
191 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
192 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
193 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
195 #define DATA_OUT_ST 7
197 #define DISCONNECT_ST 9
201 #define F_HOST_XFER_DIR 0x01
202 #define F_ALL_XFERRED 0x02
203 #define F_SG_XFER 0x04
204 #define F_AUTO_SENSE 0x08
205 #define F_ODD_BALL_CNT 0x10
206 #define F_NO_DATA_YET 0x80
209 #define F_STATUSLOADED 0x01
210 #define F_DEV_SELECTED 0x04
213 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
214 #define SCCB_DATA_UNDER_RUN 0x0C
215 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
216 #define SCCB_DATA_OVER_RUN 0x12
217 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
219 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
220 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
221 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
227 #define SCCB_IN_PROCESS 0x00
228 #define SCCB_SUCCESS 0x01
229 #define SCCB_ABORT 0x02
230 #define SCCB_ERROR 0x04
234 #define ORION_FW_REV 3110
238 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
240 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
243 #define MAX_SCSI_TAR 16
245 #define LUN_MASK 0x1f
247 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
249 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
252 #define RD_HARPOON(ioport) inb((u32bits)ioport)
253 #define RDW_HARPOON(ioport) inw((u32bits)ioport)
254 #define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
255 #define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
256 #define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
257 #define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
260 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
261 #define SYNC_TRYING BIT(6)
262 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
264 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
265 #define WIDE_ENABLED BIT(4)
266 #define WIDE_NEGOCIATED BIT(5)
268 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
269 #define TAG_Q_TRYING BIT(2)
270 #define TAG_Q_REJECT BIT(3)
272 #define TAR_ALLOW_DISC BIT(0)
275 #define EE_SYNC_MASK (BIT(0)+BIT(1))
276 #define EE_SYNC_5MB BIT(0)
277 #define EE_SYNC_10MB BIT(1)
278 #define EE_SYNC_20MB (BIT(0)+BIT(1))
280 #define EE_WIDE_SCSI BIT(7)
283 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
286 typedef struct SCCBMgr_tar_info {
290 unsigned char TarLUN_CA; /*Contingent Allgiance */
291 unsigned char TarTagQ_Cnt;
292 unsigned char TarSelQ_Cnt;
293 unsigned char TarStatus;
294 unsigned char TarEEValue;
295 unsigned char TarSyncCtrl;
296 unsigned char TarReserved[2]; /* for alignment */
297 unsigned char LunDiscQ_Idx[MAX_LUN];
298 unsigned char TarLUNBusy[MAX_LUN];
301 typedef struct NVRAMInfo {
302 unsigned char niModel; /* Model No. of card */
303 unsigned char niCardNo; /* Card no. */
304 ULONG niBaseAddr; /* Port Address of card */
305 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
306 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
307 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
308 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
309 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
310 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
313 typedef NVRAMINFO *PNVRamInfo;
321 typedef struct SCCBcard {
323 PSCCBMGR_INFO cardInfo;
328 unsigned char discQCount;
329 unsigned char tagQ_Lst;
330 unsigned char cardIndex;
331 unsigned char scanIndex;
332 unsigned char globalFlags;
334 PNVRamInfo pNvRamInfo;
335 PSCCB discQ_Tbl[QUEUE_DEPTH];
339 typedef struct SCCBcard *PSCCBcard;
342 #define F_TAG_STARTED 0x01
343 #define F_CONLUN_IO 0x02
344 #define F_DO_RENEGO 0x04
345 #define F_NO_FILTER 0x08
346 #define F_GREEN_PC 0x10
347 #define F_HOST_XFER_ACT 0x20
348 #define F_NEW_SCCB_CMD 0x40
349 #define F_UPDATE_EEPROM 0x80
352 #define ID_STRING_LENGTH 32
353 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
356 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
358 #define ASSIGN_ID 0x00
359 #define SET_P_FLAG 0x01
360 #define CFG_CMPLT 0x03
361 #define DOM_MSTR 0x0F
362 #define SYNC_PTRN 0x1F
366 #define MISC_CODE 0x14
367 #define CLR_P_FLAG 0x18
371 #define INIT_SELTD 0x01
372 #define LEVEL2_TAR 0x02
375 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
376 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
377 CLR_PRIORITY,NO_ID_AVAIL };
379 typedef struct SCCBscam_info {
381 unsigned char id_string[ID_STRING_LENGTH];
382 enum scam_id_st state;
387 #define SCSI_REQUEST_SENSE 0x03
388 #define SCSI_READ 0x08
389 #define SCSI_WRITE 0x0A
390 #define SCSI_START_STOP_UNIT 0x1B
391 #define SCSI_READ_EXTENDED 0x28
392 #define SCSI_WRITE_EXTENDED 0x2A
393 #define SCSI_WRITE_AND_VERIFY 0x2E
399 #define SSQ_FULL 0x28
404 #define SMCMD_COMP 0x00
406 #define SMSAVE_DATA_PTR 0x02
407 #define SMREST_DATA_PTR 0x03
410 #define SMREJECT 0x07
412 #define SMPARITY 0x09
413 #define SMDEV_RESET 0x0C
414 #define SMABORT_TAG 0x0D
415 #define SMINIT_RECOVERY 0x0F
416 #define SMREL_RECOVERY 0x10
419 #define DISC_PRIV 0x40
426 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
435 #define SIX_BYTE_CMD 0x06
436 #define TWELVE_BYTE_CMD 0x0C
439 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
442 #define EEPROM_WD_CNT 256
444 #define EEPROM_CHECK_SUM 0
445 #define FW_SIGNATURE 2
446 #define MODEL_NUMB_0 4
447 #define MODEL_NUMB_2 6
448 #define MODEL_NUMB_4 8
449 #define SYSTEM_CONFIG 16
450 #define SCSI_CONFIG 17
451 #define BIOS_CONFIG 18
452 #define SCAM_CONFIG 20
453 #define ADAPTER_SCSI_ID 24
456 #define IGNORE_B_SCAN 32
457 #define SEND_START_ENA 34
458 #define DEVICE_ENABLE 36
460 #define SYNC_RATE_TBL 38
461 #define SYNC_RATE_TBL01 38
462 #define SYNC_RATE_TBL23 40
463 #define SYNC_RATE_TBL45 42
464 #define SYNC_RATE_TBL67 44
465 #define SYNC_RATE_TBL89 46
466 #define SYNC_RATE_TBLab 48
467 #define SYNC_RATE_TBLcd 50
468 #define SYNC_RATE_TBLef 52
472 #define EE_SCAMBASE 256
476 #define SCAM_ENABLED BIT(2)
477 #define SCAM_LEVEL2 BIT(3)
480 #define RENEGO_ENA BITW(10)
481 #define CONNIO_ENA BITW(11)
482 #define GREEN_PC_ENA BITW(12)
485 #define AUTO_RATE_00 00
486 #define AUTO_RATE_05 01
487 #define AUTO_RATE_10 02
488 #define AUTO_RATE_20 03
490 #define WIDE_NEGO_BIT BIT(7)
491 #define DISC_ENABLE_BIT BIT(6)
495 #define hp_vendor_id_0 0x00 /* LSB */
496 #define ORION_VEND_0 0x4B
498 #define hp_vendor_id_1 0x01 /* MSB */
499 #define ORION_VEND_1 0x10
501 #define hp_device_id_0 0x02 /* LSB */
502 #define ORION_DEV_0 0x30
504 #define hp_device_id_1 0x03 /* MSB */
505 #define ORION_DEV_1 0x81
507 /* Sub Vendor ID and Sub Device ID only available in
508 Harpoon Version 2 and higher */
510 #define hp_sub_device_id_0 0x06 /* LSB */
514 #define hp_semaphore 0x0C
515 #define SCCB_MGR_ACTIVE BIT(0)
516 #define TICKLE_ME BIT(1)
517 #define SCCB_MGR_PRESENT BIT(3)
518 #define BIOS_IN_USE BIT(4)
522 #define hp_sys_ctrl 0x0F
524 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
525 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
526 #define HALT_MACH BIT(3) /*Halt State Machine */
527 #define HARD_ABORT BIT(4) /*Hard Abort */
537 #define hp_host_blk_cnt 0x13
539 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
541 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
545 #define hp_int_mask 0x17
547 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
548 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
551 #define hp_xfer_cnt_lo 0x18
552 #define hp_xfer_cnt_hi 0x1A
553 #define hp_xfer_cmd 0x1B
555 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
556 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
559 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
561 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
563 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
565 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
566 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
568 #define hp_host_addr_lo 0x1C
569 #define hp_host_addr_hmi 0x1E
571 #define hp_ee_ctrl 0x22
573 #define EXT_ARB_ACK BIT(7)
574 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
575 #define SEE_MS BIT(5)
576 #define SEE_CS BIT(3)
577 #define SEE_CLK BIT(2)
578 #define SEE_DO BIT(1)
579 #define SEE_DI BIT(0)
582 #define EE_WRITE 0x05
584 #define EWEN_ADDR 0x03C0
586 #define EWDS_ADDR 0x0000
594 #define hp_bm_ctrl 0x26
596 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
597 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
598 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
599 #define FAST_SINGLE BIT(6) /*?? */
601 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
604 #define hp_sg_addr 0x28
605 #define hp_page_ctrl 0x29
607 #define SCATTER_EN BIT(0)
608 #define SGRAM_ARAM BIT(1)
609 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
610 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
615 #define hp_pci_stat_cfg 0x2D
617 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
626 #define hp_rev_num 0x33
629 #define hp_stack_data 0x34
630 #define hp_stack_addr 0x35
632 #define hp_ext_status 0x36
634 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
635 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
636 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
637 #define CMD_ABORTED BIT(4) /*Command aborted */
638 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
639 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
640 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
641 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
642 BM_PARITY_ERR | PIO_OVERRUN)
644 #define hp_int_status 0x37
646 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
647 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
648 #define INT_ASSERTED BIT(5) /* */
651 #define hp_fifo_cnt 0x38
656 #define hp_intena 0x40
658 #define RESET BITW(7)
659 #define PROG_HLT BITW(6)
660 #define PARITY BITW(5)
663 #define SCAM_SEL BITW(2)
665 #define TIMEOUT BITW(0)
666 #define BUS_FREE BITW(15)
667 #define XFER_CNT_0 BITW(14)
668 #define PHASE BITW(13)
669 #define IUNKWN BITW(12)
670 #define ICMD_COMP BITW(11)
671 #define ITICKLE BITW(10)
672 #define IDO_STRT BITW(9)
673 #define ITAR_DISC BITW(8)
674 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
675 #define CLR_ALL_INT 0xFFFF
676 #define CLR_ALL_INT_1 0xFF00
678 #define hp_intstat 0x42
680 #define hp_scsisig 0x44
682 #define SCSI_SEL BIT(7)
683 #define SCSI_BSY BIT(6)
684 #define SCSI_REQ BIT(5)
685 #define SCSI_ACK BIT(4)
686 #define SCSI_ATN BIT(3)
687 #define SCSI_CD BIT(2)
688 #define SCSI_MSG BIT(1)
689 #define SCSI_IOBIT BIT(0)
691 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
692 #define S_MSGO_PH (BIT(2)+BIT(1) )
693 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
694 #define S_DATAI_PH ( BIT(0))
695 #define S_DATAO_PH 0x00
696 #define S_ILL_PH ( BIT(1) )
698 #define hp_scsictrl_0 0x45
700 #define SEL_TAR BIT(6)
701 #define ENA_ATN BIT(4)
702 #define ENA_RESEL BIT(2)
703 #define SCSI_RST BIT(1)
704 #define ENA_SCAM_SEL BIT(0)
708 #define hp_portctrl_0 0x46
710 #define SCSI_PORT BIT(7)
711 #define SCSI_INBIT BIT(6)
712 #define DMA_PORT BIT(5)
713 #define DMA_RD BIT(4)
714 #define HOST_PORT BIT(3)
715 #define HOST_WRT BIT(2)
716 #define SCSI_BUS_EN BIT(1)
717 #define START_TO BIT(0)
719 #define hp_scsireset 0x47
721 #define SCSI_INI BIT(6)
722 #define SCAM_EN BIT(5)
723 #define DMA_RESET BIT(3)
724 #define HPSCSI_RESET BIT(2)
725 #define PROG_RESET BIT(1)
726 #define FIFO_CLR BIT(0)
728 #define hp_xfercnt_0 0x48
729 #define hp_xfercnt_2 0x4A
731 #define hp_fifodata_0 0x4C
732 #define hp_addstat 0x4E
734 #define SCAM_TIMER BIT(7)
735 #define SCSI_MODE8 BIT(3)
736 #define SCSI_PAR_ERR BIT(0)
738 #define hp_prgmcnt_0 0x4F
741 #define hp_selfid_0 0x50
742 #define hp_selfid_1 0x51
743 #define hp_arb_id 0x52
746 #define hp_select_id 0x53
749 #define hp_synctarg_base 0x54
750 #define hp_synctarg_12 0x54
751 #define hp_synctarg_13 0x55
752 #define hp_synctarg_14 0x56
753 #define hp_synctarg_15 0x57
755 #define hp_synctarg_8 0x58
756 #define hp_synctarg_9 0x59
757 #define hp_synctarg_10 0x5A
758 #define hp_synctarg_11 0x5B
760 #define hp_synctarg_4 0x5C
761 #define hp_synctarg_5 0x5D
762 #define hp_synctarg_6 0x5E
763 #define hp_synctarg_7 0x5F
765 #define hp_synctarg_0 0x60
766 #define hp_synctarg_1 0x61
767 #define hp_synctarg_2 0x62
768 #define hp_synctarg_3 0x63
770 #define NARROW_SCSI BIT(4)
771 #define DEFAULT_OFFSET 0x0F
773 #define hp_autostart_0 0x64
774 #define hp_autostart_1 0x65
775 #define hp_autostart_3 0x67
779 #define AUTO_IMMED BIT(5)
780 #define SELECT BIT(6)
781 #define END_DATA (BIT(7)+BIT(6))
783 #define hp_gp_reg_0 0x68
784 #define hp_gp_reg_1 0x69
785 #define hp_gp_reg_3 0x6B
787 #define hp_seltimeout 0x6C
790 #define TO_4ms 0x67 /* 3.9959ms */
792 #define TO_5ms 0x03 /* 4.9152ms */
793 #define TO_10ms 0x07 /* 11.xxxms */
794 #define TO_250ms 0x99 /* 250.68ms */
795 #define TO_290ms 0xB1 /* 289.99ms */
797 #define hp_clkctrl_0 0x6D
799 #define PWR_DWN BIT(6)
800 #define ACTdeassert BIT(4)
801 #define CLK_40MHZ (BIT(1) + BIT(0))
803 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
805 #define hp_fiforead 0x6E
806 #define hp_fifowrite 0x6F
808 #define hp_offsetctr 0x70
809 #define hp_xferstat 0x71
811 #define FIFO_EMPTY BIT(6)
813 #define hp_portctrl_1 0x72
815 #define CHK_SCSI_P BIT(3)
816 #define HOST_MODE8 BIT(0)
818 #define hp_xfer_pad 0x73
820 #define ID_UNLOCK BIT(3)
822 #define hp_scsidata_0 0x74
823 #define hp_scsidata_1 0x75
827 #define hp_aramBase 0x80
828 #define BIOS_DATA_OFFSET 0x60
829 #define BIOS_RELATIVE_CARD 0x64
834 #define AR3 (BITW(9) + BITW(8))
835 #define SDATA BITW(10)
838 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
840 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
844 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
846 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
849 #define ADATA_OUT 0x00
850 #define ADATA_IN BITW(8)
851 #define ACOMMAND BITW(10)
852 #define ASTATUS (BITW(10)+BITW(8))
853 #define AMSG_OUT (BITW(10)+BITW(9))
854 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
857 #define BRH_OP BITW(13) /* Branch */
861 #define EQUAL BITW(8)
862 #define NOT_EQ BITW(9)
864 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
867 #define FIFO_0 BITW(10)
870 #define MPM_OP BITW(15) /* Match phase and move data */
873 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
876 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
881 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
891 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
893 #define SSI_OP (BITW(15)+BITW(11))
896 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
897 #define SSI_IDO_STRT (IDO_STRT >> 8)
899 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
900 #define SSI_ITICKLE (ITICKLE >> 8)
902 #define SSI_IUNKWN (IUNKWN >> 8)
903 #define SSI_INO_CC (IUNKWN >> 8)
904 #define SSI_IRFAIL (IUNKWN >> 8)
907 #define NP 0x10 /*Next Phase */
908 #define NTCMD 0x02 /*Non- Tagged Command start */
909 #define CMDPZ 0x04 /*Command phase */
910 #define DINT 0x12 /*Data Out/In interrupt */
911 #define DI 0x13 /*Data Out */
912 #define DC 0x19 /*Disconnect Message */
913 #define ST 0x1D /*Status Phase */
914 #define UNKNWN 0x24 /*Unknown bus action */
915 #define CC 0x25 /*Command Completion failure */
916 #define TICK 0x26 /*New target reselected us. */
917 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
920 #define ID_MSG_STRT hp_aramBase + 0x00
921 #define NON_TAG_ID_MSG hp_aramBase + 0x06
922 #define CMD_STRT hp_aramBase + 0x08
923 #define SYNC_MSGS hp_aramBase + 0x08
929 #define TAG_STRT 0x00
930 #define DISCONNECT_START 0x10/2
931 #define END_DATA_START 0x14/2
932 #define CMD_ONLY_STRT CMDPZ/2
933 #define SELCHK_STRT SELCHK/2
943 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
944 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
946 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
948 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
950 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
951 WR_HARP32(port,hp_xfercnt_0,count),\
952 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
954 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
956 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
957 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
960 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
961 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
965 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
966 WR_HARPOON(port+hp_scsireset, 0x00))
968 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
969 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
971 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
972 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
974 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
975 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
977 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
978 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
983 static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag);
984 static void FPT_ssel(ULONG port, unsigned char p_card);
985 static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard);
986 static void FPT_shandem(ULONG port, unsigned char p_card,PSCCB pCurrSCCB);
987 static void FPT_stsyncn(ULONG port, unsigned char p_card);
988 static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset);
989 static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
990 PSCCBMgr_tar_info currTar_Info);
991 static void FPT_sresb(ULONG port, unsigned char p_card);
992 static void FPT_sxfrp(ULONG p_port, unsigned char p_card);
993 static void FPT_schkdd(ULONG port, unsigned char p_card);
994 static unsigned char FPT_RdStack(ULONG port, unsigned char index);
995 static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data);
996 static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort);
998 static void FPT_SendMsg(ULONG port, unsigned char message);
999 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
1000 unsigned char error_code);
1002 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
1003 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1005 static unsigned char FPT_siwidn(ULONG port, unsigned char p_card);
1006 static void FPT_stwidn(ULONG port, unsigned char p_card);
1007 static void FPT_siwidr(ULONG port, unsigned char width);
1010 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1011 static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
1012 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1013 unsigned char p_card);
1014 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1015 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1016 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1017 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
1018 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1019 static USHORT FPT_CalcCrc16(unsigned char buffer[]);
1020 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1023 static void FPT_Wait1Second(ULONG p_port);
1024 static void FPT_Wait(ULONG p_port, unsigned char p_delay);
1025 static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode);
1026 static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1027 static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1028 static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1029 static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, USHORT ee_addr);
1033 static void FPT_phaseDataOut(ULONG port, unsigned char p_card);
1034 static void FPT_phaseDataIn(ULONG port, unsigned char p_card);
1035 static void FPT_phaseCommand(ULONG port, unsigned char p_card);
1036 static void FPT_phaseStatus(ULONG port, unsigned char p_card);
1037 static void FPT_phaseMsgOut(ULONG port, unsigned char p_card);
1038 static void FPT_phaseMsgIn(ULONG port, unsigned char p_card);
1039 static void FPT_phaseIllegal(ULONG port, unsigned char p_card);
1041 static void FPT_phaseDecode(ULONG port, unsigned char p_card);
1042 static void FPT_phaseChkFifo(ULONG port, unsigned char p_card);
1043 static void FPT_phaseBusFree(ULONG p_port, unsigned char p_card);
1048 static void FPT_XbowInit(ULONG port, unsigned char scamFlg);
1049 static void FPT_BusMasterInit(ULONG p_port);
1050 static void FPT_DiagEEPROM(ULONG p_port);
1055 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1056 static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1057 static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1058 static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB);
1059 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1062 static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
1063 PSCCBcard pCurrCard, USHORT p_int);
1065 static void FPT_SccbMgrTableInitAll(void);
1066 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1067 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1071 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1073 static int FPT_scarb(ULONG p_port, unsigned char p_sel_type);
1074 static void FPT_scbusf(ULONG p_port);
1075 static void FPT_scsel(ULONG p_port);
1076 static void FPT_scasid(unsigned char p_card, ULONG p_port);
1077 static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data);
1078 static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[]);
1079 static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[]);
1080 static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit);
1081 static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit);
1082 static unsigned char FPT_scvalq(unsigned char p_quintet);
1083 static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id);
1084 static void FPT_scwtsel(ULONG p_port);
1085 static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id);
1086 static void FPT_scsavdi(unsigned char p_card, ULONG p_port);
1087 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1090 static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card);
1091 static void FPT_autoLoadDefaultMap(ULONG p_port);
1096 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1097 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1098 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1099 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1102 static unsigned char FPT_mbCards = 0;
1103 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1104 ' ', 'B', 'T', '-', '9', '3', '0', \
1105 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1106 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1108 static USHORT FPT_default_intena = 0;
1111 static void (*FPT_s_PhaseTbl[8]) (ULONG, unsigned char)= { 0 };
1114 /*---------------------------------------------------------------------
1116 * Function: FlashPoint_ProbeHostAdapter
1118 * Description: Setup and/or Search for cards and return info to caller.
1120 *---------------------------------------------------------------------*/
1122 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1124 static unsigned char first_time = 1;
1126 unsigned char i,j,id,ScamFlg;
1127 USHORT temp,temp2,temp3,temp4,temp5,temp6;
1129 PNVRamInfo pCurrNvRam;
1131 ioport = pCardInfo->si_baseaddr;
1134 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1135 return((int)FAILURE);
1137 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1138 return((int)FAILURE);
1140 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1141 return((int)FAILURE);
1143 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1144 return((int)FAILURE);
1147 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1149 /* For new Harpoon then check for sub_device ID LSB
1150 the bits(0-3) must be all ZERO for compatible with
1151 current version of SCCBMgr, else skip this Harpoon
1154 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1155 return((int)FAILURE);
1160 FPT_SccbMgrTableInitAll();
1165 if(FPT_RdStack(ioport, 0) != 0x00) {
1166 if(FPT_ChkIfChipInitialized(ioport) == 0)
1169 WR_HARPOON(ioport+hp_semaphore, 0x00);
1170 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1171 FPT_DiagEEPROM(ioport);
1175 if(FPT_mbCards < MAX_MB_CARDS) {
1176 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1178 pCurrNvRam->niBaseAddr = ioport;
1179 FPT_RNVRamData(pCurrNvRam);
1181 return((int) FAILURE);
1186 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1187 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1190 pCardInfo->si_id = pCurrNvRam->niAdapId;
1192 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1193 (unsigned char)0x0FF);
1195 pCardInfo->si_lun = 0x00;
1196 pCardInfo->si_fw_revision = ORION_FW_REV;
1203 for (id = 0; id < (16/2); id++) {
1206 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1207 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1208 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1210 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1212 for (i = 0; i < 2; temp >>=8,i++) {
1221 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1222 temp6 |= 0x8000; /* Fall through */
1223 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1224 temp5 |= 0x8000; /* Fall through */
1225 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1226 temp2 |= 0x8000; /* Fall through */
1227 case AUTO_RATE_00: /* Asynchronous */
1231 if (temp & DISC_ENABLE_BIT)
1234 if (temp & WIDE_NEGO_BIT)
1240 pCardInfo->si_per_targ_init_sync = temp2;
1241 pCardInfo->si_per_targ_no_disc = temp3;
1242 pCardInfo->si_per_targ_wide_nego = temp4;
1243 pCardInfo->si_per_targ_fast_nego = temp5;
1244 pCardInfo->si_per_targ_ultra_nego = temp6;
1247 i = pCurrNvRam->niSysConf;
1249 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1252 ScamFlg = pCurrNvRam->niScamConf;
1254 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1256 pCardInfo->si_flags = 0x0000;
1259 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1262 pCardInfo->si_flags |= SOFT_RESET;
1265 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1267 if (ScamFlg & SCAM_ENABLED)
1268 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1270 if (ScamFlg & SCAM_LEVEL2)
1271 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1273 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1275 j |= SCSI_TERM_ENA_L;
1277 WR_HARPOON(ioport+hp_bm_ctrl, j );
1279 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1281 j |= SCSI_TERM_ENA_H;
1283 WR_HARPOON(ioport+hp_ee_ctrl, j );
1285 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1287 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1289 pCardInfo->si_card_family = HARPOON_FAMILY;
1290 pCardInfo->si_bustype = BUSTYPE_PCI;
1293 pCardInfo->si_card_model[0] = '9';
1294 switch(pCurrNvRam->niModel & 0x0f){
1296 pCardInfo->si_card_model[1] = '3';
1297 pCardInfo->si_card_model[2] = '0';
1300 pCardInfo->si_card_model[1] = '5';
1301 pCardInfo->si_card_model[2] = '0';
1304 pCardInfo->si_card_model[1] = '3';
1305 pCardInfo->si_card_model[2] = '2';
1308 pCardInfo->si_card_model[1] = '5';
1309 pCardInfo->si_card_model[2] = '2';
1313 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1314 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1315 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1317 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1318 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1321 if (pCardInfo->si_card_model[1] == '3')
1323 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1324 pCardInfo->si_flags |= LOW_BYTE_TERM;
1326 else if (pCardInfo->si_card_model[2] == '0')
1328 temp = RD_HARPOON(ioport+hp_xfer_pad);
1329 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1330 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1331 pCardInfo->si_flags |= LOW_BYTE_TERM;
1332 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1333 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1334 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1335 WR_HARPOON(ioport+hp_xfer_pad, temp);
1339 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1340 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1341 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1342 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1344 for (i = 0; i < 8; i++)
1347 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1349 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1350 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1352 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1353 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1354 if (!(temp3 & BIT(7)))
1355 pCardInfo->si_flags |= LOW_BYTE_TERM;
1356 if (!(temp3 & BIT(6)))
1357 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1361 ARAM_ACCESS(ioport);
1363 for ( i = 0; i < 4; i++ ) {
1365 pCardInfo->si_XlatInfo[i] =
1366 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1369 /* return with -1 if no sort, else return with
1370 logical card number sorted by BIOS (zero-based) */
1372 pCardInfo->si_relative_cardnum =
1373 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1375 SGRAM_ACCESS(ioport);
1377 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1378 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1379 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1380 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1381 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1382 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1383 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1384 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1386 pCardInfo->si_present = 0x01;
1392 /*---------------------------------------------------------------------
1394 * Function: FlashPoint_HardwareResetHostAdapter
1396 * Description: Setup adapter for normal operation (hard reset).
1398 *---------------------------------------------------------------------*/
1400 static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1402 PSCCBcard CurrCard = NULL;
1403 PNVRamInfo pCurrNvRam;
1404 unsigned char i,j,thisCard, ScamFlg;
1405 USHORT temp,sync_bit_map,id;
1408 ioport = pCardInfo->si_baseaddr;
1410 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1412 if (thisCard == MAX_CARDS) {
1417 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1419 CurrCard = &FPT_BL_Card[thisCard];
1420 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1424 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1426 FPT_BL_Card[thisCard].ioPort = ioport;
1427 CurrCard = &FPT_BL_Card[thisCard];
1430 for(i = 0; i < FPT_mbCards; i++){
1431 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1432 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1434 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1435 CurrCard->cardIndex = thisCard;
1436 CurrCard->cardInfo = pCardInfo;
1442 pCurrNvRam = CurrCard->pNvRamInfo;
1445 ScamFlg = pCurrNvRam->niScamConf;
1448 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1452 FPT_BusMasterInit(ioport);
1453 FPT_XbowInit(ioport, ScamFlg);
1455 FPT_autoLoadDefaultMap(ioport);
1458 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1460 WR_HARPOON(ioport+hp_selfid_0, id);
1461 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1462 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1463 CurrCard->ourId = pCardInfo->si_id;
1465 i = (unsigned char) pCardInfo->si_flags;
1466 if (i & SCSI_PARITY_ENA)
1467 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1469 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1470 if (i & LOW_BYTE_TERM)
1471 j |= SCSI_TERM_ENA_L;
1472 WR_HARPOON(ioport+hp_bm_ctrl, j);
1474 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1475 if (i & HIGH_BYTE_TERM)
1476 j |= SCSI_TERM_ENA_H;
1477 WR_HARPOON(ioport+hp_ee_ctrl, j );
1480 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1482 FPT_sresb(ioport,thisCard);
1484 FPT_scini(thisCard, pCardInfo->si_id, 0);
1489 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1490 CurrCard->globalFlags |= F_NO_FILTER;
1493 if(pCurrNvRam->niSysConf & 0x10)
1494 CurrCard->globalFlags |= F_GREEN_PC;
1497 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1498 CurrCard->globalFlags |= F_GREEN_PC;
1501 /* Set global flag to indicate Re-Negotiation to be done on all
1504 if(pCurrNvRam->niScsiConf & 0x04)
1505 CurrCard->globalFlags |= F_DO_RENEGO;
1508 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1509 CurrCard->globalFlags |= F_DO_RENEGO;
1513 if(pCurrNvRam->niScsiConf & 0x08)
1514 CurrCard->globalFlags |= F_CONLUN_IO;
1517 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1518 CurrCard->globalFlags |= F_CONLUN_IO;
1522 temp = pCardInfo->si_per_targ_no_disc;
1524 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1527 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1530 sync_bit_map = 0x0001;
1532 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1535 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1536 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1537 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1539 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1541 for (i = 0; i < 2; temp >>=8,i++) {
1543 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1545 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1549 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1550 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1551 (unsigned char)(temp & ~EE_SYNC_MASK);
1554 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1557 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1559 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1563 else { /* NARROW SCSI */
1564 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1575 WR_HARPOON((ioport+hp_semaphore),
1576 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1578 return((ULONG)CurrCard);
1581 static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
1588 PNVRamInfo pCurrNvRam;
1590 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1597 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1599 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1600 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1602 portBase = pCurrNvRam->niBaseAddr;
1604 for(i = 0; i < MAX_SCSI_TAR; i++){
1605 regOffset = hp_aramBase + 64 + i*4;
1606 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1607 scamData = *pScamTbl;
1608 WR_HARP32(portBase, regOffset, scamData);
1612 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1617 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1625 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1626 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1627 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1628 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1629 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1631 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1632 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1634 portBase = pNvRamInfo->niBaseAddr;
1636 for(i = 0; i < MAX_SCSI_TAR; i++){
1637 regOffset = hp_aramBase + 64 + i*4;
1638 RD_HARP32(portBase, regOffset, scamData);
1639 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1640 *pScamTbl = scamData;
1645 static unsigned char FPT_RdStack(ULONG portBase, unsigned char index)
1647 WR_HARPOON(portBase + hp_stack_addr, index);
1648 return(RD_HARPOON(portBase + hp_stack_data));
1651 static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data)
1653 WR_HARPOON(portBase + hp_stack_addr, index);
1654 WR_HARPOON(portBase + hp_stack_data, data);
1658 static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort)
1660 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1662 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1665 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1666 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1671 /*---------------------------------------------------------------------
1673 * Function: FlashPoint_StartCCB
1675 * Description: Start a command pointed to by p_Sccb. When the
1676 * command is completed it will be returned via the
1677 * callback function.
1679 *---------------------------------------------------------------------*/
1680 static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
1683 unsigned char thisCard, lun;
1685 CALL_BK_FN callback;
1687 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1688 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1690 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1693 p_Sccb->HostStatus = SCCB_COMPLETE;
1694 p_Sccb->SccbStatus = SCCB_ERROR;
1695 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1702 FPT_sinits(p_Sccb,thisCard);
1705 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1707 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1708 | SCCB_MGR_ACTIVE));
1710 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1712 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1713 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1717 ((PSCCBcard)pCurrCard)->cmdCounter++;
1719 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1721 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1723 if(p_Sccb->OperationCode == RESET_COMMAND)
1725 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1726 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1727 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1728 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1732 FPT_queueAddSccb(p_Sccb,thisCard);
1736 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1738 if(p_Sccb->OperationCode == RESET_COMMAND)
1740 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1741 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1742 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1743 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1747 FPT_queueAddSccb(p_Sccb,thisCard);
1753 MDISABLE_INT(ioport);
1755 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1756 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1760 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1761 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1762 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1765 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1766 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1771 if(p_Sccb->OperationCode == RESET_COMMAND)
1773 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1774 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1775 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1776 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1780 FPT_queueAddSccb(p_Sccb,thisCard);
1785 MENABLE_INT(ioport);
1791 /*---------------------------------------------------------------------
1793 * Function: FlashPoint_AbortCCB
1795 * Description: Abort the command pointed to by p_Sccb. When the
1796 * command is completed it will be returned via the
1797 * callback function.
1799 *---------------------------------------------------------------------*/
1800 static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
1804 unsigned char thisCard;
1805 CALL_BK_FN callback;
1808 PSCCBMgr_tar_info currTar_Info;
1811 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1813 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1815 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1818 if (FPT_queueFindSccb(p_Sccb,thisCard))
1821 ((PSCCBcard)pCurrCard)->cmdCounter--;
1823 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1824 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1825 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1827 p_Sccb->SccbStatus = SCCB_ABORT;
1828 callback = p_Sccb->SccbCallback;
1836 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1838 p_Sccb->SccbStatus = SCCB_ABORT;
1846 TID = p_Sccb->TargID;
1849 if(p_Sccb->Sccb_tag)
1851 MDISABLE_INT(ioport);
1852 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1854 p_Sccb->SccbStatus = SCCB_ABORT;
1855 p_Sccb->Sccb_scsistat = ABORT_ST;
1856 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1858 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1860 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1861 FPT_ssel(ioport, thisCard);
1865 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1866 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1867 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1868 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1871 MENABLE_INT(ioport);
1876 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1878 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1881 p_Sccb->SccbStatus = SCCB_ABORT;
1892 /*---------------------------------------------------------------------
1894 * Function: FlashPoint_InterruptPending
1896 * Description: Do a quick check to determine if there is a pending
1897 * interrupt for this card and disable the IRQ Pin if so.
1899 *---------------------------------------------------------------------*/
1900 static unsigned char FlashPoint_InterruptPending(ULONG pCurrCard)
1904 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1906 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1918 /*---------------------------------------------------------------------
1920 * Function: FlashPoint_HandleInterrupt
1922 * Description: This is our entry point when an interrupt is generated
1923 * by the card and the upper level driver passes it on to
1926 *---------------------------------------------------------------------*/
1927 static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
1930 unsigned char thisCard,result,bm_status, bm_int_st;
1932 unsigned char i, target;
1935 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1936 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1938 MDISABLE_INT(ioport);
1940 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1941 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1945 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1947 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1951 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1953 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1954 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1955 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1960 MENABLE_INT(ioport);
1966 else if (hp_int & ICMD_COMP) {
1968 if ( !(hp_int & BUS_FREE) ) {
1969 /* Wait for the BusFree before starting a new command. We
1970 must also check for being reselected since the BusFree
1971 may not show up if another device reselects us in 1.5us or
1972 less. SRR Wednesday, 3/8/1995.
1974 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1977 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1979 FPT_phaseChkFifo(ioport, thisCard);
1981 /* WRW_HARPOON((ioport+hp_intstat),
1982 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1985 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1987 FPT_autoCmdCmplt(ioport,thisCard);
1992 else if (hp_int & ITAR_DISC)
1995 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1997 FPT_phaseChkFifo(ioport, thisCard);
2001 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2003 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2004 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2006 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2009 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2010 FPT_queueDisconnect(currSCCB,thisCard);
2012 /* Wait for the BusFree before starting a new command. We
2013 must also check for being reselected since the BusFree
2014 may not show up if another device reselects us in 1.5us or
2015 less. SRR Wednesday, 3/8/1995.
2017 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2018 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2019 RD_HARPOON((ioport+hp_scsisig)) ==
2020 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2023 The additional loop exit condition above detects a timing problem
2024 with the revision D/E harpoon chips. The caller should reset the
2025 host adapter to recover when 0xFE is returned.
2027 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2029 MENABLE_INT(ioport);
2033 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2036 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2041 else if (hp_int & RSEL) {
2043 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2045 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2047 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2049 FPT_phaseChkFifo(ioport, thisCard);
2052 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2054 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2055 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2056 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2059 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2060 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2061 FPT_queueDisconnect(currSCCB,thisCard);
2064 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2065 FPT_phaseDecode(ioport,thisCard);
2070 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2073 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2074 FPT_phaseDecode(ioport,thisCard);
2079 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2081 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2082 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2084 FPT_phaseDecode(ioport,thisCard);
2088 /* Harpoon problem some SCSI target device respond to selection
2089 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2090 to latch the correct Target ID into reg. x53.
2091 The work around require to correct this reg. But when write to this
2092 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2093 need to read this reg first then restore it later. After update to 0x53 */
2095 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2096 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2097 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2098 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2099 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2100 WR_HARPOON(ioport+hp_fifowrite, i);
2101 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2105 else if (hp_int & XFER_CNT_0) {
2107 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2109 FPT_schkdd(ioport,thisCard);
2114 else if (hp_int & BUS_FREE) {
2116 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2118 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2120 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2123 FPT_phaseBusFree(ioport,thisCard);
2127 else if (hp_int & ITICKLE) {
2129 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2130 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2135 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2138 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2141 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2143 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2146 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2147 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2148 FPT_ssel(ioport,thisCard);
2157 MENABLE_INT(ioport);
2162 /*---------------------------------------------------------------------
2164 * Function: Sccb_bad_isr
2166 * Description: Some type of interrupt has occurred which is slightly
2167 * out of the ordinary. We will now decode it fully, in
2168 * this routine. This is broken up in an attempt to save
2171 *---------------------------------------------------------------------*/
2172 static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
2173 PSCCBcard pCurrCard, USHORT p_int)
2175 unsigned char temp, ScamFlg;
2176 PSCCBMgr_tar_info currTar_Info;
2177 PNVRamInfo pCurrNvRam;
2180 if (RD_HARPOON(p_port+hp_ext_status) &
2181 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2184 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2187 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2190 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2193 WR_HARPOON(p_port+hp_pci_stat_cfg,
2194 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2196 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2200 if (pCurrCard->currentSCCB != NULL)
2203 if (!pCurrCard->currentSCCB->HostStatus)
2204 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2206 FPT_sxfrp(p_port,p_card);
2208 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2209 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2210 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2211 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2213 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2215 FPT_phaseDecode(p_port,p_card);
2221 else if (p_int & RESET)
2224 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2225 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2226 if (pCurrCard->currentSCCB != NULL) {
2228 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2230 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2234 DISABLE_AUTO(p_port);
2236 FPT_sresb(p_port,p_card);
2238 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2240 pCurrNvRam = pCurrCard->pNvRamInfo;
2242 ScamFlg = pCurrNvRam->niScamConf;
2245 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2248 FPT_XbowInit(p_port, ScamFlg);
2250 FPT_scini(p_card, pCurrCard->ourId, 0);
2256 else if (p_int & FIFO) {
2258 WRW_HARPOON((p_port+hp_intstat), FIFO);
2260 if (pCurrCard->currentSCCB != NULL)
2261 FPT_sxfrp(p_port,p_card);
2264 else if (p_int & TIMEOUT)
2267 DISABLE_AUTO(p_port);
2269 WRW_HARPOON((p_port+hp_intstat),
2270 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2272 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2275 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2276 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2277 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2278 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2280 currTar_Info->TarLUNBusy[0] = 0;
2283 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2285 currTar_Info->TarSyncCtrl = 0;
2286 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2289 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2291 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2294 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2296 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2300 else if (p_int & SCAM_SEL)
2303 FPT_scarb(p_port,LEVEL2_TAR);
2305 FPT_scasid(p_card, p_port);
2309 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2316 /*---------------------------------------------------------------------
2318 * Function: SccbMgrTableInit
2320 * Description: Initialize all Sccb manager data structures.
2322 *---------------------------------------------------------------------*/
2324 static void FPT_SccbMgrTableInitAll()
2326 unsigned char thisCard;
2328 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2330 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2332 FPT_BL_Card[thisCard].ioPort = 0x00;
2333 FPT_BL_Card[thisCard].cardInfo = NULL;
2334 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2335 FPT_BL_Card[thisCard].ourId = 0x00;
2336 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2341 /*---------------------------------------------------------------------
2343 * Function: SccbMgrTableInit
2345 * Description: Initialize all Sccb manager data structures.
2347 *---------------------------------------------------------------------*/
2349 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2351 unsigned char scsiID, qtag;
2353 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2355 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2358 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2360 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2361 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2362 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2365 pCurrCard->scanIndex = 0x00;
2366 pCurrCard->currentSCCB = NULL;
2367 pCurrCard->globalFlags = 0x00;
2368 pCurrCard->cmdCounter = 0x00;
2369 pCurrCard->tagQ_Lst = 0x01;
2370 pCurrCard->discQCount = 0;
2376 /*---------------------------------------------------------------------
2378 * Function: SccbMgrTableInit
2380 * Description: Initialize all Sccb manager data structures.
2382 *---------------------------------------------------------------------*/
2384 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2387 unsigned char lun, qtag;
2388 PSCCBMgr_tar_info currTar_Info;
2390 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2392 currTar_Info->TarSelQ_Cnt = 0;
2393 currTar_Info->TarSyncCtrl = 0;
2395 currTar_Info->TarSelQ_Head = NULL;
2396 currTar_Info->TarSelQ_Tail = NULL;
2397 currTar_Info->TarTagQ_Cnt = 0;
2398 currTar_Info->TarLUN_CA = 0;
2401 for (lun = 0; lun < MAX_LUN; lun++)
2403 currTar_Info->TarLUNBusy[lun] = 0;
2404 currTar_Info->LunDiscQ_Idx[lun] = 0;
2407 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2409 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2411 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2413 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2414 FPT_BL_Card[p_card].discQCount--;
2421 /*---------------------------------------------------------------------
2425 * Description: Read in a message byte from the SCSI bus, and check
2426 * for a parity error.
2428 *---------------------------------------------------------------------*/
2430 static unsigned char FPT_sfm(ULONG port, PSCCB pCurrSCCB)
2432 unsigned char message;
2436 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2437 (TimeOutLoop++ < 20000) ){}
2440 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2442 message = RD_HARPOON(port+hp_scsidata_0);
2444 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2447 if (TimeOutLoop > 20000)
2448 message = 0x00; /* force message byte = 0 if Time Out on Req */
2450 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2451 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2453 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2454 WR_HARPOON(port+hp_xferstat, 0);
2455 WR_HARPOON(port+hp_fiforead, 0);
2456 WR_HARPOON(port+hp_fifowrite, 0);
2457 if (pCurrSCCB != NULL)
2459 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2464 ACCEPT_MSG_ATN(port);
2466 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2467 (TimeOutLoop++ < 20000) ){}
2468 if (TimeOutLoop > 20000)
2470 WRW_HARPOON((port+hp_intstat), PARITY);
2473 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2475 WRW_HARPOON((port+hp_intstat), PARITY);
2478 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2480 RD_HARPOON(port+hp_scsidata_0);
2482 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2487 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2488 WR_HARPOON(port+hp_xferstat, 0);
2489 WR_HARPOON(port+hp_fiforead, 0);
2490 WR_HARPOON(port+hp_fifowrite, 0);
2495 /*---------------------------------------------------------------------
2497 * Function: FPT_ssel
2499 * Description: Load up automation and select target device.
2501 *---------------------------------------------------------------------*/
2503 static void FPT_ssel(ULONG port, unsigned char p_card)
2506 unsigned char auto_loaded, i, target, *theCCB;
2511 PSCCBMgr_tar_info currTar_Info;
2512 unsigned char lastTag, lun;
2514 CurrCard = &FPT_BL_Card[p_card];
2515 currSCCB = CurrCard->currentSCCB;
2516 target = currSCCB->TargID;
2517 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2518 lastTag = CurrCard->tagQ_Lst;
2523 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2524 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2526 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2527 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2529 lun = currSCCB->Lun;
2534 if (CurrCard->globalFlags & F_TAG_STARTED)
2536 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2538 if ((currTar_Info->TarLUN_CA == 0)
2539 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2543 if (currTar_Info->TarTagQ_Cnt !=0)
2545 currTar_Info->TarLUNBusy[lun] = 1;
2546 FPT_queueSelectFail(CurrCard,p_card);
2552 currTar_Info->TarLUNBusy[lun] = 1;
2555 } /*End non-tagged */
2558 currTar_Info->TarLUNBusy[lun] = 1;
2561 } /*!Use cmd Q Tagged */
2564 if (currTar_Info->TarLUN_CA == 1)
2566 FPT_queueSelectFail(CurrCard,p_card);
2571 currTar_Info->TarLUNBusy[lun] = 1;
2573 } /*else use cmd Q tagged */
2575 } /*if glob tagged started */
2578 currTar_Info->TarLUNBusy[lun] = 1;
2583 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2584 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2585 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2587 if(CurrCard->discQCount >= QUEUE_DEPTH)
2589 currTar_Info->TarLUNBusy[lun] = 1;
2590 FPT_queueSelectFail(CurrCard,p_card);
2594 for (i = 1; i < QUEUE_DEPTH; i++)
2596 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2597 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2599 CurrCard->tagQ_Lst = lastTag;
2600 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2601 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2602 CurrCard->discQCount++;
2606 if(i == QUEUE_DEPTH)
2608 currTar_Info->TarLUNBusy[lun] = 1;
2609 FPT_queueSelectFail(CurrCard,p_card);
2619 WR_HARPOON(port+hp_select_id, target);
2620 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2622 if (currSCCB->OperationCode == RESET_COMMAND) {
2623 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2624 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2626 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2628 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2630 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2632 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2634 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2636 currTar_Info->TarSyncCtrl = 0;
2637 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2640 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2642 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2645 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2646 FPT_SccbMgrTableInitTarget(p_card, target);
2650 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2652 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2653 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2655 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2657 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2658 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2659 >> 6) | (unsigned char)0x20)));
2660 WRW_HARPOON((port+SYNC_MSGS+2),
2661 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2662 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2664 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2669 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2670 auto_loaded = FPT_siwidn(port,p_card);
2671 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2674 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2675 == SYNC_SUPPORTED)) {
2676 auto_loaded = FPT_sisyncn(port,p_card, 0);
2677 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2684 if (currSCCB->ControlByte & F_USE_CMD_Q)
2687 CurrCard->globalFlags |= F_TAG_STARTED;
2689 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2692 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2694 /* Fix up the start instruction with a jump to
2695 Non-Tag-CMD handling */
2696 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2698 WRW_HARPOON((port+NON_TAG_ID_MSG),
2699 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2701 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2703 /* Setup our STATE so we know what happend when
2704 the wheels fall off. */
2705 currSCCB->Sccb_scsistat = SELECT_ST;
2707 currTar_Info->TarLUNBusy[lun] = 1;
2712 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2714 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2715 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2716 >> 6) | (unsigned char)0x20)));
2718 for (i = 1; i < QUEUE_DEPTH; i++)
2720 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2721 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2723 WRW_HARPOON((port+ID_MSG_STRT+6),
2724 (MPM_OP+AMSG_OUT+lastTag));
2725 CurrCard->tagQ_Lst = lastTag;
2726 currSCCB->Sccb_tag = lastTag;
2727 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2728 CurrCard->discQCount++;
2734 if ( i == QUEUE_DEPTH )
2736 currTar_Info->TarLUNBusy[lun] = 1;
2737 FPT_queueSelectFail(CurrCard,p_card);
2742 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2744 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2751 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2753 WRW_HARPOON((port+NON_TAG_ID_MSG),
2754 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2756 currSCCB->Sccb_scsistat = SELECT_ST;
2758 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2762 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2764 cdb_reg = port + CMD_STRT;
2766 for (i=0; i < currSCCB->CdbLength; i++)
2768 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2773 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2774 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2778 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2779 WR_HARPOON(port+hp_xferstat, 0x00);
2781 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2783 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2786 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2788 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2793 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2794 auto_loaded |= AUTO_IMMED; */
2795 auto_loaded = AUTO_IMMED;
2799 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2806 /*---------------------------------------------------------------------
2808 * Function: FPT_sres
2810 * Description: Hookup the correct CCB and handle the incoming messages.
2812 *---------------------------------------------------------------------*/
2814 static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard)
2817 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2820 PSCCBMgr_tar_info currTar_Info;
2826 if(pCurrCard->currentSCCB != NULL)
2828 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2832 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2835 currSCCB = pCurrCard->currentSCCB;
2836 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2838 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2839 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2841 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2843 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2844 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2846 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2847 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2849 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2850 if(currSCCB->Sccb_scsistat != ABORT_ST)
2852 pCurrCard->discQCount--;
2853 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2859 currTar_Info->TarLUNBusy[0] = 0;
2860 if(currSCCB->Sccb_tag)
2862 if(currSCCB->Sccb_scsistat != ABORT_ST)
2864 pCurrCard->discQCount--;
2865 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2869 if(currSCCB->Sccb_scsistat != ABORT_ST)
2871 pCurrCard->discQCount--;
2872 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2877 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2880 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2883 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2884 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2891 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2895 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2897 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2900 WRW_HARPOON((port+hp_intstat), PHASE);
2905 WRW_HARPOON((port+hp_intstat), PHASE);
2906 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2909 message = FPT_sfm(port,pCurrCard->currentSCCB);
2913 if (message <= (0x80 | LUN_MASK))
2915 lun = message & (unsigned char)LUN_MASK;
2917 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2919 if (currTar_Info->TarTagQ_Cnt != 0)
2922 if (!(currTar_Info->TarLUN_CA))
2924 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2927 message = FPT_sfm(port,pCurrCard->currentSCCB);
2938 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2946 } /*End Q cnt != 0 */
2948 } /*End Tag cmds supported! */
2950 } /*End valid ID message. */
2955 ACCEPT_MSG_ATN(port);
2958 } /* End good id message. */
2968 ACCEPT_MSG_ATN(port);
2970 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2971 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2972 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2980 if(msgRetryCount == 1)
2982 FPT_SendMsg(port, SMPARITY);
2986 FPT_SendMsg(port, SMDEV_RESET);
2988 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2990 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2993 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2997 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
3000 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
3004 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3005 FPT_SccbMgrTableInitTarget(p_card,our_target);
3009 }while(message == 0);
3013 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3014 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3016 currTar_Info->TarLUNBusy[lun] = 1;
3017 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3018 if(pCurrCard->currentSCCB != NULL)
3024 ACCEPT_MSG_ATN(port);
3029 currTar_Info->TarLUNBusy[0] = 1;
3034 if (pCurrCard->discQ_Tbl[tag] != NULL)
3036 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3037 currTar_Info->TarTagQ_Cnt--;
3042 ACCEPT_MSG_ATN(port);
3046 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3047 if(pCurrCard->currentSCCB != NULL)
3053 ACCEPT_MSG_ATN(port);
3058 if(pCurrCard->currentSCCB != NULL)
3060 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3062 /* During Abort Tag command, the target could have got re-selected
3063 and completed the command. Check the select Q and remove the CCB
3064 if it is in the Select Q */
3065 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3070 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3071 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3072 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3075 static void FPT_SendMsg(ULONG port, unsigned char message)
3077 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3079 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3082 WRW_HARPOON((port+hp_intstat), PHASE);
3087 WRW_HARPOON((port+hp_intstat), PHASE);
3088 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3090 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3093 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3095 WR_HARPOON(port+hp_scsidata_0,message);
3097 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3101 WR_HARPOON(port+hp_portctrl_0, 0x00);
3103 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3104 (message == SMABORT_TAG) )
3106 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3108 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3110 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3116 /*---------------------------------------------------------------------
3118 * Function: FPT_sdecm
3120 * Description: Determine the proper responce to the message from the
3123 *---------------------------------------------------------------------*/
3124 static void FPT_sdecm(unsigned char message, ULONG port, unsigned char p_card)
3128 PSCCBMgr_tar_info currTar_Info;
3130 CurrCard = &FPT_BL_Card[p_card];
3131 currSCCB = CurrCard->currentSCCB;
3133 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3135 if (message == SMREST_DATA_PTR)
3137 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3139 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3141 FPT_hostDataXferRestart(currSCCB);
3145 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3148 else if (message == SMCMD_COMP)
3152 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3154 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3155 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3162 else if ((message == SMNO_OP) || (message >= SMIDENT)
3163 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3167 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3170 else if (message == SMREJECT)
3173 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3174 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3175 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3176 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3179 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3184 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3185 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3187 if(currSCCB->Lun == 0x00)
3189 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3192 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3194 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3197 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3201 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3202 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3204 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3208 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3210 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3211 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3214 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3215 CurrCard->discQCount--;
3216 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3217 currSCCB->Sccb_tag = 0x00;
3222 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3226 if(currSCCB->Lun == 0x00)
3228 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3229 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3236 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3237 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3238 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3240 currTar_Info->TarLUNBusy[0] = 1;
3243 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3245 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3254 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3255 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3257 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3259 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3264 else if (message == SMEXT)
3268 FPT_shandem(port,p_card,currSCCB);
3271 else if (message == SMIGNORWR)
3274 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3276 message = FPT_sfm(port,currSCCB);
3278 if(currSCCB->Sccb_scsimsg != SMPARITY)
3280 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3287 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3288 currSCCB->Sccb_scsimsg = SMREJECT;
3290 ACCEPT_MSG_ATN(port);
3291 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3296 /*---------------------------------------------------------------------
3298 * Function: FPT_shandem
3300 * Description: Decide what to do with the extended message.
3302 *---------------------------------------------------------------------*/
3303 static void FPT_shandem(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
3305 unsigned char length,message;
3307 length = FPT_sfm(port,pCurrSCCB);
3312 message = FPT_sfm(port,pCurrSCCB);
3316 if (message == SMSYNC)
3323 FPT_stsyncn(port,p_card);
3328 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3329 ACCEPT_MSG_ATN(port);
3332 else if (message == SMWDTR)
3339 FPT_stwidn(port,p_card);
3344 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3345 ACCEPT_MSG_ATN(port);
3347 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3353 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3354 ACCEPT_MSG_ATN(port);
3356 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3361 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3363 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3367 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3368 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3373 /*---------------------------------------------------------------------
3375 * Function: FPT_sisyncn
3377 * Description: Read in a message byte from the SCSI bus, and check
3378 * for a parity error.
3380 *---------------------------------------------------------------------*/
3382 static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag)
3385 PSCCBMgr_tar_info currTar_Info;
3387 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3388 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3390 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3393 WRW_HARPOON((port+ID_MSG_STRT),
3394 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3396 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3398 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3399 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3400 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3403 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3405 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3407 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3409 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3411 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3413 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3416 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3419 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3420 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3421 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3426 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3427 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3428 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3432 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3441 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3442 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3449 /*---------------------------------------------------------------------
3451 * Function: FPT_stsyncn
3453 * Description: The has sent us a Sync Nego message so handle it as
3456 *---------------------------------------------------------------------*/
3457 static void FPT_stsyncn(ULONG port, unsigned char p_card)
3459 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3461 PSCCBMgr_tar_info currTar_Info;
3463 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3464 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3466 sync_msg = FPT_sfm(port,currSCCB);
3468 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3470 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3477 offset = FPT_sfm(port,currSCCB);
3479 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3481 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3485 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3487 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3489 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3491 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3493 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3495 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3498 our_sync_msg = 0; /* Message = Async */
3500 if (sync_msg < our_sync_msg) {
3501 sync_msg = our_sync_msg; /*if faster, then set to max. */
3504 if (offset == ASYNC)
3507 if (offset > MAX_OFFSET)
3508 offset = MAX_OFFSET;
3514 sync_reg = 0x20; /* Use 10MB/s */
3518 sync_reg = 0x40; /* Use 6.6MB/s */
3522 sync_reg = 0x60; /* Use 5MB/s */
3526 sync_reg = 0x80; /* Use 4MB/s */
3530 sync_reg = 0xA0; /* Use 3.33MB/s */
3534 sync_reg = 0xC0; /* Use 2.85MB/s */
3538 sync_reg = 0xE0; /* Use 2.5MB/s */
3540 if (sync_msg > 100) {
3542 sync_reg = 0x00; /* Use ASYNC */
3547 if (currTar_Info->TarStatus & WIDE_ENABLED)
3553 sync_reg |= (offset | NARROW_SCSI);
3555 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3558 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3563 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3564 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3566 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3572 ACCEPT_MSG_ATN(port);
3574 FPT_sisyncr(port,sync_msg,offset);
3576 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3577 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3582 /*---------------------------------------------------------------------
3584 * Function: FPT_sisyncr
3586 * Description: Answer the targets sync message.
3588 *---------------------------------------------------------------------*/
3589 static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset)
3592 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3593 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3594 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3595 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3596 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3597 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3598 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3601 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3602 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3604 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3606 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3611 /*---------------------------------------------------------------------
3613 * Function: FPT_siwidn
3615 * Description: Read in a message byte from the SCSI bus, and check
3616 * for a parity error.
3618 *---------------------------------------------------------------------*/
3620 static unsigned char FPT_siwidn(ULONG port, unsigned char p_card)
3623 PSCCBMgr_tar_info currTar_Info;
3625 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3626 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3628 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3631 WRW_HARPOON((port+ID_MSG_STRT),
3632 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3634 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3636 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3637 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3638 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3639 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3640 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3641 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3643 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3646 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3647 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3654 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3655 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3657 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3664 /*---------------------------------------------------------------------
3666 * Function: FPT_stwidn
3668 * Description: The has sent us a Wide Nego message so handle it as
3671 *---------------------------------------------------------------------*/
3672 static void FPT_stwidn(ULONG port, unsigned char p_card)
3674 unsigned char width;
3676 PSCCBMgr_tar_info currTar_Info;
3678 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3679 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3681 width = FPT_sfm(port,currSCCB);
3683 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3685 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3690 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3694 currTar_Info->TarStatus |= WIDE_ENABLED;
3698 width = NARROW_SCSI;
3699 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3703 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3706 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3711 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3713 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3715 ACCEPT_MSG_ATN(port);
3717 FPT_sisyncn(port,p_card, 1);
3718 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3724 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3731 ACCEPT_MSG_ATN(port);
3733 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3738 FPT_siwidr(port,width);
3740 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3745 /*---------------------------------------------------------------------
3747 * Function: FPT_siwidr
3749 * Description: Answer the targets Wide nego message.
3751 *---------------------------------------------------------------------*/
3752 static void FPT_siwidr(ULONG port, unsigned char width)
3755 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3756 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3757 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3758 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3759 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3760 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3763 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3764 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3766 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3768 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3773 /*---------------------------------------------------------------------
3775 * Function: FPT_sssyncv
3777 * Description: Write the desired value to the Sync Register for the
3780 *---------------------------------------------------------------------*/
3781 static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
3782 PSCCBMgr_tar_info currTar_Info)
3784 unsigned char index;
3791 index = 12; /* hp_synctarg_0 */
3794 index = 13; /* hp_synctarg_1 */
3797 index = 14; /* hp_synctarg_2 */
3800 index = 15; /* hp_synctarg_3 */
3803 index = 8; /* hp_synctarg_4 */
3806 index = 9; /* hp_synctarg_5 */
3809 index = 10; /* hp_synctarg_6 */
3812 index = 11; /* hp_synctarg_7 */
3815 index = 4; /* hp_synctarg_8 */
3818 index = 5; /* hp_synctarg_9 */
3821 index = 6; /* hp_synctarg_10 */
3824 index = 7; /* hp_synctarg_11 */
3827 index = 0; /* hp_synctarg_12 */
3830 index = 1; /* hp_synctarg_13 */
3833 index = 2; /* hp_synctarg_14 */
3836 index = 3; /* hp_synctarg_15 */
3840 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3842 currTar_Info->TarSyncCtrl = p_sync_value;
3846 /*---------------------------------------------------------------------
3848 * Function: FPT_sresb
3850 * Description: Reset the desired card's SCSI bus.
3852 *---------------------------------------------------------------------*/
3853 static void FPT_sresb(ULONG port, unsigned char p_card)
3855 unsigned char scsiID, i;
3857 PSCCBMgr_tar_info currTar_Info;
3859 WR_HARPOON(port+hp_page_ctrl,
3860 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3861 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3863 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3865 scsiID = RD_HARPOON(port+hp_seltimeout);
3866 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3867 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3869 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3871 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3873 WR_HARPOON(port+hp_seltimeout,scsiID);
3875 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3877 FPT_Wait(port, TO_5ms);
3879 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3881 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3883 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3885 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3887 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3889 currTar_Info->TarSyncCtrl = 0;
3890 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3893 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3895 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3898 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3900 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3903 FPT_BL_Card[p_card].scanIndex = 0x00;
3904 FPT_BL_Card[p_card].currentSCCB = NULL;
3905 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3907 FPT_BL_Card[p_card].cmdCounter = 0x00;
3908 FPT_BL_Card[p_card].discQCount = 0x00;
3909 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3911 for(i = 0; i < QUEUE_DEPTH; i++)
3912 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3914 WR_HARPOON(port+hp_page_ctrl,
3915 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3919 /*---------------------------------------------------------------------
3921 * Function: FPT_ssenss
3923 * Description: Setup for the Auto Sense command.
3925 *---------------------------------------------------------------------*/
3926 static void FPT_ssenss(PSCCBcard pCurrCard)
3931 currSCCB = pCurrCard->currentSCCB;
3934 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3936 for (i = 0; i < 6; i++) {
3938 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3941 currSCCB->CdbLength = SIX_BYTE_CMD;
3942 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3943 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3944 currSCCB->Cdb[2] = 0x00;
3945 currSCCB->Cdb[3] = 0x00;
3946 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3947 currSCCB->Cdb[5] = 0x00;
3949 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3951 currSCCB->Sccb_ATC = 0x00;
3953 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3955 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3957 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3959 currSCCB->ControlByte = 0x00;
3961 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3966 /*---------------------------------------------------------------------
3968 * Function: FPT_sxfrp
3970 * Description: Transfer data into the bit bucket until the device
3971 * decides to switch phase.
3973 *---------------------------------------------------------------------*/
3975 static void FPT_sxfrp(ULONG p_port, unsigned char p_card)
3977 unsigned char curr_phz;
3980 DISABLE_AUTO(p_port);
3982 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3984 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3988 /* If the Automation handled the end of the transfer then do not
3989 match the phase or we will get out of sync with the ISR. */
3991 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3994 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3996 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3998 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4001 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4003 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4004 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
4006 if (curr_phz & (unsigned char)SCSI_IOBIT)
4008 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4010 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4012 RD_HARPOON(p_port+hp_fifodata_0);
4017 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4018 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4020 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4023 } /* End of While loop for padding data I/O phase */
4025 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4027 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4031 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4032 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4034 RD_HARPOON(p_port+hp_fifodata_0);
4037 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4039 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4040 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4042 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4043 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4048 /*---------------------------------------------------------------------
4050 * Function: FPT_schkdd
4052 * Description: Make sure data has been flushed from both FIFOs and abort
4053 * the operations if necessary.
4055 *---------------------------------------------------------------------*/
4057 static void FPT_schkdd(ULONG port, unsigned char p_card)
4060 unsigned char sPhase;
4064 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4067 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4068 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4074 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4077 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4079 currSCCB->Sccb_XferCnt = 1;
4081 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4082 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4083 WR_HARPOON(port+hp_xferstat, 0x00);
4089 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4091 currSCCB->Sccb_XferCnt = 0;
4094 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4095 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4097 currSCCB->HostStatus = SCCB_PARITY_ERR;
4098 WRW_HARPOON((port+hp_intstat), PARITY);
4102 FPT_hostDataXferAbort(port,p_card,currSCCB);
4105 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4109 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4111 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4114 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4117 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4120 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4124 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4125 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4126 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4127 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4128 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4131 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4133 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4135 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4136 FPT_phaseDataIn(port,p_card);
4140 FPT_phaseDataOut(port,p_card);
4145 FPT_sxfrp(port,p_card);
4146 if (!(RDW_HARPOON((port+hp_intstat)) &
4147 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4149 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4150 FPT_phaseDecode(port,p_card);
4157 WR_HARPOON(port+hp_portctrl_0, 0x00);
4162 /*---------------------------------------------------------------------
4164 * Function: FPT_sinits
4166 * Description: Setup SCCB manager fields in this SCCB.
4168 *---------------------------------------------------------------------*/
4170 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
4172 PSCCBMgr_tar_info currTar_Info;
4174 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4178 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4180 p_sccb->Sccb_XferState = 0x00;
4181 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4183 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4184 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4186 p_sccb->Sccb_SGoffset = 0;
4187 p_sccb->Sccb_XferState = F_SG_XFER;
4188 p_sccb->Sccb_XferCnt = 0x00;
4191 if (p_sccb->DataLength == 0x00)
4193 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4195 if (p_sccb->ControlByte & F_USE_CMD_Q)
4197 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4198 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4201 currTar_Info->TarStatus |= TAG_Q_TRYING;
4204 /* For !single SCSI device in system & device allow Disconnect
4205 or command is tag_q type then send Cmd with Disconnect Enable
4206 else send Cmd with Disconnect Disable */
4209 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4210 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4211 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4213 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4214 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4215 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4220 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4223 p_sccb->HostStatus = 0x00;
4224 p_sccb->TargetStatus = 0x00;
4225 p_sccb->Sccb_tag = 0x00;
4226 p_sccb->Sccb_MGRFlags = 0x00;
4227 p_sccb->Sccb_sgseg = 0x00;
4228 p_sccb->Sccb_ATC = 0x00;
4229 p_sccb->Sccb_savedATC = 0x00;
4231 p_sccb->SccbVirtDataPtr = 0x00;
4232 p_sccb->Sccb_forwardlink = NULL;
4233 p_sccb->Sccb_backlink = NULL;
4235 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4236 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4237 p_sccb->Sccb_scsimsg = SMNO_OP;
4242 /*---------------------------------------------------------------------
4244 * Function: Phase Decode
4246 * Description: Determine the phase and call the appropriate function.
4248 *---------------------------------------------------------------------*/
4250 static void FPT_phaseDecode(ULONG p_port, unsigned char p_card)
4252 unsigned char phase_ref;
4253 void (*phase) (ULONG, unsigned char);
4256 DISABLE_AUTO(p_port);
4258 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4260 phase = FPT_s_PhaseTbl[phase_ref];
4262 (*phase)(p_port, p_card); /* Call the correct phase func */
4267 /*---------------------------------------------------------------------
4269 * Function: Data Out Phase
4271 * Description: Start up both the BusMaster and Xbow.
4273 *---------------------------------------------------------------------*/
4275 static void FPT_phaseDataOut(ULONG port, unsigned char p_card)
4280 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4281 if (currSCCB == NULL)
4283 return; /* Exit if No SCCB record */
4286 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4287 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4289 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4291 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4293 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4295 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4297 if (currSCCB->Sccb_XferCnt == 0) {
4300 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4301 (currSCCB->HostStatus == SCCB_COMPLETE))
4302 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4304 FPT_sxfrp(port,p_card);
4305 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4306 FPT_phaseDecode(port,p_card);
4311 /*---------------------------------------------------------------------
4313 * Function: Data In Phase
4315 * Description: Startup the BusMaster and the XBOW.
4317 *---------------------------------------------------------------------*/
4319 static void FPT_phaseDataIn(ULONG port, unsigned char p_card)
4324 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4326 if (currSCCB == NULL)
4328 return; /* Exit if No SCCB record */
4332 currSCCB->Sccb_scsistat = DATA_IN_ST;
4333 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4334 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4336 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4338 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4340 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4342 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4344 if (currSCCB->Sccb_XferCnt == 0) {
4347 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4348 (currSCCB->HostStatus == SCCB_COMPLETE))
4349 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4351 FPT_sxfrp(port,p_card);
4352 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4353 FPT_phaseDecode(port,p_card);
4358 /*---------------------------------------------------------------------
4360 * Function: Command Phase
4362 * Description: Load the CDB into the automation and start it up.
4364 *---------------------------------------------------------------------*/
4366 static void FPT_phaseCommand(ULONG p_port, unsigned char p_card)
4372 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4374 if (currSCCB->OperationCode == RESET_COMMAND) {
4376 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4377 currSCCB->CdbLength = SIX_BYTE_CMD;
4380 WR_HARPOON(p_port+hp_scsisig, 0x00);
4382 ARAM_ACCESS(p_port);
4385 cdb_reg = p_port + CMD_STRT;
4387 for (i=0; i < currSCCB->CdbLength; i++) {
4389 if (currSCCB->OperationCode == RESET_COMMAND)
4391 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4394 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4398 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4399 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4401 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4403 currSCCB->Sccb_scsistat = COMMAND_ST;
4405 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4406 SGRAM_ACCESS(p_port);
4410 /*---------------------------------------------------------------------
4412 * Function: Status phase
4414 * Description: Bring in the status and command complete message bytes
4416 *---------------------------------------------------------------------*/
4418 static void FPT_phaseStatus(ULONG port, unsigned char p_card)
4420 /* Start-up the automation to finish off this command and let the
4421 isr handle the interrupt for command complete when it comes in.
4422 We could wait here for the interrupt to be generated?
4425 WR_HARPOON(port+hp_scsisig, 0x00);
4427 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4431 /*---------------------------------------------------------------------
4433 * Function: Phase Message Out
4435 * Description: Send out our message (if we have one) and handle whatever
4438 *---------------------------------------------------------------------*/
4440 static void FPT_phaseMsgOut(ULONG port, unsigned char p_card)
4442 unsigned char message,scsiID;
4444 PSCCBMgr_tar_info currTar_Info;
4446 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4448 if (currSCCB != NULL) {
4450 message = currSCCB->Sccb_scsimsg;
4451 scsiID = currSCCB->TargID;
4453 if (message == SMDEV_RESET)
4457 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4458 currTar_Info->TarSyncCtrl = 0;
4459 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4461 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4464 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4468 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4471 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4475 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4476 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4478 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4480 currSCCB->HostStatus = SCCB_COMPLETE;
4481 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4483 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4484 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4489 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4493 if(message == SMNO_OP)
4495 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4497 FPT_ssel(port,p_card);
4505 if (message == SMABORT)
4507 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4516 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4519 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4521 WR_HARPOON(port+hp_scsidata_0,message);
4523 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4527 WR_HARPOON(port+hp_portctrl_0, 0x00);
4529 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4530 (message == SMABORT_TAG) )
4533 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4535 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4537 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4539 if (currSCCB != NULL)
4542 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4543 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4544 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4546 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4548 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4553 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4560 FPT_sxfrp(port,p_card);
4567 if(message == SMPARITY)
4569 currSCCB->Sccb_scsimsg = SMNO_OP;
4570 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4574 FPT_sxfrp(port,p_card);
4580 /*---------------------------------------------------------------------
4582 * Function: Message In phase
4584 * Description: Bring in the message and determine what to do with it.
4586 *---------------------------------------------------------------------*/
4588 static void FPT_phaseMsgIn(ULONG port, unsigned char p_card)
4590 unsigned char message;
4593 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4595 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4598 FPT_phaseChkFifo(port, p_card);
4601 message = RD_HARPOON(port+hp_scsidata_0);
4602 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4605 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4612 message = FPT_sfm(port,currSCCB);
4617 FPT_sdecm(message,port,p_card);
4622 if(currSCCB->Sccb_scsimsg != SMPARITY)
4624 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4631 /*---------------------------------------------------------------------
4633 * Function: Illegal phase
4635 * Description: Target switched to some illegal phase, so all we can do
4636 * is report an error back to the host (if that is possible)
4637 * and send an ABORT message to the misbehaving target.
4639 *---------------------------------------------------------------------*/
4641 static void FPT_phaseIllegal(ULONG port, unsigned char p_card)
4645 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4647 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4648 if (currSCCB != NULL) {
4650 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4651 currSCCB->Sccb_scsistat = ABORT_ST;
4652 currSCCB->Sccb_scsimsg = SMABORT;
4655 ACCEPT_MSG_ATN(port);
4660 /*---------------------------------------------------------------------
4662 * Function: Phase Check FIFO
4664 * Description: Make sure data has been flushed from both FIFOs and abort
4665 * the operations if necessary.
4667 *---------------------------------------------------------------------*/
4669 static void FPT_phaseChkFifo(ULONG port, unsigned char p_card)
4674 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4676 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4679 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4680 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4683 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4685 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4687 currSCCB->Sccb_XferCnt = 0;
4689 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4690 (currSCCB->HostStatus == SCCB_COMPLETE))
4692 currSCCB->HostStatus = SCCB_PARITY_ERR;
4693 WRW_HARPOON((port+hp_intstat), PARITY);
4696 FPT_hostDataXferAbort(port,p_card,currSCCB);
4698 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4700 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4701 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4704 } /*End Data In specific code. */
4708 GET_XFER_CNT(port,xfercnt);
4711 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4714 WR_HARPOON(port+hp_portctrl_0, 0x00);
4716 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4718 currSCCB->Sccb_XferCnt = xfercnt;
4720 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4721 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4723 currSCCB->HostStatus = SCCB_PARITY_ERR;
4724 WRW_HARPOON((port+hp_intstat), PARITY);
4728 FPT_hostDataXferAbort(port,p_card,currSCCB);
4731 WR_HARPOON(port+hp_fifowrite, 0x00);
4732 WR_HARPOON(port+hp_fiforead, 0x00);
4733 WR_HARPOON(port+hp_xferstat, 0x00);
4735 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4739 /*---------------------------------------------------------------------
4741 * Function: Phase Bus Free
4743 * Description: We just went bus free so figure out if it was
4744 * because of command complete or from a disconnect.
4746 *---------------------------------------------------------------------*/
4747 static void FPT_phaseBusFree(ULONG port, unsigned char p_card)
4751 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4753 if (currSCCB != NULL)
4759 if (currSCCB->OperationCode == RESET_COMMAND)
4762 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4763 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4766 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4768 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4770 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4774 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4776 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4777 (unsigned char)SYNC_SUPPORTED;
4778 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4781 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4783 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4784 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4785 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4787 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4790 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4792 /* Make sure this is not a phony BUS_FREE. If we were
4793 reselected or if BUSY is NOT on then this is a
4794 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4796 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4797 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4799 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4812 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4814 if (!currSCCB->HostStatus)
4816 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4819 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4820 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4821 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4823 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4825 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4830 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4832 } /*end if !=null */
4838 /*---------------------------------------------------------------------
4840 * Function: Auto Load Default Map
4842 * Description: Load the Automation RAM with the defualt map values.
4844 *---------------------------------------------------------------------*/
4845 static void FPT_autoLoadDefaultMap(ULONG p_port)
4849 ARAM_ACCESS(p_port);
4850 map_addr = p_port + hp_aramBase;
4852 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4854 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4856 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4858 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4874 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4876 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4878 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4880 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4882 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4884 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4886 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4887 map_addr +=2; /*This means AYNC DATA IN */
4888 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4890 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4892 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4894 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4896 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4898 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4900 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4902 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4904 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4906 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4908 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4910 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4912 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4914 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4916 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4918 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4920 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4922 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4929 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4931 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4932 map_addr +=2; /* DIDN'T GET ONE */
4933 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4935 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4937 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4941 SGRAM_ACCESS(p_port);
4944 /*---------------------------------------------------------------------
4946 * Function: Auto Command Complete
4948 * Description: Post command back to host and find another command
4951 *---------------------------------------------------------------------*/
4953 static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card)
4956 unsigned char status_byte;
4958 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4960 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4962 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4964 if (status_byte != SSGOOD) {
4966 if (status_byte == SSQ_FULL) {
4969 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4970 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4972 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4973 if(FPT_BL_Card[p_card].discQCount != 0)
4974 FPT_BL_Card[p_card].discQCount--;
4975 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4979 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4980 if(currSCCB->Sccb_tag)
4982 if(FPT_BL_Card[p_card].discQCount != 0)
4983 FPT_BL_Card[p_card].discQCount--;
4984 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4987 if(FPT_BL_Card[p_card].discQCount != 0)
4988 FPT_BL_Card[p_card].discQCount--;
4989 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4993 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4995 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
5000 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5002 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
5003 (unsigned char)SYNC_SUPPORTED;
5005 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5006 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5008 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5009 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5011 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5012 if(FPT_BL_Card[p_card].discQCount != 0)
5013 FPT_BL_Card[p_card].discQCount--;
5014 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5018 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5019 if(currSCCB->Sccb_tag)
5021 if(FPT_BL_Card[p_card].discQCount != 0)
5022 FPT_BL_Card[p_card].discQCount--;
5023 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5026 if(FPT_BL_Card[p_card].discQCount != 0)
5027 FPT_BL_Card[p_card].discQCount--;
5028 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5035 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5038 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5039 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5040 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5042 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5043 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5045 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5046 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5048 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5049 if(FPT_BL_Card[p_card].discQCount != 0)
5050 FPT_BL_Card[p_card].discQCount--;
5051 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5055 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5056 if(currSCCB->Sccb_tag)
5058 if(FPT_BL_Card[p_card].discQCount != 0)
5059 FPT_BL_Card[p_card].discQCount--;
5060 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5063 if(FPT_BL_Card[p_card].discQCount != 0)
5064 FPT_BL_Card[p_card].discQCount--;
5065 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5072 if (status_byte == SSCHECK)
5074 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5076 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5078 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5080 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5082 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5087 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5089 currSCCB->SccbStatus = SCCB_ERROR;
5090 currSCCB->TargetStatus = status_byte;
5092 if (status_byte == SSCHECK) {
5094 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5098 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5100 if (currSCCB->RequestSenseLength == 0)
5101 currSCCB->RequestSenseLength = 14;
5103 FPT_ssenss(&FPT_BL_Card[p_card]);
5104 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5106 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5107 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5109 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5110 if(FPT_BL_Card[p_card].discQCount != 0)
5111 FPT_BL_Card[p_card].discQCount--;
5112 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5116 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5117 if(currSCCB->Sccb_tag)
5119 if(FPT_BL_Card[p_card].discQCount != 0)
5120 FPT_BL_Card[p_card].discQCount--;
5121 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5124 if(FPT_BL_Card[p_card].discQCount != 0)
5125 FPT_BL_Card[p_card].discQCount--;
5126 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5136 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5137 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5138 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5140 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5143 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5146 #define SHORT_WAIT 0x0000000F
5147 #define LONG_WAIT 0x0000FFFFL
5150 /*---------------------------------------------------------------------
5152 * Function: Data Transfer Processor
5154 * Description: This routine performs two tasks.
5155 * (1) Start data transfer by calling HOST_DATA_XFER_START
5156 * function. Once data transfer is started, (2) Depends
5157 * on the type of data transfer mode Scatter/Gather mode
5158 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5159 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5160 * data transfer done. In Scatter/Gather mode, this routine
5161 * checks bus master command complete and dual rank busy
5162 * bit to keep chaining SC transfer command. Similarly,
5163 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5164 * (F_HOST_XFER_ACT bit) for data transfer done.
5166 *---------------------------------------------------------------------*/
5168 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
5172 currSCCB = pCurrCard->currentSCCB;
5174 if (currSCCB->Sccb_XferState & F_SG_XFER)
5176 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5179 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5180 currSCCB->Sccb_SGoffset = 0x00;
5182 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5184 FPT_busMstrSGDataXferStart(port, currSCCB);
5189 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5191 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5193 FPT_busMstrDataXferStart(port, currSCCB);
5199 /*---------------------------------------------------------------------
5201 * Function: BusMaster Scatter Gather Data Transfer Start
5205 *---------------------------------------------------------------------*/
5206 static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5208 ULONG count,addr,tmpSGCnt;
5210 unsigned char sg_count, i;
5214 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5216 count = ((ULONG) HOST_RD_CMD)<<24;
5220 count = ((ULONG) HOST_WRT_CMD)<<24;
5225 sg_index = pcurrSCCB->Sccb_sgseg;
5226 reg_offset = hp_aramBase;
5229 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5232 WR_HARPOON(p_port+hp_page_ctrl, i);
5234 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5235 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5237 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5240 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5243 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5244 ((sg_index * 2) + 1));
5247 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5249 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5250 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5252 tmpSGCnt = count & 0x00FFFFFFL;
5255 WR_HARP32(p_port,reg_offset,addr);
5258 WR_HARP32(p_port,reg_offset,count);
5261 count &= 0xFF000000L;
5267 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5269 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5271 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5273 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5276 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5277 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5283 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5284 (tmpSGCnt & 0x000000001))
5287 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5292 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5294 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5295 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5299 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5304 /*---------------------------------------------------------------------
5306 * Function: BusMaster Data Transfer Start
5310 *---------------------------------------------------------------------*/
5311 static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5315 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5317 count = pcurrSCCB->Sccb_XferCnt;
5319 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5323 addr = pcurrSCCB->SensePointer;
5324 count = pcurrSCCB->RequestSenseLength;
5328 HP_SETUP_ADDR_CNT(p_port,addr,count);
5331 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5333 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5334 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5336 WR_HARPOON(p_port+hp_xfer_cmd,
5337 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5342 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5343 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5345 WR_HARPOON(p_port+hp_xfer_cmd,
5346 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5352 /*---------------------------------------------------------------------
5354 * Function: BusMaster Timeout Handler
5356 * Description: This function is called after a bus master command busy time
5357 * out is detected. This routines issue halt state machine
5358 * with a software time out for command busy. If command busy
5359 * is still asserted at the end of the time out, it issues
5360 * hard abort with another software time out. It hard abort
5361 * command busy is also time out, it'll just give up.
5363 *---------------------------------------------------------------------*/
5364 static unsigned char FPT_busMstrTimeOut(ULONG p_port)
5368 timeout = LONG_WAIT;
5370 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5372 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5376 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5377 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5379 timeout = LONG_WAIT;
5380 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5383 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5385 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5395 /*---------------------------------------------------------------------
5397 * Function: Host Data Transfer Abort
5399 * Description: Abort any in progress transfer.
5401 *---------------------------------------------------------------------*/
5402 static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
5409 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5411 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5414 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5416 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5417 timeout = LONG_WAIT;
5419 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5421 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5423 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5425 if (FPT_busMstrTimeOut(port)) {
5427 if (pCurrSCCB->HostStatus == 0x00)
5429 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5433 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5435 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5437 if (pCurrSCCB->HostStatus == 0x00)
5440 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5446 else if (pCurrSCCB->Sccb_XferCnt) {
5448 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5451 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5454 WR_HARPOON(port+hp_sg_addr,0x00);
5456 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5458 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5460 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5463 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5465 while (remain_cnt < 0x01000000L) {
5469 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5470 DataPointer) + (sg_ptr * 2)))) {
5472 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5473 DataPointer) + (sg_ptr * 2)));
5484 if (remain_cnt < 0x01000000L) {
5487 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5489 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5492 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5493 && (remain_cnt == 0))
5495 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5501 if (pCurrSCCB->HostStatus == 0x00) {
5503 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5509 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5512 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5514 FPT_busMstrTimeOut(port);
5519 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5521 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5523 if (pCurrSCCB->HostStatus == 0x00) {
5525 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5536 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5538 timeout = SHORT_WAIT;
5540 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5541 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5545 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5547 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5550 timeout = LONG_WAIT;
5552 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5555 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5559 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5561 if (pCurrSCCB->HostStatus == 0x00) {
5563 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5566 FPT_busMstrTimeOut(port);
5570 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5572 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5574 if (pCurrSCCB->HostStatus == 0x00) {
5576 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5587 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5589 timeout = LONG_WAIT;
5591 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5593 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5595 if (pCurrSCCB->HostStatus == 0x00) {
5597 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5600 FPT_busMstrTimeOut(port);
5605 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5607 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5609 if (pCurrSCCB->HostStatus == 0x00) {
5611 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5617 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5619 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5622 WR_HARPOON(port+hp_sg_addr,0x00);
5624 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5626 pCurrSCCB->Sccb_SGoffset = 0x00;
5629 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5630 pCurrSCCB->DataLength) {
5632 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5634 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5641 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5643 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5647 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5652 /*---------------------------------------------------------------------
5654 * Function: Host Data Transfer Restart
5656 * Description: Reset the available count due to a restore data
5659 *---------------------------------------------------------------------*/
5660 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5666 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5668 currSCCB->Sccb_XferCnt = 0;
5670 sg_index = 0xffff; /*Index by long words into sg list. */
5671 data_count = 0; /*Running count of SG xfer counts. */
5673 sg_ptr = (ULONG *)currSCCB->DataPointer;
5675 while (data_count < currSCCB->Sccb_ATC) {
5678 data_count += *(sg_ptr+(sg_index * 2));
5681 if (data_count == currSCCB->Sccb_ATC) {
5683 currSCCB->Sccb_SGoffset = 0;
5688 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5691 currSCCB->Sccb_sgseg = (USHORT)sg_index;
5695 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5701 /*---------------------------------------------------------------------
5703 * Function: FPT_scini
5705 * Description: Setup all data structures necessary for SCAM selection.
5707 *---------------------------------------------------------------------*/
5709 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5712 unsigned char loser,assigned_id;
5715 unsigned char i,k,ScamFlg ;
5717 PNVRamInfo pCurrNvRam;
5719 currCard = &FPT_BL_Card[p_card];
5720 p_port = currCard->ioPort;
5721 pCurrNvRam = currCard->pNvRamInfo;
5725 ScamFlg = pCurrNvRam->niScamConf;
5726 i = pCurrNvRam->niSysConf;
5729 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5730 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5732 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5735 FPT_inisci(p_card,p_port, p_our_id);
5737 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5738 too slow to return to SCAM selection */
5741 FPT_Wait1Second(p_port);
5743 FPT_Wait(p_port, TO_250ms); */
5745 FPT_Wait1Second(p_port);
5747 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5749 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5754 FPT_scxferc(p_port,SYNC_PTRN);
5755 FPT_scxferc(p_port,DOM_MSTR);
5756 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5757 } while ( loser == 0xFF );
5761 if ((p_power_up) && (!loser))
5763 FPT_sresb(p_port,p_card);
5764 FPT_Wait(p_port, TO_250ms);
5766 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5771 FPT_scxferc(p_port, SYNC_PTRN);
5772 FPT_scxferc(p_port, DOM_MSTR);
5773 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5775 } while ( loser == 0xFF );
5790 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5793 if (ScamFlg & SCAM_ENABLED)
5796 for (i=0; i < MAX_SCSI_TAR; i++)
5798 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5799 (FPT_scamInfo[i].state == ID_UNUSED))
5801 if (FPT_scsell(p_port,i))
5803 FPT_scamInfo[i].state = LEGACY;
5804 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5805 (FPT_scamInfo[i].id_string[1] != 0xFA))
5808 FPT_scamInfo[i].id_string[0] = 0xFF;
5809 FPT_scamInfo[i].id_string[1] = 0xFA;
5810 if(pCurrNvRam == NULL)
5811 currCard->globalFlags |= F_UPDATE_EEPROM;
5817 FPT_sresb(p_port,p_card);
5818 FPT_Wait1Second(p_port);
5819 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5821 FPT_scasid(p_card, p_port);
5826 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5828 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5830 FPT_scwtsel(p_port);
5833 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5835 i = FPT_scxferc(p_port,0x00);
5838 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5840 i = FPT_scxferc(p_port,0x00);
5843 k = FPT_scxferc(p_port,0x00);
5848 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5849 FPT_inisci(p_card, p_port, p_our_id);
5850 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5851 FPT_scamInfo[currCard->ourId].id_string[0]
5859 else if (i == SET_P_FLAG)
5861 if (!(FPT_scsendi(p_port,
5862 &FPT_scamInfo[p_our_id].id_string[0])))
5863 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5865 }while (!assigned_id);
5867 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5870 if (ScamFlg & SCAM_ENABLED)
5873 if (currCard->globalFlags & F_UPDATE_EEPROM)
5875 FPT_scsavdi(p_card, p_port);
5876 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5882 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5884 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5885 (FPT_scamInfo[i].state == LEGACY))
5890 currCard->globalFlags |= F_SINGLE_DEVICE;
5892 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5897 /*---------------------------------------------------------------------
5899 * Function: FPT_scarb
5901 * Description: Gain control of the bus and wait SCAM select time (250ms)
5903 *---------------------------------------------------------------------*/
5905 static int FPT_scarb(ULONG p_port, unsigned char p_sel_type)
5907 if (p_sel_type == INIT_SELTD)
5910 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5913 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5916 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5921 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5923 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5929 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5931 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5933 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5934 ~(SCSI_BSY | SCSI_SEL)));
5940 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5942 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5943 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5944 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5945 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5947 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5949 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5952 FPT_Wait(p_port,TO_250ms);
5958 /*---------------------------------------------------------------------
5960 * Function: FPT_scbusf
5962 * Description: Release the SCSI bus and disable SCAM selection.
5964 *---------------------------------------------------------------------*/
5966 static void FPT_scbusf(ULONG p_port)
5968 WR_HARPOON(p_port+hp_page_ctrl,
5969 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5972 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5974 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5977 WR_HARPOON(p_port+hp_scsisig, 0x00);
5980 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5983 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5986 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5988 WR_HARPOON(p_port+hp_page_ctrl,
5989 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5994 /*---------------------------------------------------------------------
5996 * Function: FPT_scasid
5998 * Description: Assign an ID to all the SCAM devices.
6000 *---------------------------------------------------------------------*/
6002 static void FPT_scasid(unsigned char p_card, ULONG p_port)
6004 unsigned char temp_id_string[ID_STRING_LENGTH];
6006 unsigned char i,k,scam_id;
6007 unsigned char crcBytes[3];
6008 PNVRamInfo pCurrNvRam;
6009 ushort_ptr pCrcBytes;
6011 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6018 for (k=0; k < ID_STRING_LENGTH; k++)
6020 temp_id_string[k] = (unsigned char) 0x00;
6023 FPT_scxferc(p_port,SYNC_PTRN);
6024 FPT_scxferc(p_port,ASSIGN_ID);
6026 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6029 pCrcBytes = (ushort_ptr)&crcBytes[0];
6030 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6031 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6032 temp_id_string[1] = crcBytes[2];
6033 temp_id_string[2] = crcBytes[0];
6034 temp_id_string[3] = crcBytes[1];
6035 for(k = 4; k < ID_STRING_LENGTH; k++)
6036 temp_id_string[k] = (unsigned char) 0x00;
6038 i = FPT_scmachid(p_card,temp_id_string);
6040 if (i == CLR_PRIORITY)
6042 FPT_scxferc(p_port,MISC_CODE);
6043 FPT_scxferc(p_port,CLR_P_FLAG);
6044 i = 0; /*Not the last ID yet. */
6047 else if (i != NO_ID_AVAIL)
6050 FPT_scxferc(p_port,ID_0_7);
6052 FPT_scxferc(p_port,ID_8_F);
6054 scam_id = (i & (unsigned char) 0x07);
6057 for (k=1; k < 0x08; k <<= 1)
6059 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6061 FPT_scxferc(p_port,scam_id);
6063 i = 0; /*Not the last ID yet. */
6074 FPT_scxferc(p_port,SYNC_PTRN);
6075 FPT_scxferc(p_port,CFG_CMPLT);
6082 /*---------------------------------------------------------------------
6084 * Function: FPT_scsel
6086 * Description: Select all the SCAM devices.
6088 *---------------------------------------------------------------------*/
6090 static void FPT_scsel(ULONG p_port)
6093 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6094 FPT_scwiros(p_port, SCSI_MSG);
6096 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6099 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6100 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6101 (unsigned char)(BIT(7)+BIT(6))));
6104 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6105 FPT_scwiros(p_port, SCSI_SEL);
6107 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6108 ~(unsigned char)BIT(6)));
6109 FPT_scwirod(p_port, BIT(6));
6111 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6116 /*---------------------------------------------------------------------
6118 * Function: FPT_scxferc
6120 * Description: Handshake the p_data (DB4-0) across the bus.
6122 *---------------------------------------------------------------------*/
6124 static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data)
6126 unsigned char curr_data, ret_data;
6128 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6130 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6132 curr_data &= ~BIT(7);
6134 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6136 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6137 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6139 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6141 curr_data |= BIT(6);
6143 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145 curr_data &= ~BIT(5);
6147 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6149 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6151 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6152 curr_data |= BIT(7);
6154 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6156 curr_data &= ~BIT(6);
6158 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6160 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6166 /*---------------------------------------------------------------------
6168 * Function: FPT_scsendi
6170 * Description: Transfer our Identification string to determine if we
6171 * will be the dominant master.
6173 *---------------------------------------------------------------------*/
6175 static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[])
6177 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6181 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6183 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6186 ret_data = FPT_scxferc(p_port,00);
6188 else if (p_id_string[byte_cnt] & bit_cnt)
6190 ret_data = FPT_scxferc(p_port,02);
6194 ret_data = FPT_scxferc(p_port,01);
6199 if ((ret_data & 0x1C) == 0x10)
6200 return(0x00); /*End of isolation stage, we won! */
6202 if (ret_data & 0x1C)
6205 if ((defer) && (!(ret_data & 0x1F)))
6206 return(0x01); /*End of isolation stage, we lost. */
6213 return(0x01); /*We lost */
6215 return(0); /*We WON! Yeeessss! */
6220 /*---------------------------------------------------------------------
6222 * Function: FPT_sciso
6224 * Description: Transfer the Identification string.
6226 *---------------------------------------------------------------------*/
6228 static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[])
6230 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6234 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6236 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6238 ret_data = FPT_scxferc(p_port,0);
6240 if (ret_data & 0xFC)
6246 if (ret_data & BIT(1)) {
6251 if ((ret_data & 0x1F) == 0)
6254 if(bit_cnt != 0 || bit_cnt != 8)
6258 FPT_scxferc(p_port, SYNC_PTRN);
6259 FPT_scxferc(p_port, ASSIGN_ID);
6271 p_id_string[byte_cnt] = the_data;
6280 /*---------------------------------------------------------------------
6282 * Function: FPT_scwirod
6284 * Description: Sample the SCSI data bus making sure the signal has been
6285 * deasserted for the correct number of consecutive samples.
6287 *---------------------------------------------------------------------*/
6289 static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit)
6294 while ( i < MAX_SCSI_TAR ) {
6296 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6309 /*---------------------------------------------------------------------
6311 * Function: FPT_scwiros
6313 * Description: Sample the SCSI Signal lines making sure the signal has been
6314 * deasserted for the correct number of consecutive samples.
6316 *---------------------------------------------------------------------*/
6318 static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit)
6323 while ( i < MAX_SCSI_TAR ) {
6325 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6337 /*---------------------------------------------------------------------
6339 * Function: FPT_scvalq
6341 * Description: Make sure we received a valid data byte.
6343 *---------------------------------------------------------------------*/
6345 static unsigned char FPT_scvalq(unsigned char p_quintet)
6347 unsigned char count;
6349 for (count=1; count < 0x08; count<<=1) {
6350 if (!(p_quintet & count))
6354 if (p_quintet & 0x18)
6362 /*---------------------------------------------------------------------
6364 * Function: FPT_scsell
6366 * Description: Select the specified device ID using a selection timeout
6367 * less than 4ms. If somebody responds then it is a legacy
6368 * drive and this ID must be marked as such.
6370 *---------------------------------------------------------------------*/
6372 static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id)
6376 WR_HARPOON(p_port+hp_page_ctrl,
6377 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6379 ARAM_ACCESS(p_port);
6381 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6382 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6385 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6386 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6388 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6390 WRW_HARPOON((p_port+hp_intstat),
6391 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6393 WR_HARPOON(p_port+hp_select_id, targ_id);
6395 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6396 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6397 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6400 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6401 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6403 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6404 FPT_Wait(p_port, TO_250ms);
6406 DISABLE_AUTO(p_port);
6408 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6409 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6411 SGRAM_ACCESS(p_port);
6413 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6415 WRW_HARPOON((p_port+hp_intstat),
6416 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6418 WR_HARPOON(p_port+hp_page_ctrl,
6419 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6421 return(0); /*No legacy device */
6426 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6427 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6429 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6434 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6436 WR_HARPOON(p_port+hp_page_ctrl,
6437 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6439 return(1); /*Found one of them oldies! */
6443 /*---------------------------------------------------------------------
6445 * Function: FPT_scwtsel
6447 * Description: Wait to be selected by another SCAM initiator.
6449 *---------------------------------------------------------------------*/
6451 static void FPT_scwtsel(ULONG p_port)
6453 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6457 /*---------------------------------------------------------------------
6459 * Function: FPT_inisci
6461 * Description: Setup the data Structure with the info from the EEPROM.
6463 *---------------------------------------------------------------------*/
6465 static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id)
6467 unsigned char i,k,max_id;
6469 PNVRamInfo pCurrNvRam;
6471 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6473 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6480 for(i = 0; i < max_id; i++){
6482 for(k = 0; k < 4; k++)
6483 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6484 for(k = 4; k < ID_STRING_LENGTH; k++)
6485 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6487 if(FPT_scamInfo[i].id_string[0] == 0x00)
6488 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6490 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6494 for (i=0; i < max_id; i++)
6496 for (k=0; k < ID_STRING_LENGTH; k+=2)
6498 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
6499 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6500 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6502 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6505 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6506 (FPT_scamInfo[i].id_string[0] == 0xFF))
6508 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6511 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6515 for(k = 0; k < ID_STRING_LENGTH; k++)
6516 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6520 /*---------------------------------------------------------------------
6522 * Function: FPT_scmachid
6524 * Description: Match the Device ID string with our values stored in
6527 *---------------------------------------------------------------------*/
6529 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6532 unsigned char i,k,match;
6535 for (i=0; i < MAX_SCSI_TAR; i++) {
6539 for (k=0; k < ID_STRING_LENGTH; k++)
6541 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6547 FPT_scamInfo[i].state = ID_ASSIGNED;
6555 if (p_id_string[0] & BIT(5))
6560 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6561 match = p_id_string[1] & (unsigned char) 0x1F;
6569 if (FPT_scamInfo[match].state == ID_UNUSED)
6571 for (k=0; k < ID_STRING_LENGTH; k++)
6573 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6576 FPT_scamInfo[match].state = ID_ASSIGNED;
6578 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6579 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6589 if (p_id_string[0] & BIT(5))
6592 match = MAX_SCSI_TAR-1;
6598 if (p_id_string[0] & BIT(7))
6600 return(CLR_PRIORITY);
6604 if (p_id_string[0] & BIT(5))
6609 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6610 match = p_id_string[1] & (unsigned char) 0x1F;
6619 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6621 for (k=0; k < ID_STRING_LENGTH; k++)
6623 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6626 FPT_scamInfo[match].id_string[0] |= BIT(7);
6627 FPT_scamInfo[match].state = ID_ASSIGNED;
6628 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6629 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6639 if (p_id_string[0] & BIT(5))
6642 match = MAX_SCSI_TAR-1;
6646 return(NO_ID_AVAIL);
6650 /*---------------------------------------------------------------------
6652 * Function: FPT_scsavdi
6654 * Description: Save off the device SCAM ID strings.
6656 *---------------------------------------------------------------------*/
6658 static void FPT_scsavdi(unsigned char p_card, ULONG p_port)
6660 unsigned char i,k,max_id;
6661 USHORT ee_data,sum_data;
6666 for (i = 1; i < EE_SCAMBASE/2; i++)
6668 sum_data += FPT_utilEERead(p_port, i);
6672 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6674 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6680 for (i=0; i < max_id; i++)
6683 for (k=0; k < ID_STRING_LENGTH; k+=2)
6685 ee_data = FPT_scamInfo[i].id_string[k+1];
6687 ee_data |= FPT_scamInfo[i].id_string[k];
6688 sum_data += ee_data;
6689 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
6690 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6695 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6696 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6699 /*---------------------------------------------------------------------
6701 * Function: FPT_XbowInit
6703 * Description: Setup the Xbow for normal operation.
6705 *---------------------------------------------------------------------*/
6707 static void FPT_XbowInit(ULONG port, unsigned char ScamFlg)
6711 i = RD_HARPOON(port+hp_page_ctrl);
6712 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6714 WR_HARPOON(port+hp_scsireset,0x00);
6715 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6717 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6720 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6722 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6724 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6725 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6727 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6729 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6730 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6732 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6733 FPT_default_intena |= SCAM_SEL;
6735 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6737 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6739 /* Turn on SCSI_MODE8 for narrow cards to fix the
6740 strapping issue with the DUAL CHANNEL card */
6741 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6742 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6744 WR_HARPOON(port+hp_page_ctrl, i);
6749 /*---------------------------------------------------------------------
6751 * Function: FPT_BusMasterInit
6753 * Description: Initialize the BusMaster for normal operations.
6755 *---------------------------------------------------------------------*/
6757 static void FPT_BusMasterInit(ULONG p_port)
6761 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6762 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6764 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6767 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6769 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6772 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6773 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6774 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6779 /*---------------------------------------------------------------------
6781 * Function: FPT_DiagEEPROM
6783 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6786 *---------------------------------------------------------------------*/
6788 static void FPT_DiagEEPROM(ULONG p_port)
6790 USHORT index,temp,max_wd_cnt;
6792 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6793 max_wd_cnt = EEPROM_WD_CNT;
6795 max_wd_cnt = EEPROM_WD_CNT * 2;
6797 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6799 if (temp == 0x4641) {
6801 for (index = 2; index < max_wd_cnt; index++) {
6803 temp += FPT_utilEERead(p_port, index);
6807 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6809 return; /*EEPROM is Okay so return now! */
6814 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6816 for (index = 0; index < max_wd_cnt; index++) {
6818 FPT_utilEEWrite(p_port, 0x0000, index);
6823 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6825 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6827 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6829 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6831 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6833 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6835 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6837 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6840 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6842 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6844 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6851 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6853 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6855 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6857 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6859 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6861 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6865 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6867 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6869 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6871 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6873 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6875 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6877 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6879 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6882 index = ((EE_SCAMBASE/2)+(7*16));
6883 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6884 temp += (0x0700+TYPE_CODE0);
6886 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6887 temp += 0x5542; /* BUSLOGIC */
6889 FPT_utilEEWrite(p_port, 0x4C53, index);
6892 FPT_utilEEWrite(p_port, 0x474F, index);
6895 FPT_utilEEWrite(p_port, 0x4349, index);
6898 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6899 temp += 0x5442; /* BT- 930 */
6901 FPT_utilEEWrite(p_port, 0x202D, index);
6904 FPT_utilEEWrite(p_port, 0x3339, index);
6906 index++; /*Serial # */
6907 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6910 FPT_utilEEWrite(p_port, 0x5453, index);
6913 FPT_utilEEWrite(p_port, 0x5645, index);
6916 FPT_utilEEWrite(p_port, 0x2045, index);
6919 FPT_utilEEWrite(p_port, 0x202F, index);
6922 FPT_utilEEWrite(p_port, 0x4F4A, index);
6925 FPT_utilEEWrite(p_port, 0x204E, index);
6928 FPT_utilEEWrite(p_port, 0x3539, index);
6933 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6935 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6940 /*---------------------------------------------------------------------
6942 * Function: Queue Search Select
6944 * Description: Try to find a new command to execute.
6946 *---------------------------------------------------------------------*/
6948 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6950 unsigned char scan_ptr, lun;
6951 PSCCBMgr_tar_info currTar_Info;
6954 scan_ptr = pCurrCard->scanIndex;
6957 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6958 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6959 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6961 if (currTar_Info->TarSelQ_Cnt != 0)
6965 if (scan_ptr == MAX_SCSI_TAR)
6968 for(lun=0; lun < MAX_LUN; lun++)
6970 if(currTar_Info->TarLUNBusy[lun] == 0)
6973 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6976 while((pCurrCard->currentSCCB != NULL) &&
6977 (lun != pCurrCard->currentSCCB->Lun))
6979 pOldSccb = pCurrCard->currentSCCB;
6980 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6983 if(pCurrCard->currentSCCB == NULL)
6985 if(pOldSccb != NULL)
6987 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6989 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6991 currTar_Info->TarSelQ_Cnt--;
6995 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6997 if (currTar_Info->TarSelQ_Head == NULL)
6999 currTar_Info->TarSelQ_Tail = NULL;
7000 currTar_Info->TarSelQ_Cnt = 0;
7004 currTar_Info->TarSelQ_Cnt--;
7005 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7008 pCurrCard->scanIndex = scan_ptr;
7010 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7020 if (scan_ptr == MAX_SCSI_TAR) {
7028 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7029 (currTar_Info->TarLUNBusy[0] == 0))
7032 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7034 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7036 if (currTar_Info->TarSelQ_Head == NULL)
7038 currTar_Info->TarSelQ_Tail = NULL;
7039 currTar_Info->TarSelQ_Cnt = 0;
7043 currTar_Info->TarSelQ_Cnt--;
7044 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7048 if (scan_ptr == MAX_SCSI_TAR)
7051 pCurrCard->scanIndex = scan_ptr;
7053 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7061 if (scan_ptr == MAX_SCSI_TAR)
7067 } while (scan_ptr != pCurrCard->scanIndex);
7071 /*---------------------------------------------------------------------
7073 * Function: Queue Select Fail
7075 * Description: Add the current SCCB to the head of the Queue.
7077 *---------------------------------------------------------------------*/
7079 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7081 unsigned char thisTarg;
7082 PSCCBMgr_tar_info currTar_Info;
7084 if (pCurrCard->currentSCCB != NULL)
7086 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7087 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7089 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7091 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7093 if (currTar_Info->TarSelQ_Cnt == 0)
7095 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7100 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7104 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7106 pCurrCard->currentSCCB = NULL;
7107 currTar_Info->TarSelQ_Cnt++;
7110 /*---------------------------------------------------------------------
7112 * Function: Queue Command Complete
7114 * Description: Call the callback function with the current SCCB.
7116 *---------------------------------------------------------------------*/
7118 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7119 unsigned char p_card)
7122 unsigned char i, SCSIcmd;
7123 CALL_BK_FN callback;
7124 PSCCBMgr_tar_info currTar_Info;
7126 SCSIcmd = p_sccb->Cdb[0];
7129 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7131 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7132 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7133 (p_sccb->TargetStatus != SSCHECK))
7135 if ((SCSIcmd == SCSI_READ) ||
7136 (SCSIcmd == SCSI_WRITE) ||
7137 (SCSIcmd == SCSI_READ_EXTENDED) ||
7138 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7139 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7140 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7141 (pCurrCard->globalFlags & F_NO_FILTER)
7143 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7147 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7149 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7150 p_sccb->SccbStatus = SCCB_ERROR;
7152 p_sccb->SccbStatus = SCCB_SUCCESS;
7155 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7157 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7158 for (i=0; i < 6; i++) {
7159 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7163 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7164 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7166 FPT_utilUpdateResidual(p_sccb);
7169 pCurrCard->cmdCounter--;
7170 if (!pCurrCard->cmdCounter) {
7172 if (pCurrCard->globalFlags & F_GREEN_PC) {
7173 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7174 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7177 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7178 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7182 if(pCurrCard->discQCount != 0)
7184 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7185 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7186 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7188 pCurrCard->discQCount--;
7189 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7193 if(p_sccb->Sccb_tag)
7195 pCurrCard->discQCount--;
7196 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7199 pCurrCard->discQCount--;
7200 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7206 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7208 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7209 pCurrCard->currentSCCB = NULL;
7213 /*---------------------------------------------------------------------
7215 * Function: Queue Disconnect
7217 * Description: Add SCCB to our disconnect array.
7219 *---------------------------------------------------------------------*/
7220 static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
7222 PSCCBMgr_tar_info currTar_Info;
7224 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7226 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7227 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7229 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7233 if (p_sccb->Sccb_tag)
7235 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7236 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7237 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7240 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7243 FPT_BL_Card[p_card].currentSCCB = NULL;
7247 /*---------------------------------------------------------------------
7249 * Function: Queue Flush SCCB
7251 * Description: Flush all SCCB's back to the host driver for this target.
7253 *---------------------------------------------------------------------*/
7255 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7257 unsigned char qtag,thisTarg;
7259 PSCCBMgr_tar_info currTar_Info;
7261 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7262 if(currSCCB != NULL)
7264 thisTarg = (unsigned char)currSCCB->TargID;
7265 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7267 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7269 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7270 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7273 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7275 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7277 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7278 currTar_Info->TarTagQ_Cnt--;
7286 /*---------------------------------------------------------------------
7288 * Function: Queue Flush Target SCCB
7290 * Description: Flush all SCCB's back to the host driver for this target.
7292 *---------------------------------------------------------------------*/
7294 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7295 unsigned char error_code)
7298 PSCCBMgr_tar_info currTar_Info;
7300 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7302 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7304 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7305 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7308 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7310 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7312 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7313 currTar_Info->TarTagQ_Cnt--;
7324 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
7326 PSCCBMgr_tar_info currTar_Info;
7327 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7329 p_SCCB->Sccb_forwardlink = NULL;
7331 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7333 if (currTar_Info->TarSelQ_Cnt == 0) {
7335 currTar_Info->TarSelQ_Head = p_SCCB;
7340 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7344 currTar_Info->TarSelQ_Tail = p_SCCB;
7345 currTar_Info->TarSelQ_Cnt++;
7349 /*---------------------------------------------------------------------
7351 * Function: Queue Find SCCB
7353 * Description: Search the target select Queue for this SCCB, and
7354 * remove it if found.
7356 *---------------------------------------------------------------------*/
7358 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
7361 PSCCBMgr_tar_info currTar_Info;
7363 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7365 q_ptr = currTar_Info->TarSelQ_Head;
7367 while(q_ptr != NULL) {
7369 if (q_ptr == p_SCCB) {
7372 if (currTar_Info->TarSelQ_Head == q_ptr) {
7374 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7377 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7379 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7382 if (q_ptr->Sccb_forwardlink != NULL) {
7383 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7386 if (q_ptr->Sccb_backlink != NULL) {
7387 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7390 currTar_Info->TarSelQ_Cnt--;
7396 q_ptr = q_ptr->Sccb_forwardlink;
7406 /*---------------------------------------------------------------------
7408 * Function: Utility Update Residual Count
7410 * Description: Update the XferCnt to the remaining byte count.
7411 * If we transferred all the data then just write zero.
7412 * If Non-SG transfer then report Total Cnt - Actual Transfer
7413 * Cnt. For SG transfers add the count fields of all
7414 * remaining SG elements, as well as any partial remaining
7417 *---------------------------------------------------------------------*/
7419 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7425 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7427 p_SCCB->DataLength = 0x0000;
7430 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7432 partial_cnt = 0x0000;
7434 sg_index = p_SCCB->Sccb_sgseg;
7436 sg_ptr = (ULONG *)p_SCCB->DataPointer;
7438 if (p_SCCB->Sccb_SGoffset) {
7440 partial_cnt = p_SCCB->Sccb_SGoffset;
7444 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7445 p_SCCB->DataLength ) {
7447 partial_cnt += *(sg_ptr+(sg_index * 2));
7451 p_SCCB->DataLength = partial_cnt;
7456 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7461 /*---------------------------------------------------------------------
7463 * Function: Wait 1 Second
7465 * Description: Wait for 1 second.
7467 *---------------------------------------------------------------------*/
7469 static void FPT_Wait1Second(ULONG p_port)
7473 for(i=0; i < 4; i++) {
7475 FPT_Wait(p_port, TO_250ms);
7477 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7480 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7486 /*---------------------------------------------------------------------
7488 * Function: FPT_Wait
7490 * Description: Wait the desired delay.
7492 *---------------------------------------------------------------------*/
7494 static void FPT_Wait(ULONG p_port, unsigned char p_delay)
7496 unsigned char old_timer;
7497 unsigned char green_flag;
7499 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7501 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7502 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7504 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7505 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7506 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7509 WR_HARPOON(p_port+hp_portctrl_0,
7510 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7512 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7514 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7517 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7521 WR_HARPOON(p_port+hp_portctrl_0,
7522 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7524 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7525 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7527 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7529 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7533 /*---------------------------------------------------------------------
7535 * Function: Enable/Disable Write to EEPROM
7537 * Description: The EEPROM must first be enabled for writes
7538 * A total of 9 clocks are needed.
7540 *---------------------------------------------------------------------*/
7542 static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode)
7544 unsigned char ee_value;
7546 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7550 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7555 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7557 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7558 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7562 /*---------------------------------------------------------------------
7564 * Function: Write EEPROM
7566 * Description: Write a word to the EEPROM at the specified
7569 *---------------------------------------------------------------------*/
7571 static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
7574 unsigned char ee_value;
7577 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7582 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7585 ee_value |= (SEE_MS + SEE_CS);
7587 for(i = 0x8000; i != 0; i>>=1) {
7592 ee_value &= ~SEE_DO;
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 ee_value |= SEE_CLK; /* Clock data! */
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 ee_value &= ~SEE_CLK;
7600 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7601 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7603 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7604 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7606 FPT_Wait(p_port, TO_10ms);
7608 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7609 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7610 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7613 /*---------------------------------------------------------------------
7615 * Function: Read EEPROM
7617 * Description: Read a word from the EEPROM at the desired
7620 *---------------------------------------------------------------------*/
7622 static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
7624 USHORT i, ee_data1, ee_data2;
7627 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7630 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7632 if(ee_data1 == ee_data2)
7635 ee_data1 = ee_data2;
7643 /*---------------------------------------------------------------------
7645 * Function: Read EEPROM Original
7647 * Description: Read a word from the EEPROM at the desired
7650 *---------------------------------------------------------------------*/
7652 static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
7655 unsigned char ee_value;
7658 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7662 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7665 ee_value |= (SEE_MS + SEE_CS);
7668 for(i = 1; i <= 16; i++) {
7670 ee_value |= SEE_CLK; /* Clock data! */
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 ee_value &= ~SEE_CLK;
7674 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7675 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7679 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7683 ee_value &= ~(SEE_MS + SEE_CS);
7684 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7685 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7691 /*---------------------------------------------------------------------
7693 * Function: Send EE command and Address to the EEPROM
7695 * Description: Transfers the correct command and sends the address
7698 *---------------------------------------------------------------------*/
7700 static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, USHORT ee_addr)
7702 unsigned char ee_value;
7703 unsigned char narrow_flg;
7708 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714 ee_value |= SEE_CS; /* Set CS to EEPROM */
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7718 for(i = 0x04; i != 0; i>>=1) {
7723 ee_value &= ~SEE_DO;
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 ee_value |= SEE_CLK; /* Clock data! */
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 ee_value &= ~SEE_CLK;
7731 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7732 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7748 ee_value &= ~SEE_DO;
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 ee_value |= SEE_CLK; /* Clock data! */
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 ee_value &= ~SEE_CLK;
7756 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7757 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7763 static USHORT FPT_CalcCrc16(unsigned char buffer[])
7768 for (i=0; i < ID_STRING_LENGTH; i++)
7770 ch = (USHORT) buffer[i];
7771 for(j=0; j < 8; j++)
7774 crc = (crc >> 1) ^ CRCMASK;
7783 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7788 for(i = 0; i < ID_STRING_LENGTH; i++)
7796 The following inline definitions avoid type conflicts.
7799 static inline unsigned char
7800 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7802 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7806 static inline FlashPoint_CardHandle_T
7807 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7809 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7813 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7815 FlashPoint_ReleaseHostAdapter(CardHandle);
7820 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7822 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7827 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7829 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7833 static inline boolean
7834 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7836 return FlashPoint_InterruptPending(CardHandle);
7841 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7843 return FlashPoint_HandleInterrupt(CardHandle);
7847 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7848 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7849 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7850 #define FlashPoint_StartCCB FlashPoint__StartCCB
7851 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7852 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7853 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7856 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7860 Define prototypes for the FlashPoint SCCB Manager Functions.
7863 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7864 extern FlashPoint_CardHandle_T
7865 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7866 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7867 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7868 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7869 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7870 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7873 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */