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
51 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
52 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
57 typedef struct _SCCB *PSCCB;
58 typedef void (*CALL_BK_FN)(PSCCB);
61 typedef struct SCCBMgr_info {
62 unsigned long si_baseaddr;
63 unsigned char si_present;
64 unsigned char si_intvect;
67 unsigned short si_fw_revision;
68 unsigned short si_per_targ_init_sync;
69 unsigned short si_per_targ_fast_nego;
70 unsigned short si_per_targ_ultra_nego;
71 unsigned short si_per_targ_no_disc;
72 unsigned short si_per_targ_wide_nego;
73 unsigned short si_flags;
74 unsigned char si_card_family;
75 unsigned char si_bustype;
76 unsigned char si_card_model[3];
77 unsigned char si_relative_cardnum;
78 unsigned char si_reserved[4];
79 unsigned long si_OS_reserved;
80 unsigned char si_XlatInfo[4];
81 unsigned long si_reserved2[5];
82 unsigned long si_secondary_range;
85 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
88 #define SCSI_PARITY_ENA 0x0001
89 #define LOW_BYTE_TERM 0x0010
90 #define HIGH_BYTE_TERM 0x0020
91 #define BUSTYPE_PCI 0x3
93 #define SUPPORT_16TAR_32LUN 0x0002
94 #define SOFT_RESET 0x0004
95 #define EXTENDED_TRANSLATION 0x0008
96 #define POST_ALL_UNDERRRUNS 0x0040
97 #define FLAG_SCAM_ENABLED 0x0080
98 #define FLAG_SCAM_LEVEL2 0x0100
103 #define HARPOON_FAMILY 0x02
107 /* SCCB struct used for both SCCB and UCB manager compiles!
108 * The UCB Manager treats the SCCB as it's 'native hardware structure'
113 typedef struct _SCCB {
114 unsigned char OperationCode;
115 unsigned char ControlByte;
116 unsigned char CdbLength;
117 unsigned char RequestSenseLength;
118 unsigned long DataLength;
119 unsigned long DataPointer;
120 unsigned char CcbRes[2];
121 unsigned char HostStatus;
122 unsigned char TargetStatus;
123 unsigned char TargID;
125 unsigned char Cdb[12];
126 unsigned char CcbRes1;
127 unsigned char Reserved1;
128 unsigned long Reserved2;
129 unsigned long SensePointer;
132 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
133 unsigned long SccbIOPort; /* Identifies board base port */
134 unsigned char SccbStatus;
135 unsigned char SCCBRes2;
136 unsigned short SccbOSFlags;
139 unsigned long Sccb_XferCnt; /* actual transfer count */
140 unsigned long Sccb_ATC;
141 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
142 unsigned long Sccb_res1;
143 unsigned short Sccb_MGRFlags;
144 unsigned short Sccb_sgseg;
145 unsigned char Sccb_scsimsg; /* identify msg for selection */
146 unsigned char Sccb_tag;
147 unsigned char Sccb_scsistat;
148 unsigned char Sccb_idmsg; /* image of last msg in */
149 PSCCB Sccb_forwardlink;
151 unsigned long Sccb_savedATC;
152 unsigned char Save_Cdb[6];
153 unsigned char Save_CdbLen;
154 unsigned char Sccb_XferState;
155 unsigned long Sccb_SGoffset;
163 #define SCATTER_GATHER_COMMAND 0x02
164 #define RESIDUAL_COMMAND 0x03
165 #define RESIDUAL_SG_COMMAND 0x04
166 #define RESET_COMMAND 0x81
169 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
170 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
171 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
172 #define SCCB_DATA_XFER_IN 0x08 /* Read */
175 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
178 #define BUS_FREE_ST 0
180 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
181 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
182 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
183 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
185 #define DATA_OUT_ST 7
187 #define DISCONNECT_ST 9
191 #define F_HOST_XFER_DIR 0x01
192 #define F_ALL_XFERRED 0x02
193 #define F_SG_XFER 0x04
194 #define F_AUTO_SENSE 0x08
195 #define F_ODD_BALL_CNT 0x10
196 #define F_NO_DATA_YET 0x80
199 #define F_STATUSLOADED 0x01
200 #define F_DEV_SELECTED 0x04
203 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
204 #define SCCB_DATA_UNDER_RUN 0x0C
205 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
206 #define SCCB_DATA_OVER_RUN 0x12
207 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
209 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
210 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
211 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
217 #define SCCB_IN_PROCESS 0x00
218 #define SCCB_SUCCESS 0x01
219 #define SCCB_ABORT 0x02
220 #define SCCB_ERROR 0x04
224 #define ORION_FW_REV 3110
228 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
230 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
233 #define MAX_SCSI_TAR 16
235 #define LUN_MASK 0x1f
237 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
239 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
242 #define RD_HARPOON(ioport) inb((u32)ioport)
243 #define RDW_HARPOON(ioport) inw((u32)ioport)
244 #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
245 #define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
246 #define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
247 #define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
250 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
251 #define SYNC_TRYING BIT(6)
252 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
254 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
255 #define WIDE_ENABLED BIT(4)
256 #define WIDE_NEGOCIATED BIT(5)
258 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
259 #define TAG_Q_TRYING BIT(2)
260 #define TAG_Q_REJECT BIT(3)
262 #define TAR_ALLOW_DISC BIT(0)
265 #define EE_SYNC_MASK (BIT(0)+BIT(1))
266 #define EE_SYNC_5MB BIT(0)
267 #define EE_SYNC_10MB BIT(1)
268 #define EE_SYNC_20MB (BIT(0)+BIT(1))
270 #define EE_WIDE_SCSI BIT(7)
273 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
276 typedef struct SCCBMgr_tar_info {
280 unsigned char TarLUN_CA; /*Contingent Allgiance */
281 unsigned char TarTagQ_Cnt;
282 unsigned char TarSelQ_Cnt;
283 unsigned char TarStatus;
284 unsigned char TarEEValue;
285 unsigned char TarSyncCtrl;
286 unsigned char TarReserved[2]; /* for alignment */
287 unsigned char LunDiscQ_Idx[MAX_LUN];
288 unsigned char TarLUNBusy[MAX_LUN];
291 typedef struct NVRAMInfo {
292 unsigned char niModel; /* Model No. of card */
293 unsigned char niCardNo; /* Card no. */
294 unsigned long niBaseAddr; /* Port Address of card */
295 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
296 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
297 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
298 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
299 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
300 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
303 typedef NVRAMINFO *PNVRamInfo;
311 typedef struct SCCBcard {
313 PSCCBMGR_INFO cardInfo;
315 unsigned long ioPort;
317 unsigned short cmdCounter;
318 unsigned char discQCount;
319 unsigned char tagQ_Lst;
320 unsigned char cardIndex;
321 unsigned char scanIndex;
322 unsigned char globalFlags;
324 PNVRamInfo pNvRamInfo;
325 PSCCB discQ_Tbl[QUEUE_DEPTH];
329 typedef struct SCCBcard *PSCCBcard;
332 #define F_TAG_STARTED 0x01
333 #define F_CONLUN_IO 0x02
334 #define F_DO_RENEGO 0x04
335 #define F_NO_FILTER 0x08
336 #define F_GREEN_PC 0x10
337 #define F_HOST_XFER_ACT 0x20
338 #define F_NEW_SCCB_CMD 0x40
339 #define F_UPDATE_EEPROM 0x80
342 #define ID_STRING_LENGTH 32
343 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
346 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
348 #define ASSIGN_ID 0x00
349 #define SET_P_FLAG 0x01
350 #define CFG_CMPLT 0x03
351 #define DOM_MSTR 0x0F
352 #define SYNC_PTRN 0x1F
356 #define MISC_CODE 0x14
357 #define CLR_P_FLAG 0x18
361 #define INIT_SELTD 0x01
362 #define LEVEL2_TAR 0x02
365 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
366 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
367 CLR_PRIORITY,NO_ID_AVAIL };
369 typedef struct SCCBscam_info {
371 unsigned char id_string[ID_STRING_LENGTH];
372 enum scam_id_st state;
377 #define SCSI_REQUEST_SENSE 0x03
378 #define SCSI_READ 0x08
379 #define SCSI_WRITE 0x0A
380 #define SCSI_START_STOP_UNIT 0x1B
381 #define SCSI_READ_EXTENDED 0x28
382 #define SCSI_WRITE_EXTENDED 0x2A
383 #define SCSI_WRITE_AND_VERIFY 0x2E
389 #define SSQ_FULL 0x28
394 #define SMCMD_COMP 0x00
396 #define SMSAVE_DATA_PTR 0x02
397 #define SMREST_DATA_PTR 0x03
400 #define SMREJECT 0x07
402 #define SMPARITY 0x09
403 #define SMDEV_RESET 0x0C
404 #define SMABORT_TAG 0x0D
405 #define SMINIT_RECOVERY 0x0F
406 #define SMREL_RECOVERY 0x10
409 #define DISC_PRIV 0x40
416 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
425 #define SIX_BYTE_CMD 0x06
426 #define TWELVE_BYTE_CMD 0x0C
429 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
432 #define EEPROM_WD_CNT 256
434 #define EEPROM_CHECK_SUM 0
435 #define FW_SIGNATURE 2
436 #define MODEL_NUMB_0 4
437 #define MODEL_NUMB_2 6
438 #define MODEL_NUMB_4 8
439 #define SYSTEM_CONFIG 16
440 #define SCSI_CONFIG 17
441 #define BIOS_CONFIG 18
442 #define SCAM_CONFIG 20
443 #define ADAPTER_SCSI_ID 24
446 #define IGNORE_B_SCAN 32
447 #define SEND_START_ENA 34
448 #define DEVICE_ENABLE 36
450 #define SYNC_RATE_TBL 38
451 #define SYNC_RATE_TBL01 38
452 #define SYNC_RATE_TBL23 40
453 #define SYNC_RATE_TBL45 42
454 #define SYNC_RATE_TBL67 44
455 #define SYNC_RATE_TBL89 46
456 #define SYNC_RATE_TBLab 48
457 #define SYNC_RATE_TBLcd 50
458 #define SYNC_RATE_TBLef 52
462 #define EE_SCAMBASE 256
466 #define SCAM_ENABLED BIT(2)
467 #define SCAM_LEVEL2 BIT(3)
470 #define RENEGO_ENA BITW(10)
471 #define CONNIO_ENA BITW(11)
472 #define GREEN_PC_ENA BITW(12)
475 #define AUTO_RATE_00 00
476 #define AUTO_RATE_05 01
477 #define AUTO_RATE_10 02
478 #define AUTO_RATE_20 03
480 #define WIDE_NEGO_BIT BIT(7)
481 #define DISC_ENABLE_BIT BIT(6)
485 #define hp_vendor_id_0 0x00 /* LSB */
486 #define ORION_VEND_0 0x4B
488 #define hp_vendor_id_1 0x01 /* MSB */
489 #define ORION_VEND_1 0x10
491 #define hp_device_id_0 0x02 /* LSB */
492 #define ORION_DEV_0 0x30
494 #define hp_device_id_1 0x03 /* MSB */
495 #define ORION_DEV_1 0x81
497 /* Sub Vendor ID and Sub Device ID only available in
498 Harpoon Version 2 and higher */
500 #define hp_sub_device_id_0 0x06 /* LSB */
504 #define hp_semaphore 0x0C
505 #define SCCB_MGR_ACTIVE BIT(0)
506 #define TICKLE_ME BIT(1)
507 #define SCCB_MGR_PRESENT BIT(3)
508 #define BIOS_IN_USE BIT(4)
512 #define hp_sys_ctrl 0x0F
514 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
515 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
516 #define HALT_MACH BIT(3) /*Halt State Machine */
517 #define HARD_ABORT BIT(4) /*Hard Abort */
527 #define hp_host_blk_cnt 0x13
529 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
531 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
535 #define hp_int_mask 0x17
537 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
538 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
541 #define hp_xfer_cnt_lo 0x18
542 #define hp_xfer_cnt_hi 0x1A
543 #define hp_xfer_cmd 0x1B
545 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
546 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
549 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
551 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
553 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
555 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
556 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
558 #define hp_host_addr_lo 0x1C
559 #define hp_host_addr_hmi 0x1E
561 #define hp_ee_ctrl 0x22
563 #define EXT_ARB_ACK BIT(7)
564 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
565 #define SEE_MS BIT(5)
566 #define SEE_CS BIT(3)
567 #define SEE_CLK BIT(2)
568 #define SEE_DO BIT(1)
569 #define SEE_DI BIT(0)
572 #define EE_WRITE 0x05
574 #define EWEN_ADDR 0x03C0
576 #define EWDS_ADDR 0x0000
584 #define hp_bm_ctrl 0x26
586 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
587 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
588 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
589 #define FAST_SINGLE BIT(6) /*?? */
591 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
594 #define hp_sg_addr 0x28
595 #define hp_page_ctrl 0x29
597 #define SCATTER_EN BIT(0)
598 #define SGRAM_ARAM BIT(1)
599 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
600 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
605 #define hp_pci_stat_cfg 0x2D
607 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
616 #define hp_rev_num 0x33
619 #define hp_stack_data 0x34
620 #define hp_stack_addr 0x35
622 #define hp_ext_status 0x36
624 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
625 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
626 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
627 #define CMD_ABORTED BIT(4) /*Command aborted */
628 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
629 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
630 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
631 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
632 BM_PARITY_ERR | PIO_OVERRUN)
634 #define hp_int_status 0x37
636 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
637 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
638 #define INT_ASSERTED BIT(5) /* */
641 #define hp_fifo_cnt 0x38
646 #define hp_intena 0x40
648 #define RESET BITW(7)
649 #define PROG_HLT BITW(6)
650 #define PARITY BITW(5)
653 #define SCAM_SEL BITW(2)
655 #define TIMEOUT BITW(0)
656 #define BUS_FREE BITW(15)
657 #define XFER_CNT_0 BITW(14)
658 #define PHASE BITW(13)
659 #define IUNKWN BITW(12)
660 #define ICMD_COMP BITW(11)
661 #define ITICKLE BITW(10)
662 #define IDO_STRT BITW(9)
663 #define ITAR_DISC BITW(8)
664 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
665 #define CLR_ALL_INT 0xFFFF
666 #define CLR_ALL_INT_1 0xFF00
668 #define hp_intstat 0x42
670 #define hp_scsisig 0x44
672 #define SCSI_SEL BIT(7)
673 #define SCSI_BSY BIT(6)
674 #define SCSI_REQ BIT(5)
675 #define SCSI_ACK BIT(4)
676 #define SCSI_ATN BIT(3)
677 #define SCSI_CD BIT(2)
678 #define SCSI_MSG BIT(1)
679 #define SCSI_IOBIT BIT(0)
681 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
682 #define S_MSGO_PH (BIT(2)+BIT(1) )
683 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
684 #define S_DATAI_PH ( BIT(0))
685 #define S_DATAO_PH 0x00
686 #define S_ILL_PH ( BIT(1) )
688 #define hp_scsictrl_0 0x45
690 #define SEL_TAR BIT(6)
691 #define ENA_ATN BIT(4)
692 #define ENA_RESEL BIT(2)
693 #define SCSI_RST BIT(1)
694 #define ENA_SCAM_SEL BIT(0)
698 #define hp_portctrl_0 0x46
700 #define SCSI_PORT BIT(7)
701 #define SCSI_INBIT BIT(6)
702 #define DMA_PORT BIT(5)
703 #define DMA_RD BIT(4)
704 #define HOST_PORT BIT(3)
705 #define HOST_WRT BIT(2)
706 #define SCSI_BUS_EN BIT(1)
707 #define START_TO BIT(0)
709 #define hp_scsireset 0x47
711 #define SCSI_INI BIT(6)
712 #define SCAM_EN BIT(5)
713 #define DMA_RESET BIT(3)
714 #define HPSCSI_RESET BIT(2)
715 #define PROG_RESET BIT(1)
716 #define FIFO_CLR BIT(0)
718 #define hp_xfercnt_0 0x48
719 #define hp_xfercnt_2 0x4A
721 #define hp_fifodata_0 0x4C
722 #define hp_addstat 0x4E
724 #define SCAM_TIMER BIT(7)
725 #define SCSI_MODE8 BIT(3)
726 #define SCSI_PAR_ERR BIT(0)
728 #define hp_prgmcnt_0 0x4F
731 #define hp_selfid_0 0x50
732 #define hp_selfid_1 0x51
733 #define hp_arb_id 0x52
736 #define hp_select_id 0x53
739 #define hp_synctarg_base 0x54
740 #define hp_synctarg_12 0x54
741 #define hp_synctarg_13 0x55
742 #define hp_synctarg_14 0x56
743 #define hp_synctarg_15 0x57
745 #define hp_synctarg_8 0x58
746 #define hp_synctarg_9 0x59
747 #define hp_synctarg_10 0x5A
748 #define hp_synctarg_11 0x5B
750 #define hp_synctarg_4 0x5C
751 #define hp_synctarg_5 0x5D
752 #define hp_synctarg_6 0x5E
753 #define hp_synctarg_7 0x5F
755 #define hp_synctarg_0 0x60
756 #define hp_synctarg_1 0x61
757 #define hp_synctarg_2 0x62
758 #define hp_synctarg_3 0x63
760 #define NARROW_SCSI BIT(4)
761 #define DEFAULT_OFFSET 0x0F
763 #define hp_autostart_0 0x64
764 #define hp_autostart_1 0x65
765 #define hp_autostart_3 0x67
769 #define AUTO_IMMED BIT(5)
770 #define SELECT BIT(6)
771 #define END_DATA (BIT(7)+BIT(6))
773 #define hp_gp_reg_0 0x68
774 #define hp_gp_reg_1 0x69
775 #define hp_gp_reg_3 0x6B
777 #define hp_seltimeout 0x6C
780 #define TO_4ms 0x67 /* 3.9959ms */
782 #define TO_5ms 0x03 /* 4.9152ms */
783 #define TO_10ms 0x07 /* 11.xxxms */
784 #define TO_250ms 0x99 /* 250.68ms */
785 #define TO_290ms 0xB1 /* 289.99ms */
787 #define hp_clkctrl_0 0x6D
789 #define PWR_DWN BIT(6)
790 #define ACTdeassert BIT(4)
791 #define CLK_40MHZ (BIT(1) + BIT(0))
793 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
795 #define hp_fiforead 0x6E
796 #define hp_fifowrite 0x6F
798 #define hp_offsetctr 0x70
799 #define hp_xferstat 0x71
801 #define FIFO_EMPTY BIT(6)
803 #define hp_portctrl_1 0x72
805 #define CHK_SCSI_P BIT(3)
806 #define HOST_MODE8 BIT(0)
808 #define hp_xfer_pad 0x73
810 #define ID_UNLOCK BIT(3)
812 #define hp_scsidata_0 0x74
813 #define hp_scsidata_1 0x75
817 #define hp_aramBase 0x80
818 #define BIOS_DATA_OFFSET 0x60
819 #define BIOS_RELATIVE_CARD 0x64
824 #define AR3 (BITW(9) + BITW(8))
825 #define SDATA BITW(10)
828 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
830 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
834 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
836 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
839 #define ADATA_OUT 0x00
840 #define ADATA_IN BITW(8)
841 #define ACOMMAND BITW(10)
842 #define ASTATUS (BITW(10)+BITW(8))
843 #define AMSG_OUT (BITW(10)+BITW(9))
844 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
847 #define BRH_OP BITW(13) /* Branch */
851 #define EQUAL BITW(8)
852 #define NOT_EQ BITW(9)
854 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
857 #define FIFO_0 BITW(10)
860 #define MPM_OP BITW(15) /* Match phase and move data */
863 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
866 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
871 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
881 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
883 #define SSI_OP (BITW(15)+BITW(11))
886 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
887 #define SSI_IDO_STRT (IDO_STRT >> 8)
889 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
890 #define SSI_ITICKLE (ITICKLE >> 8)
892 #define SSI_IUNKWN (IUNKWN >> 8)
893 #define SSI_INO_CC (IUNKWN >> 8)
894 #define SSI_IRFAIL (IUNKWN >> 8)
897 #define NP 0x10 /*Next Phase */
898 #define NTCMD 0x02 /*Non- Tagged Command start */
899 #define CMDPZ 0x04 /*Command phase */
900 #define DINT 0x12 /*Data Out/In interrupt */
901 #define DI 0x13 /*Data Out */
902 #define DC 0x19 /*Disconnect Message */
903 #define ST 0x1D /*Status Phase */
904 #define UNKNWN 0x24 /*Unknown bus action */
905 #define CC 0x25 /*Command Completion failure */
906 #define TICK 0x26 /*New target reselected us. */
907 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
910 #define ID_MSG_STRT hp_aramBase + 0x00
911 #define NON_TAG_ID_MSG hp_aramBase + 0x06
912 #define CMD_STRT hp_aramBase + 0x08
913 #define SYNC_MSGS hp_aramBase + 0x08
919 #define TAG_STRT 0x00
920 #define DISCONNECT_START 0x10/2
921 #define END_DATA_START 0x14/2
922 #define CMD_ONLY_STRT CMDPZ/2
923 #define SELCHK_STRT SELCHK/2
933 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
934 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
936 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
938 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
940 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
941 WR_HARP32(port,hp_xfercnt_0,count),\
942 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
944 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
946 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
947 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
950 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
951 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
955 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
956 WR_HARPOON(port+hp_scsireset, 0x00))
958 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
959 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
961 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
962 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
964 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
965 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
967 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
968 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
973 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
974 static void FPT_ssel(unsigned long port, unsigned char p_card);
975 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
976 static void FPT_shandem(unsigned long port, unsigned char p_card,PSCCB pCurrSCCB);
977 static void FPT_stsyncn(unsigned long port, unsigned char p_card);
978 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
979 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
980 PSCCBMgr_tar_info currTar_Info);
981 static void FPT_sresb(unsigned long port, unsigned char p_card);
982 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
983 static void FPT_schkdd(unsigned long port, unsigned char p_card);
984 static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
985 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
986 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
988 static void FPT_SendMsg(unsigned long port, unsigned char message);
989 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
990 unsigned char error_code);
992 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
993 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
995 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
996 static void FPT_stwidn(unsigned long port, unsigned char p_card);
997 static void FPT_siwidr(unsigned long port, unsigned char width);
1000 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1001 static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
1002 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1003 unsigned char p_card);
1004 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1005 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1006 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1007 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
1008 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1009 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1010 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1013 static void FPT_Wait1Second(unsigned long p_port);
1014 static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1015 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1016 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1017 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1018 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1019 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
1023 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1024 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1025 static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1026 static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1027 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1028 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1029 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
1031 static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1032 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1033 static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
1038 static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1039 static void FPT_BusMasterInit(unsigned long p_port);
1040 static void FPT_DiagEEPROM(unsigned long p_port);
1045 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1046 static void FPT_busMstrSGDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1047 static void FPT_busMstrDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1048 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB);
1049 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1052 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
1053 PSCCBcard pCurrCard, unsigned short p_int);
1055 static void FPT_SccbMgrTableInitAll(void);
1056 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1057 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1061 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1063 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1064 static void FPT_scbusf(unsigned long p_port);
1065 static void FPT_scsel(unsigned long p_port);
1066 static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1067 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1068 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1069 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1070 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1071 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
1072 static unsigned char FPT_scvalq(unsigned char p_quintet);
1073 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1074 static void FPT_scwtsel(unsigned long p_port);
1075 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1076 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
1077 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1080 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1081 static void FPT_autoLoadDefaultMap(unsigned long p_port);
1086 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1087 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1088 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1089 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1092 static unsigned char FPT_mbCards = 0;
1093 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1094 ' ', 'B', 'T', '-', '9', '3', '0', \
1095 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1096 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1098 static unsigned short FPT_default_intena = 0;
1101 static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
1104 /*---------------------------------------------------------------------
1106 * Function: FlashPoint_ProbeHostAdapter
1108 * Description: Setup and/or Search for cards and return info to caller.
1110 *---------------------------------------------------------------------*/
1112 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1114 static unsigned char first_time = 1;
1116 unsigned char i,j,id,ScamFlg;
1117 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1118 unsigned long ioport;
1119 PNVRamInfo pCurrNvRam;
1121 ioport = pCardInfo->si_baseaddr;
1124 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1125 return((int)FAILURE);
1127 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1128 return((int)FAILURE);
1130 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1131 return((int)FAILURE);
1133 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1134 return((int)FAILURE);
1137 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1139 /* For new Harpoon then check for sub_device ID LSB
1140 the bits(0-3) must be all ZERO for compatible with
1141 current version of SCCBMgr, else skip this Harpoon
1144 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1145 return((int)FAILURE);
1150 FPT_SccbMgrTableInitAll();
1155 if(FPT_RdStack(ioport, 0) != 0x00) {
1156 if(FPT_ChkIfChipInitialized(ioport) == 0)
1159 WR_HARPOON(ioport+hp_semaphore, 0x00);
1160 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1161 FPT_DiagEEPROM(ioport);
1165 if(FPT_mbCards < MAX_MB_CARDS) {
1166 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1168 pCurrNvRam->niBaseAddr = ioport;
1169 FPT_RNVRamData(pCurrNvRam);
1171 return((int) FAILURE);
1176 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1177 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1180 pCardInfo->si_id = pCurrNvRam->niAdapId;
1182 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1183 (unsigned char)0x0FF);
1185 pCardInfo->si_lun = 0x00;
1186 pCardInfo->si_fw_revision = ORION_FW_REV;
1193 for (id = 0; id < (16/2); id++) {
1196 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1197 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1198 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1200 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1202 for (i = 0; i < 2; temp >>=8,i++) {
1211 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1212 temp6 |= 0x8000; /* Fall through */
1213 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1214 temp5 |= 0x8000; /* Fall through */
1215 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1216 temp2 |= 0x8000; /* Fall through */
1217 case AUTO_RATE_00: /* Asynchronous */
1221 if (temp & DISC_ENABLE_BIT)
1224 if (temp & WIDE_NEGO_BIT)
1230 pCardInfo->si_per_targ_init_sync = temp2;
1231 pCardInfo->si_per_targ_no_disc = temp3;
1232 pCardInfo->si_per_targ_wide_nego = temp4;
1233 pCardInfo->si_per_targ_fast_nego = temp5;
1234 pCardInfo->si_per_targ_ultra_nego = temp6;
1237 i = pCurrNvRam->niSysConf;
1239 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1242 ScamFlg = pCurrNvRam->niScamConf;
1244 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1246 pCardInfo->si_flags = 0x0000;
1249 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1252 pCardInfo->si_flags |= SOFT_RESET;
1255 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1257 if (ScamFlg & SCAM_ENABLED)
1258 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1260 if (ScamFlg & SCAM_LEVEL2)
1261 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1263 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1265 j |= SCSI_TERM_ENA_L;
1267 WR_HARPOON(ioport+hp_bm_ctrl, j );
1269 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1271 j |= SCSI_TERM_ENA_H;
1273 WR_HARPOON(ioport+hp_ee_ctrl, j );
1275 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1277 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1279 pCardInfo->si_card_family = HARPOON_FAMILY;
1280 pCardInfo->si_bustype = BUSTYPE_PCI;
1283 pCardInfo->si_card_model[0] = '9';
1284 switch(pCurrNvRam->niModel & 0x0f){
1286 pCardInfo->si_card_model[1] = '3';
1287 pCardInfo->si_card_model[2] = '0';
1290 pCardInfo->si_card_model[1] = '5';
1291 pCardInfo->si_card_model[2] = '0';
1294 pCardInfo->si_card_model[1] = '3';
1295 pCardInfo->si_card_model[2] = '2';
1298 pCardInfo->si_card_model[1] = '5';
1299 pCardInfo->si_card_model[2] = '2';
1303 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1304 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1305 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1307 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1308 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1311 if (pCardInfo->si_card_model[1] == '3')
1313 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1314 pCardInfo->si_flags |= LOW_BYTE_TERM;
1316 else if (pCardInfo->si_card_model[2] == '0')
1318 temp = RD_HARPOON(ioport+hp_xfer_pad);
1319 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1320 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1321 pCardInfo->si_flags |= LOW_BYTE_TERM;
1322 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1323 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1324 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1325 WR_HARPOON(ioport+hp_xfer_pad, temp);
1329 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1330 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1331 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1332 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1334 for (i = 0; i < 8; i++)
1337 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1339 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1340 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1342 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1343 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1344 if (!(temp3 & BIT(7)))
1345 pCardInfo->si_flags |= LOW_BYTE_TERM;
1346 if (!(temp3 & BIT(6)))
1347 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1351 ARAM_ACCESS(ioport);
1353 for ( i = 0; i < 4; i++ ) {
1355 pCardInfo->si_XlatInfo[i] =
1356 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1359 /* return with -1 if no sort, else return with
1360 logical card number sorted by BIOS (zero-based) */
1362 pCardInfo->si_relative_cardnum =
1363 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1365 SGRAM_ACCESS(ioport);
1367 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1368 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1369 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1370 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1371 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1372 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1373 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1374 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1376 pCardInfo->si_present = 0x01;
1382 /*---------------------------------------------------------------------
1384 * Function: FlashPoint_HardwareResetHostAdapter
1386 * Description: Setup adapter for normal operation (hard reset).
1388 *---------------------------------------------------------------------*/
1390 static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1392 PSCCBcard CurrCard = NULL;
1393 PNVRamInfo pCurrNvRam;
1394 unsigned char i,j,thisCard, ScamFlg;
1395 unsigned short temp,sync_bit_map,id;
1396 unsigned long ioport;
1398 ioport = pCardInfo->si_baseaddr;
1400 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1402 if (thisCard == MAX_CARDS) {
1407 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1409 CurrCard = &FPT_BL_Card[thisCard];
1410 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1414 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1416 FPT_BL_Card[thisCard].ioPort = ioport;
1417 CurrCard = &FPT_BL_Card[thisCard];
1420 for(i = 0; i < FPT_mbCards; i++){
1421 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1422 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1424 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1425 CurrCard->cardIndex = thisCard;
1426 CurrCard->cardInfo = pCardInfo;
1432 pCurrNvRam = CurrCard->pNvRamInfo;
1435 ScamFlg = pCurrNvRam->niScamConf;
1438 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1442 FPT_BusMasterInit(ioport);
1443 FPT_XbowInit(ioport, ScamFlg);
1445 FPT_autoLoadDefaultMap(ioport);
1448 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1450 WR_HARPOON(ioport+hp_selfid_0, id);
1451 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1452 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1453 CurrCard->ourId = pCardInfo->si_id;
1455 i = (unsigned char) pCardInfo->si_flags;
1456 if (i & SCSI_PARITY_ENA)
1457 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1459 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1460 if (i & LOW_BYTE_TERM)
1461 j |= SCSI_TERM_ENA_L;
1462 WR_HARPOON(ioport+hp_bm_ctrl, j);
1464 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1465 if (i & HIGH_BYTE_TERM)
1466 j |= SCSI_TERM_ENA_H;
1467 WR_HARPOON(ioport+hp_ee_ctrl, j );
1470 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1472 FPT_sresb(ioport,thisCard);
1474 FPT_scini(thisCard, pCardInfo->si_id, 0);
1479 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1480 CurrCard->globalFlags |= F_NO_FILTER;
1483 if(pCurrNvRam->niSysConf & 0x10)
1484 CurrCard->globalFlags |= F_GREEN_PC;
1487 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1488 CurrCard->globalFlags |= F_GREEN_PC;
1491 /* Set global flag to indicate Re-Negotiation to be done on all
1494 if(pCurrNvRam->niScsiConf & 0x04)
1495 CurrCard->globalFlags |= F_DO_RENEGO;
1498 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1499 CurrCard->globalFlags |= F_DO_RENEGO;
1503 if(pCurrNvRam->niScsiConf & 0x08)
1504 CurrCard->globalFlags |= F_CONLUN_IO;
1507 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1508 CurrCard->globalFlags |= F_CONLUN_IO;
1512 temp = pCardInfo->si_per_targ_no_disc;
1514 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1517 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1520 sync_bit_map = 0x0001;
1522 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1525 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1526 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1527 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1529 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1531 for (i = 0; i < 2; temp >>=8,i++) {
1533 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1535 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1539 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1540 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1541 (unsigned char)(temp & ~EE_SYNC_MASK);
1544 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1547 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1549 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1553 else { /* NARROW SCSI */
1554 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1565 WR_HARPOON((ioport+hp_semaphore),
1566 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1568 return((unsigned long)CurrCard);
1571 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1574 unsigned long portBase;
1575 unsigned long regOffset;
1576 unsigned long scamData;
1577 unsigned long *pScamTbl;
1578 PNVRamInfo pCurrNvRam;
1580 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1584 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1585 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1586 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1587 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1589 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1590 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1592 portBase = pCurrNvRam->niBaseAddr;
1594 for(i = 0; i < MAX_SCSI_TAR; i++){
1595 regOffset = hp_aramBase + 64 + i*4;
1596 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
1597 scamData = *pScamTbl;
1598 WR_HARP32(portBase, regOffset, scamData);
1602 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1607 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1610 unsigned long portBase;
1611 unsigned long regOffset;
1612 unsigned long scamData;
1613 unsigned long *pScamTbl;
1615 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1616 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1617 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1618 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1619 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1621 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1622 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1624 portBase = pNvRamInfo->niBaseAddr;
1626 for(i = 0; i < MAX_SCSI_TAR; i++){
1627 regOffset = hp_aramBase + 64 + i*4;
1628 RD_HARP32(portBase, regOffset, scamData);
1629 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
1630 *pScamTbl = scamData;
1635 static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1637 WR_HARPOON(portBase + hp_stack_addr, index);
1638 return(RD_HARPOON(portBase + hp_stack_data));
1641 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
1643 WR_HARPOON(portBase + hp_stack_addr, index);
1644 WR_HARPOON(portBase + hp_stack_data, data);
1648 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1650 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1652 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1655 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1656 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1661 /*---------------------------------------------------------------------
1663 * Function: FlashPoint_StartCCB
1665 * Description: Start a command pointed to by p_Sccb. When the
1666 * command is completed it will be returned via the
1667 * callback function.
1669 *---------------------------------------------------------------------*/
1670 static void FlashPoint_StartCCB(unsigned long pCurrCard, PSCCB p_Sccb)
1672 unsigned long ioport;
1673 unsigned char thisCard, lun;
1675 CALL_BK_FN callback;
1677 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1678 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1680 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1683 p_Sccb->HostStatus = SCCB_COMPLETE;
1684 p_Sccb->SccbStatus = SCCB_ERROR;
1685 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1692 FPT_sinits(p_Sccb,thisCard);
1695 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1697 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1698 | SCCB_MGR_ACTIVE));
1700 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1702 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1703 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1707 ((PSCCBcard)pCurrCard)->cmdCounter++;
1709 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1711 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1713 if(p_Sccb->OperationCode == RESET_COMMAND)
1715 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1716 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1717 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1718 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1722 FPT_queueAddSccb(p_Sccb,thisCard);
1726 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1728 if(p_Sccb->OperationCode == RESET_COMMAND)
1730 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1731 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1732 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1733 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1737 FPT_queueAddSccb(p_Sccb,thisCard);
1743 MDISABLE_INT(ioport);
1745 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1746 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1750 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1751 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1752 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1755 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1756 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1761 if(p_Sccb->OperationCode == RESET_COMMAND)
1763 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1764 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1765 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1766 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1770 FPT_queueAddSccb(p_Sccb,thisCard);
1775 MENABLE_INT(ioport);
1781 /*---------------------------------------------------------------------
1783 * Function: FlashPoint_AbortCCB
1785 * Description: Abort the command pointed to by p_Sccb. When the
1786 * command is completed it will be returned via the
1787 * callback function.
1789 *---------------------------------------------------------------------*/
1790 static int FlashPoint_AbortCCB(unsigned long pCurrCard, PSCCB p_Sccb)
1792 unsigned long ioport;
1794 unsigned char thisCard;
1795 CALL_BK_FN callback;
1798 PSCCBMgr_tar_info currTar_Info;
1801 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1803 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1805 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1808 if (FPT_queueFindSccb(p_Sccb,thisCard))
1811 ((PSCCBcard)pCurrCard)->cmdCounter--;
1813 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1814 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1815 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1817 p_Sccb->SccbStatus = SCCB_ABORT;
1818 callback = p_Sccb->SccbCallback;
1826 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1828 p_Sccb->SccbStatus = SCCB_ABORT;
1836 TID = p_Sccb->TargID;
1839 if(p_Sccb->Sccb_tag)
1841 MDISABLE_INT(ioport);
1842 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1844 p_Sccb->SccbStatus = SCCB_ABORT;
1845 p_Sccb->Sccb_scsistat = ABORT_ST;
1846 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1848 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1850 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1851 FPT_ssel(ioport, thisCard);
1855 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1856 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1857 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1858 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1861 MENABLE_INT(ioport);
1866 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1868 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1871 p_Sccb->SccbStatus = SCCB_ABORT;
1882 /*---------------------------------------------------------------------
1884 * Function: FlashPoint_InterruptPending
1886 * Description: Do a quick check to determine if there is a pending
1887 * interrupt for this card and disable the IRQ Pin if so.
1889 *---------------------------------------------------------------------*/
1890 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1892 unsigned long ioport;
1894 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1896 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1908 /*---------------------------------------------------------------------
1910 * Function: FlashPoint_HandleInterrupt
1912 * Description: This is our entry point when an interrupt is generated
1913 * by the card and the upper level driver passes it on to
1916 *---------------------------------------------------------------------*/
1917 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1920 unsigned char thisCard,result,bm_status, bm_int_st;
1921 unsigned short hp_int;
1922 unsigned char i, target;
1923 unsigned long ioport;
1925 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1926 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1928 MDISABLE_INT(ioport);
1930 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1931 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1935 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1937 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1941 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1943 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1944 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1945 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1950 MENABLE_INT(ioport);
1956 else if (hp_int & ICMD_COMP) {
1958 if ( !(hp_int & BUS_FREE) ) {
1959 /* Wait for the BusFree before starting a new command. We
1960 must also check for being reselected since the BusFree
1961 may not show up if another device reselects us in 1.5us or
1962 less. SRR Wednesday, 3/8/1995.
1964 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1967 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1969 FPT_phaseChkFifo(ioport, thisCard);
1971 /* WRW_HARPOON((ioport+hp_intstat),
1972 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1975 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1977 FPT_autoCmdCmplt(ioport,thisCard);
1982 else if (hp_int & ITAR_DISC)
1985 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1987 FPT_phaseChkFifo(ioport, thisCard);
1991 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1993 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1994 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1996 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1999 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2000 FPT_queueDisconnect(currSCCB,thisCard);
2002 /* Wait for the BusFree before starting a new command. We
2003 must also check for being reselected since the BusFree
2004 may not show up if another device reselects us in 1.5us or
2005 less. SRR Wednesday, 3/8/1995.
2007 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2008 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2009 RD_HARPOON((ioport+hp_scsisig)) ==
2010 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2013 The additional loop exit condition above detects a timing problem
2014 with the revision D/E harpoon chips. The caller should reset the
2015 host adapter to recover when 0xFE is returned.
2017 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2019 MENABLE_INT(ioport);
2023 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2026 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2031 else if (hp_int & RSEL) {
2033 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2035 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2037 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2039 FPT_phaseChkFifo(ioport, thisCard);
2042 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2044 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2045 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2046 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2049 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2050 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2051 FPT_queueDisconnect(currSCCB,thisCard);
2054 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2055 FPT_phaseDecode(ioport,thisCard);
2060 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2063 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2064 FPT_phaseDecode(ioport,thisCard);
2069 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2071 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2072 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2074 FPT_phaseDecode(ioport,thisCard);
2078 /* Harpoon problem some SCSI target device respond to selection
2079 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2080 to latch the correct Target ID into reg. x53.
2081 The work around require to correct this reg. But when write to this
2082 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2083 need to read this reg first then restore it later. After update to 0x53 */
2085 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2086 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2087 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2088 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2089 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2090 WR_HARPOON(ioport+hp_fifowrite, i);
2091 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2095 else if (hp_int & XFER_CNT_0) {
2097 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2099 FPT_schkdd(ioport,thisCard);
2104 else if (hp_int & BUS_FREE) {
2106 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2108 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2110 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2113 FPT_phaseBusFree(ioport,thisCard);
2117 else if (hp_int & ITICKLE) {
2119 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2120 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2125 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2128 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2131 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2133 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2136 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2137 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2138 FPT_ssel(ioport,thisCard);
2147 MENABLE_INT(ioport);
2152 /*---------------------------------------------------------------------
2154 * Function: Sccb_bad_isr
2156 * Description: Some type of interrupt has occurred which is slightly
2157 * out of the ordinary. We will now decode it fully, in
2158 * this routine. This is broken up in an attempt to save
2161 *---------------------------------------------------------------------*/
2162 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
2163 PSCCBcard pCurrCard, unsigned short p_int)
2165 unsigned char temp, ScamFlg;
2166 PSCCBMgr_tar_info currTar_Info;
2167 PNVRamInfo pCurrNvRam;
2170 if (RD_HARPOON(p_port+hp_ext_status) &
2171 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2174 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2177 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2180 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2183 WR_HARPOON(p_port+hp_pci_stat_cfg,
2184 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2186 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2190 if (pCurrCard->currentSCCB != NULL)
2193 if (!pCurrCard->currentSCCB->HostStatus)
2194 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2196 FPT_sxfrp(p_port,p_card);
2198 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2199 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2200 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2201 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2203 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2205 FPT_phaseDecode(p_port,p_card);
2211 else if (p_int & RESET)
2214 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2215 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2216 if (pCurrCard->currentSCCB != NULL) {
2218 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2220 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2224 DISABLE_AUTO(p_port);
2226 FPT_sresb(p_port,p_card);
2228 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2230 pCurrNvRam = pCurrCard->pNvRamInfo;
2232 ScamFlg = pCurrNvRam->niScamConf;
2235 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2238 FPT_XbowInit(p_port, ScamFlg);
2240 FPT_scini(p_card, pCurrCard->ourId, 0);
2246 else if (p_int & FIFO) {
2248 WRW_HARPOON((p_port+hp_intstat), FIFO);
2250 if (pCurrCard->currentSCCB != NULL)
2251 FPT_sxfrp(p_port,p_card);
2254 else if (p_int & TIMEOUT)
2257 DISABLE_AUTO(p_port);
2259 WRW_HARPOON((p_port+hp_intstat),
2260 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2262 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2265 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2266 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2267 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2268 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2270 currTar_Info->TarLUNBusy[0] = 0;
2273 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2275 currTar_Info->TarSyncCtrl = 0;
2276 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2279 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2281 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2284 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2286 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2290 else if (p_int & SCAM_SEL)
2293 FPT_scarb(p_port,LEVEL2_TAR);
2295 FPT_scasid(p_card, p_port);
2299 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2306 /*---------------------------------------------------------------------
2308 * Function: SccbMgrTableInit
2310 * Description: Initialize all Sccb manager data structures.
2312 *---------------------------------------------------------------------*/
2314 static void FPT_SccbMgrTableInitAll()
2316 unsigned char thisCard;
2318 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2320 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2322 FPT_BL_Card[thisCard].ioPort = 0x00;
2323 FPT_BL_Card[thisCard].cardInfo = NULL;
2324 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2325 FPT_BL_Card[thisCard].ourId = 0x00;
2326 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2331 /*---------------------------------------------------------------------
2333 * Function: SccbMgrTableInit
2335 * Description: Initialize all Sccb manager data structures.
2337 *---------------------------------------------------------------------*/
2339 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2341 unsigned char scsiID, qtag;
2343 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2345 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2348 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2350 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2351 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2352 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2355 pCurrCard->scanIndex = 0x00;
2356 pCurrCard->currentSCCB = NULL;
2357 pCurrCard->globalFlags = 0x00;
2358 pCurrCard->cmdCounter = 0x00;
2359 pCurrCard->tagQ_Lst = 0x01;
2360 pCurrCard->discQCount = 0;
2366 /*---------------------------------------------------------------------
2368 * Function: SccbMgrTableInit
2370 * Description: Initialize all Sccb manager data structures.
2372 *---------------------------------------------------------------------*/
2374 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2377 unsigned char lun, qtag;
2378 PSCCBMgr_tar_info currTar_Info;
2380 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2382 currTar_Info->TarSelQ_Cnt = 0;
2383 currTar_Info->TarSyncCtrl = 0;
2385 currTar_Info->TarSelQ_Head = NULL;
2386 currTar_Info->TarSelQ_Tail = NULL;
2387 currTar_Info->TarTagQ_Cnt = 0;
2388 currTar_Info->TarLUN_CA = 0;
2391 for (lun = 0; lun < MAX_LUN; lun++)
2393 currTar_Info->TarLUNBusy[lun] = 0;
2394 currTar_Info->LunDiscQ_Idx[lun] = 0;
2397 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2399 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2401 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2403 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2404 FPT_BL_Card[p_card].discQCount--;
2411 /*---------------------------------------------------------------------
2415 * Description: Read in a message byte from the SCSI bus, and check
2416 * for a parity error.
2418 *---------------------------------------------------------------------*/
2420 static unsigned char FPT_sfm(unsigned long port, PSCCB pCurrSCCB)
2422 unsigned char message;
2423 unsigned short TimeOutLoop;
2426 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2427 (TimeOutLoop++ < 20000) ){}
2430 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2432 message = RD_HARPOON(port+hp_scsidata_0);
2434 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2437 if (TimeOutLoop > 20000)
2438 message = 0x00; /* force message byte = 0 if Time Out on Req */
2440 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2441 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2443 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2444 WR_HARPOON(port+hp_xferstat, 0);
2445 WR_HARPOON(port+hp_fiforead, 0);
2446 WR_HARPOON(port+hp_fifowrite, 0);
2447 if (pCurrSCCB != NULL)
2449 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2454 ACCEPT_MSG_ATN(port);
2456 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2457 (TimeOutLoop++ < 20000) ){}
2458 if (TimeOutLoop > 20000)
2460 WRW_HARPOON((port+hp_intstat), PARITY);
2463 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2465 WRW_HARPOON((port+hp_intstat), PARITY);
2468 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2470 RD_HARPOON(port+hp_scsidata_0);
2472 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2477 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2478 WR_HARPOON(port+hp_xferstat, 0);
2479 WR_HARPOON(port+hp_fiforead, 0);
2480 WR_HARPOON(port+hp_fifowrite, 0);
2485 /*---------------------------------------------------------------------
2487 * Function: FPT_ssel
2489 * Description: Load up automation and select target device.
2491 *---------------------------------------------------------------------*/
2493 static void FPT_ssel(unsigned long port, unsigned char p_card)
2496 unsigned char auto_loaded, i, target, *theCCB;
2498 unsigned long cdb_reg;
2501 PSCCBMgr_tar_info currTar_Info;
2502 unsigned char lastTag, lun;
2504 CurrCard = &FPT_BL_Card[p_card];
2505 currSCCB = CurrCard->currentSCCB;
2506 target = currSCCB->TargID;
2507 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2508 lastTag = CurrCard->tagQ_Lst;
2513 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2514 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2516 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2517 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2519 lun = currSCCB->Lun;
2524 if (CurrCard->globalFlags & F_TAG_STARTED)
2526 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2528 if ((currTar_Info->TarLUN_CA == 0)
2529 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2533 if (currTar_Info->TarTagQ_Cnt !=0)
2535 currTar_Info->TarLUNBusy[lun] = 1;
2536 FPT_queueSelectFail(CurrCard,p_card);
2542 currTar_Info->TarLUNBusy[lun] = 1;
2545 } /*End non-tagged */
2548 currTar_Info->TarLUNBusy[lun] = 1;
2551 } /*!Use cmd Q Tagged */
2554 if (currTar_Info->TarLUN_CA == 1)
2556 FPT_queueSelectFail(CurrCard,p_card);
2561 currTar_Info->TarLUNBusy[lun] = 1;
2563 } /*else use cmd Q tagged */
2565 } /*if glob tagged started */
2568 currTar_Info->TarLUNBusy[lun] = 1;
2573 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2574 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2575 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2577 if(CurrCard->discQCount >= QUEUE_DEPTH)
2579 currTar_Info->TarLUNBusy[lun] = 1;
2580 FPT_queueSelectFail(CurrCard,p_card);
2584 for (i = 1; i < QUEUE_DEPTH; i++)
2586 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2587 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2589 CurrCard->tagQ_Lst = lastTag;
2590 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2591 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2592 CurrCard->discQCount++;
2596 if(i == QUEUE_DEPTH)
2598 currTar_Info->TarLUNBusy[lun] = 1;
2599 FPT_queueSelectFail(CurrCard,p_card);
2609 WR_HARPOON(port+hp_select_id, target);
2610 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2612 if (currSCCB->OperationCode == RESET_COMMAND) {
2613 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2614 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2616 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2618 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2620 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2622 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2624 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2626 currTar_Info->TarSyncCtrl = 0;
2627 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2630 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2632 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2635 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2636 FPT_SccbMgrTableInitTarget(p_card, target);
2640 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2642 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2643 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2645 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2647 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2648 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2649 >> 6) | (unsigned char)0x20)));
2650 WRW_HARPOON((port+SYNC_MSGS+2),
2651 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2652 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2654 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2659 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2660 auto_loaded = FPT_siwidn(port,p_card);
2661 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2664 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2665 == SYNC_SUPPORTED)) {
2666 auto_loaded = FPT_sisyncn(port,p_card, 0);
2667 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2674 if (currSCCB->ControlByte & F_USE_CMD_Q)
2677 CurrCard->globalFlags |= F_TAG_STARTED;
2679 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2682 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2684 /* Fix up the start instruction with a jump to
2685 Non-Tag-CMD handling */
2686 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2688 WRW_HARPOON((port+NON_TAG_ID_MSG),
2689 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2691 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2693 /* Setup our STATE so we know what happend when
2694 the wheels fall off. */
2695 currSCCB->Sccb_scsistat = SELECT_ST;
2697 currTar_Info->TarLUNBusy[lun] = 1;
2702 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2704 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2705 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2706 >> 6) | (unsigned char)0x20)));
2708 for (i = 1; i < QUEUE_DEPTH; i++)
2710 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2711 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2713 WRW_HARPOON((port+ID_MSG_STRT+6),
2714 (MPM_OP+AMSG_OUT+lastTag));
2715 CurrCard->tagQ_Lst = lastTag;
2716 currSCCB->Sccb_tag = lastTag;
2717 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2718 CurrCard->discQCount++;
2724 if ( i == QUEUE_DEPTH )
2726 currTar_Info->TarLUNBusy[lun] = 1;
2727 FPT_queueSelectFail(CurrCard,p_card);
2732 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2734 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2741 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2743 WRW_HARPOON((port+NON_TAG_ID_MSG),
2744 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2746 currSCCB->Sccb_scsistat = SELECT_ST;
2748 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2752 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2754 cdb_reg = port + CMD_STRT;
2756 for (i=0; i < currSCCB->CdbLength; i++)
2758 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2763 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2764 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2768 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2769 WR_HARPOON(port+hp_xferstat, 0x00);
2771 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2773 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2776 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2778 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2783 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2784 auto_loaded |= AUTO_IMMED; */
2785 auto_loaded = AUTO_IMMED;
2789 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2796 /*---------------------------------------------------------------------
2798 * Function: FPT_sres
2800 * Description: Hookup the correct CCB and handle the incoming messages.
2802 *---------------------------------------------------------------------*/
2804 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
2807 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2810 PSCCBMgr_tar_info currTar_Info;
2816 if(pCurrCard->currentSCCB != NULL)
2818 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2822 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2825 currSCCB = pCurrCard->currentSCCB;
2826 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2828 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2829 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2831 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2833 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2834 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2836 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2837 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2839 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2840 if(currSCCB->Sccb_scsistat != ABORT_ST)
2842 pCurrCard->discQCount--;
2843 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2849 currTar_Info->TarLUNBusy[0] = 0;
2850 if(currSCCB->Sccb_tag)
2852 if(currSCCB->Sccb_scsistat != ABORT_ST)
2854 pCurrCard->discQCount--;
2855 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2859 if(currSCCB->Sccb_scsistat != ABORT_ST)
2861 pCurrCard->discQCount--;
2862 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2867 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2870 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2873 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2874 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2881 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2885 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2887 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2890 WRW_HARPOON((port+hp_intstat), PHASE);
2895 WRW_HARPOON((port+hp_intstat), PHASE);
2896 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2899 message = FPT_sfm(port,pCurrCard->currentSCCB);
2903 if (message <= (0x80 | LUN_MASK))
2905 lun = message & (unsigned char)LUN_MASK;
2907 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2909 if (currTar_Info->TarTagQ_Cnt != 0)
2912 if (!(currTar_Info->TarLUN_CA))
2914 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2917 message = FPT_sfm(port,pCurrCard->currentSCCB);
2928 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2936 } /*End Q cnt != 0 */
2938 } /*End Tag cmds supported! */
2940 } /*End valid ID message. */
2945 ACCEPT_MSG_ATN(port);
2948 } /* End good id message. */
2958 ACCEPT_MSG_ATN(port);
2960 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2961 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2962 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2970 if(msgRetryCount == 1)
2972 FPT_SendMsg(port, SMPARITY);
2976 FPT_SendMsg(port, SMDEV_RESET);
2978 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2980 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2983 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2987 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2990 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
2994 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2995 FPT_SccbMgrTableInitTarget(p_card,our_target);
2999 }while(message == 0);
3003 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3004 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3006 currTar_Info->TarLUNBusy[lun] = 1;
3007 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3008 if(pCurrCard->currentSCCB != NULL)
3014 ACCEPT_MSG_ATN(port);
3019 currTar_Info->TarLUNBusy[0] = 1;
3024 if (pCurrCard->discQ_Tbl[tag] != NULL)
3026 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3027 currTar_Info->TarTagQ_Cnt--;
3032 ACCEPT_MSG_ATN(port);
3036 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3037 if(pCurrCard->currentSCCB != NULL)
3043 ACCEPT_MSG_ATN(port);
3048 if(pCurrCard->currentSCCB != NULL)
3050 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3052 /* During Abort Tag command, the target could have got re-selected
3053 and completed the command. Check the select Q and remove the CCB
3054 if it is in the Select Q */
3055 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3060 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3061 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3062 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3065 static void FPT_SendMsg(unsigned long port, unsigned char message)
3067 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3069 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3072 WRW_HARPOON((port+hp_intstat), PHASE);
3077 WRW_HARPOON((port+hp_intstat), PHASE);
3078 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3080 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3083 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3085 WR_HARPOON(port+hp_scsidata_0,message);
3087 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3091 WR_HARPOON(port+hp_portctrl_0, 0x00);
3093 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3094 (message == SMABORT_TAG) )
3096 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3098 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3100 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3106 /*---------------------------------------------------------------------
3108 * Function: FPT_sdecm
3110 * Description: Determine the proper responce to the message from the
3113 *---------------------------------------------------------------------*/
3114 static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
3118 PSCCBMgr_tar_info currTar_Info;
3120 CurrCard = &FPT_BL_Card[p_card];
3121 currSCCB = CurrCard->currentSCCB;
3123 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3125 if (message == SMREST_DATA_PTR)
3127 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3129 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3131 FPT_hostDataXferRestart(currSCCB);
3135 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3138 else if (message == SMCMD_COMP)
3142 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3144 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3145 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3152 else if ((message == SMNO_OP) || (message >= SMIDENT)
3153 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3157 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3160 else if (message == SMREJECT)
3163 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3164 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3165 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3166 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3169 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3174 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3175 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3177 if(currSCCB->Lun == 0x00)
3179 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3182 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3184 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3187 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3191 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3192 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3194 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3198 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3200 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3201 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3204 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3205 CurrCard->discQCount--;
3206 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3207 currSCCB->Sccb_tag = 0x00;
3212 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3216 if(currSCCB->Lun == 0x00)
3218 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3219 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3226 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3227 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3228 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3230 currTar_Info->TarLUNBusy[0] = 1;
3233 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3235 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3244 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3245 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3247 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3249 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3254 else if (message == SMEXT)
3258 FPT_shandem(port,p_card,currSCCB);
3261 else if (message == SMIGNORWR)
3264 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3266 message = FPT_sfm(port,currSCCB);
3268 if(currSCCB->Sccb_scsimsg != SMPARITY)
3270 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3277 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3278 currSCCB->Sccb_scsimsg = SMREJECT;
3280 ACCEPT_MSG_ATN(port);
3281 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3286 /*---------------------------------------------------------------------
3288 * Function: FPT_shandem
3290 * Description: Decide what to do with the extended message.
3292 *---------------------------------------------------------------------*/
3293 static void FPT_shandem(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
3295 unsigned char length,message;
3297 length = FPT_sfm(port,pCurrSCCB);
3302 message = FPT_sfm(port,pCurrSCCB);
3306 if (message == SMSYNC)
3313 FPT_stsyncn(port,p_card);
3318 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3319 ACCEPT_MSG_ATN(port);
3322 else if (message == SMWDTR)
3329 FPT_stwidn(port,p_card);
3334 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3335 ACCEPT_MSG_ATN(port);
3337 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3343 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3344 ACCEPT_MSG_ATN(port);
3346 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3351 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3353 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3357 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3358 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3363 /*---------------------------------------------------------------------
3365 * Function: FPT_sisyncn
3367 * Description: Read in a message byte from the SCSI bus, and check
3368 * for a parity error.
3370 *---------------------------------------------------------------------*/
3372 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
3375 PSCCBMgr_tar_info currTar_Info;
3377 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3378 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3380 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3383 WRW_HARPOON((port+ID_MSG_STRT),
3384 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3386 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3388 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3389 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3390 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3393 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3395 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3397 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3399 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3401 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3403 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3406 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3409 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3410 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3411 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3416 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3417 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3418 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3422 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3431 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3432 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3439 /*---------------------------------------------------------------------
3441 * Function: FPT_stsyncn
3443 * Description: The has sent us a Sync Nego message so handle it as
3446 *---------------------------------------------------------------------*/
3447 static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3449 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3451 PSCCBMgr_tar_info currTar_Info;
3453 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3454 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3456 sync_msg = FPT_sfm(port,currSCCB);
3458 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3460 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3467 offset = FPT_sfm(port,currSCCB);
3469 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3471 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3475 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3477 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3479 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3481 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3483 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3485 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3488 our_sync_msg = 0; /* Message = Async */
3490 if (sync_msg < our_sync_msg) {
3491 sync_msg = our_sync_msg; /*if faster, then set to max. */
3494 if (offset == ASYNC)
3497 if (offset > MAX_OFFSET)
3498 offset = MAX_OFFSET;
3504 sync_reg = 0x20; /* Use 10MB/s */
3508 sync_reg = 0x40; /* Use 6.6MB/s */
3512 sync_reg = 0x60; /* Use 5MB/s */
3516 sync_reg = 0x80; /* Use 4MB/s */
3520 sync_reg = 0xA0; /* Use 3.33MB/s */
3524 sync_reg = 0xC0; /* Use 2.85MB/s */
3528 sync_reg = 0xE0; /* Use 2.5MB/s */
3530 if (sync_msg > 100) {
3532 sync_reg = 0x00; /* Use ASYNC */
3537 if (currTar_Info->TarStatus & WIDE_ENABLED)
3543 sync_reg |= (offset | NARROW_SCSI);
3545 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3548 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3553 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3554 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3556 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3562 ACCEPT_MSG_ATN(port);
3564 FPT_sisyncr(port,sync_msg,offset);
3566 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3567 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3572 /*---------------------------------------------------------------------
3574 * Function: FPT_sisyncr
3576 * Description: Answer the targets sync message.
3578 *---------------------------------------------------------------------*/
3579 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
3582 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3583 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3584 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3585 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3586 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3587 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3588 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3591 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3592 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3594 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3596 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3601 /*---------------------------------------------------------------------
3603 * Function: FPT_siwidn
3605 * Description: Read in a message byte from the SCSI bus, and check
3606 * for a parity error.
3608 *---------------------------------------------------------------------*/
3610 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3613 PSCCBMgr_tar_info currTar_Info;
3615 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3616 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3618 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3621 WRW_HARPOON((port+ID_MSG_STRT),
3622 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3624 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3626 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3627 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3628 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3629 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3630 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3631 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3633 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3636 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3637 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3644 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3645 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3647 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3654 /*---------------------------------------------------------------------
3656 * Function: FPT_stwidn
3658 * Description: The has sent us a Wide Nego message so handle it as
3661 *---------------------------------------------------------------------*/
3662 static void FPT_stwidn(unsigned long port, unsigned char p_card)
3664 unsigned char width;
3666 PSCCBMgr_tar_info currTar_Info;
3668 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3669 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3671 width = FPT_sfm(port,currSCCB);
3673 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3675 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3680 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3684 currTar_Info->TarStatus |= WIDE_ENABLED;
3688 width = NARROW_SCSI;
3689 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3693 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3696 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3701 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3703 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3705 ACCEPT_MSG_ATN(port);
3707 FPT_sisyncn(port,p_card, 1);
3708 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3714 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3721 ACCEPT_MSG_ATN(port);
3723 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3728 FPT_siwidr(port,width);
3730 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3735 /*---------------------------------------------------------------------
3737 * Function: FPT_siwidr
3739 * Description: Answer the targets Wide nego message.
3741 *---------------------------------------------------------------------*/
3742 static void FPT_siwidr(unsigned long port, unsigned char width)
3745 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3746 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3747 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3748 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3749 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3750 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3753 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3754 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3756 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3758 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3763 /*---------------------------------------------------------------------
3765 * Function: FPT_sssyncv
3767 * Description: Write the desired value to the Sync Register for the
3770 *---------------------------------------------------------------------*/
3771 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
3772 PSCCBMgr_tar_info currTar_Info)
3774 unsigned char index;
3781 index = 12; /* hp_synctarg_0 */
3784 index = 13; /* hp_synctarg_1 */
3787 index = 14; /* hp_synctarg_2 */
3790 index = 15; /* hp_synctarg_3 */
3793 index = 8; /* hp_synctarg_4 */
3796 index = 9; /* hp_synctarg_5 */
3799 index = 10; /* hp_synctarg_6 */
3802 index = 11; /* hp_synctarg_7 */
3805 index = 4; /* hp_synctarg_8 */
3808 index = 5; /* hp_synctarg_9 */
3811 index = 6; /* hp_synctarg_10 */
3814 index = 7; /* hp_synctarg_11 */
3817 index = 0; /* hp_synctarg_12 */
3820 index = 1; /* hp_synctarg_13 */
3823 index = 2; /* hp_synctarg_14 */
3826 index = 3; /* hp_synctarg_15 */
3830 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3832 currTar_Info->TarSyncCtrl = p_sync_value;
3836 /*---------------------------------------------------------------------
3838 * Function: FPT_sresb
3840 * Description: Reset the desired card's SCSI bus.
3842 *---------------------------------------------------------------------*/
3843 static void FPT_sresb(unsigned long port, unsigned char p_card)
3845 unsigned char scsiID, i;
3847 PSCCBMgr_tar_info currTar_Info;
3849 WR_HARPOON(port+hp_page_ctrl,
3850 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3851 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3853 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3855 scsiID = RD_HARPOON(port+hp_seltimeout);
3856 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3857 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3859 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3861 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3863 WR_HARPOON(port+hp_seltimeout,scsiID);
3865 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3867 FPT_Wait(port, TO_5ms);
3869 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3871 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3873 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3875 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3877 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3879 currTar_Info->TarSyncCtrl = 0;
3880 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3883 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3885 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3888 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3890 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3893 FPT_BL_Card[p_card].scanIndex = 0x00;
3894 FPT_BL_Card[p_card].currentSCCB = NULL;
3895 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3897 FPT_BL_Card[p_card].cmdCounter = 0x00;
3898 FPT_BL_Card[p_card].discQCount = 0x00;
3899 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3901 for(i = 0; i < QUEUE_DEPTH; i++)
3902 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3904 WR_HARPOON(port+hp_page_ctrl,
3905 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3909 /*---------------------------------------------------------------------
3911 * Function: FPT_ssenss
3913 * Description: Setup for the Auto Sense command.
3915 *---------------------------------------------------------------------*/
3916 static void FPT_ssenss(PSCCBcard pCurrCard)
3921 currSCCB = pCurrCard->currentSCCB;
3924 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3926 for (i = 0; i < 6; i++) {
3928 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3931 currSCCB->CdbLength = SIX_BYTE_CMD;
3932 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3933 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3934 currSCCB->Cdb[2] = 0x00;
3935 currSCCB->Cdb[3] = 0x00;
3936 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3937 currSCCB->Cdb[5] = 0x00;
3939 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3941 currSCCB->Sccb_ATC = 0x00;
3943 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3945 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3947 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3949 currSCCB->ControlByte = 0x00;
3951 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3956 /*---------------------------------------------------------------------
3958 * Function: FPT_sxfrp
3960 * Description: Transfer data into the bit bucket until the device
3961 * decides to switch phase.
3963 *---------------------------------------------------------------------*/
3965 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3967 unsigned char curr_phz;
3970 DISABLE_AUTO(p_port);
3972 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3974 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3978 /* If the Automation handled the end of the transfer then do not
3979 match the phase or we will get out of sync with the ISR. */
3981 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3984 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3986 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3988 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3991 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3993 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
3994 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
3996 if (curr_phz & (unsigned char)SCSI_IOBIT)
3998 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4000 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4002 RD_HARPOON(p_port+hp_fifodata_0);
4007 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4008 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4010 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4013 } /* End of While loop for padding data I/O phase */
4015 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4017 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4021 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4022 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4024 RD_HARPOON(p_port+hp_fifodata_0);
4027 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4029 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4030 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4032 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4033 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4038 /*---------------------------------------------------------------------
4040 * Function: FPT_schkdd
4042 * Description: Make sure data has been flushed from both FIFOs and abort
4043 * the operations if necessary.
4045 *---------------------------------------------------------------------*/
4047 static void FPT_schkdd(unsigned long port, unsigned char p_card)
4049 unsigned short TimeOutLoop;
4050 unsigned char sPhase;
4054 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4057 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4058 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4064 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4067 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4069 currSCCB->Sccb_XferCnt = 1;
4071 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4072 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4073 WR_HARPOON(port+hp_xferstat, 0x00);
4079 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4081 currSCCB->Sccb_XferCnt = 0;
4084 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4085 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4087 currSCCB->HostStatus = SCCB_PARITY_ERR;
4088 WRW_HARPOON((port+hp_intstat), PARITY);
4092 FPT_hostDataXferAbort(port,p_card,currSCCB);
4095 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4099 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4101 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4104 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4107 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4110 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4114 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4115 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4116 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4117 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4118 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4121 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4123 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4125 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4126 FPT_phaseDataIn(port,p_card);
4130 FPT_phaseDataOut(port,p_card);
4135 FPT_sxfrp(port,p_card);
4136 if (!(RDW_HARPOON((port+hp_intstat)) &
4137 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4139 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4140 FPT_phaseDecode(port,p_card);
4147 WR_HARPOON(port+hp_portctrl_0, 0x00);
4152 /*---------------------------------------------------------------------
4154 * Function: FPT_sinits
4156 * Description: Setup SCCB manager fields in this SCCB.
4158 *---------------------------------------------------------------------*/
4160 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
4162 PSCCBMgr_tar_info currTar_Info;
4164 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4168 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4170 p_sccb->Sccb_XferState = 0x00;
4171 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4173 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4174 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4176 p_sccb->Sccb_SGoffset = 0;
4177 p_sccb->Sccb_XferState = F_SG_XFER;
4178 p_sccb->Sccb_XferCnt = 0x00;
4181 if (p_sccb->DataLength == 0x00)
4183 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4185 if (p_sccb->ControlByte & F_USE_CMD_Q)
4187 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4188 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4191 currTar_Info->TarStatus |= TAG_Q_TRYING;
4194 /* For !single SCSI device in system & device allow Disconnect
4195 or command is tag_q type then send Cmd with Disconnect Enable
4196 else send Cmd with Disconnect Disable */
4199 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4200 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4201 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4203 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4204 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4205 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4210 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4213 p_sccb->HostStatus = 0x00;
4214 p_sccb->TargetStatus = 0x00;
4215 p_sccb->Sccb_tag = 0x00;
4216 p_sccb->Sccb_MGRFlags = 0x00;
4217 p_sccb->Sccb_sgseg = 0x00;
4218 p_sccb->Sccb_ATC = 0x00;
4219 p_sccb->Sccb_savedATC = 0x00;
4221 p_sccb->SccbVirtDataPtr = 0x00;
4222 p_sccb->Sccb_forwardlink = NULL;
4223 p_sccb->Sccb_backlink = NULL;
4225 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4226 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4227 p_sccb->Sccb_scsimsg = SMNO_OP;
4232 /*---------------------------------------------------------------------
4234 * Function: Phase Decode
4236 * Description: Determine the phase and call the appropriate function.
4238 *---------------------------------------------------------------------*/
4240 static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4242 unsigned char phase_ref;
4243 void (*phase) (unsigned long, unsigned char);
4246 DISABLE_AUTO(p_port);
4248 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4250 phase = FPT_s_PhaseTbl[phase_ref];
4252 (*phase)(p_port, p_card); /* Call the correct phase func */
4257 /*---------------------------------------------------------------------
4259 * Function: Data Out Phase
4261 * Description: Start up both the BusMaster and Xbow.
4263 *---------------------------------------------------------------------*/
4265 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4270 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4271 if (currSCCB == NULL)
4273 return; /* Exit if No SCCB record */
4276 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4277 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4279 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4281 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4283 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4285 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4287 if (currSCCB->Sccb_XferCnt == 0) {
4290 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4291 (currSCCB->HostStatus == SCCB_COMPLETE))
4292 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4294 FPT_sxfrp(port,p_card);
4295 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4296 FPT_phaseDecode(port,p_card);
4301 /*---------------------------------------------------------------------
4303 * Function: Data In Phase
4305 * Description: Startup the BusMaster and the XBOW.
4307 *---------------------------------------------------------------------*/
4309 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4314 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4316 if (currSCCB == NULL)
4318 return; /* Exit if No SCCB record */
4322 currSCCB->Sccb_scsistat = DATA_IN_ST;
4323 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4324 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4326 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4328 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4330 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4332 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4334 if (currSCCB->Sccb_XferCnt == 0) {
4337 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4338 (currSCCB->HostStatus == SCCB_COMPLETE))
4339 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4341 FPT_sxfrp(port,p_card);
4342 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4343 FPT_phaseDecode(port,p_card);
4348 /*---------------------------------------------------------------------
4350 * Function: Command Phase
4352 * Description: Load the CDB into the automation and start it up.
4354 *---------------------------------------------------------------------*/
4356 static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4359 unsigned long cdb_reg;
4362 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4364 if (currSCCB->OperationCode == RESET_COMMAND) {
4366 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4367 currSCCB->CdbLength = SIX_BYTE_CMD;
4370 WR_HARPOON(p_port+hp_scsisig, 0x00);
4372 ARAM_ACCESS(p_port);
4375 cdb_reg = p_port + CMD_STRT;
4377 for (i=0; i < currSCCB->CdbLength; i++) {
4379 if (currSCCB->OperationCode == RESET_COMMAND)
4381 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4384 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4388 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4389 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4391 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4393 currSCCB->Sccb_scsistat = COMMAND_ST;
4395 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4396 SGRAM_ACCESS(p_port);
4400 /*---------------------------------------------------------------------
4402 * Function: Status phase
4404 * Description: Bring in the status and command complete message bytes
4406 *---------------------------------------------------------------------*/
4408 static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4410 /* Start-up the automation to finish off this command and let the
4411 isr handle the interrupt for command complete when it comes in.
4412 We could wait here for the interrupt to be generated?
4415 WR_HARPOON(port+hp_scsisig, 0x00);
4417 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4421 /*---------------------------------------------------------------------
4423 * Function: Phase Message Out
4425 * Description: Send out our message (if we have one) and handle whatever
4428 *---------------------------------------------------------------------*/
4430 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4432 unsigned char message,scsiID;
4434 PSCCBMgr_tar_info currTar_Info;
4436 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4438 if (currSCCB != NULL) {
4440 message = currSCCB->Sccb_scsimsg;
4441 scsiID = currSCCB->TargID;
4443 if (message == SMDEV_RESET)
4447 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4448 currTar_Info->TarSyncCtrl = 0;
4449 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4451 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4454 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4458 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4461 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4465 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4466 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4468 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4470 currSCCB->HostStatus = SCCB_COMPLETE;
4471 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4473 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4474 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4479 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4483 if(message == SMNO_OP)
4485 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4487 FPT_ssel(port,p_card);
4495 if (message == SMABORT)
4497 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4506 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4509 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4511 WR_HARPOON(port+hp_scsidata_0,message);
4513 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4517 WR_HARPOON(port+hp_portctrl_0, 0x00);
4519 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4520 (message == SMABORT_TAG) )
4523 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4525 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4527 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4529 if (currSCCB != NULL)
4532 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4533 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4534 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4536 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4538 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4543 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4550 FPT_sxfrp(port,p_card);
4557 if(message == SMPARITY)
4559 currSCCB->Sccb_scsimsg = SMNO_OP;
4560 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4564 FPT_sxfrp(port,p_card);
4570 /*---------------------------------------------------------------------
4572 * Function: Message In phase
4574 * Description: Bring in the message and determine what to do with it.
4576 *---------------------------------------------------------------------*/
4578 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4580 unsigned char message;
4583 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4585 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4588 FPT_phaseChkFifo(port, p_card);
4591 message = RD_HARPOON(port+hp_scsidata_0);
4592 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4595 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4602 message = FPT_sfm(port,currSCCB);
4607 FPT_sdecm(message,port,p_card);
4612 if(currSCCB->Sccb_scsimsg != SMPARITY)
4614 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4621 /*---------------------------------------------------------------------
4623 * Function: Illegal phase
4625 * Description: Target switched to some illegal phase, so all we can do
4626 * is report an error back to the host (if that is possible)
4627 * and send an ABORT message to the misbehaving target.
4629 *---------------------------------------------------------------------*/
4631 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4635 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4637 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4638 if (currSCCB != NULL) {
4640 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4641 currSCCB->Sccb_scsistat = ABORT_ST;
4642 currSCCB->Sccb_scsimsg = SMABORT;
4645 ACCEPT_MSG_ATN(port);
4650 /*---------------------------------------------------------------------
4652 * Function: Phase Check FIFO
4654 * Description: Make sure data has been flushed from both FIFOs and abort
4655 * the operations if necessary.
4657 *---------------------------------------------------------------------*/
4659 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4661 unsigned long xfercnt;
4664 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4666 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4669 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4670 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4673 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4675 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4677 currSCCB->Sccb_XferCnt = 0;
4679 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4680 (currSCCB->HostStatus == SCCB_COMPLETE))
4682 currSCCB->HostStatus = SCCB_PARITY_ERR;
4683 WRW_HARPOON((port+hp_intstat), PARITY);
4686 FPT_hostDataXferAbort(port,p_card,currSCCB);
4688 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4690 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4691 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4694 } /*End Data In specific code. */
4698 GET_XFER_CNT(port,xfercnt);
4701 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4704 WR_HARPOON(port+hp_portctrl_0, 0x00);
4706 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4708 currSCCB->Sccb_XferCnt = xfercnt;
4710 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4711 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4713 currSCCB->HostStatus = SCCB_PARITY_ERR;
4714 WRW_HARPOON((port+hp_intstat), PARITY);
4718 FPT_hostDataXferAbort(port,p_card,currSCCB);
4721 WR_HARPOON(port+hp_fifowrite, 0x00);
4722 WR_HARPOON(port+hp_fiforead, 0x00);
4723 WR_HARPOON(port+hp_xferstat, 0x00);
4725 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4729 /*---------------------------------------------------------------------
4731 * Function: Phase Bus Free
4733 * Description: We just went bus free so figure out if it was
4734 * because of command complete or from a disconnect.
4736 *---------------------------------------------------------------------*/
4737 static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4741 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4743 if (currSCCB != NULL)
4749 if (currSCCB->OperationCode == RESET_COMMAND)
4752 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4753 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4754 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4756 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4758 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4760 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4764 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4766 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4767 (unsigned char)SYNC_SUPPORTED;
4768 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4771 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4773 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4774 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4775 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4777 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4780 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4782 /* Make sure this is not a phony BUS_FREE. If we were
4783 reselected or if BUSY is NOT on then this is a
4784 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4786 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4787 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4789 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4790 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4802 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4804 if (!currSCCB->HostStatus)
4806 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4809 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4810 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4811 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4813 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4815 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4820 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4822 } /*end if !=null */
4828 /*---------------------------------------------------------------------
4830 * Function: Auto Load Default Map
4832 * Description: Load the Automation RAM with the defualt map values.
4834 *---------------------------------------------------------------------*/
4835 static void FPT_autoLoadDefaultMap(unsigned long p_port)
4837 unsigned long map_addr;
4839 ARAM_ACCESS(p_port);
4840 map_addr = p_port + hp_aramBase;
4842 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4844 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4846 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4848 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4850 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4852 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4854 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4874 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4876 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4877 map_addr +=2; /*This means AYNC DATA IN */
4878 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4880 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4882 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4884 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4886 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4888 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4890 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4892 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4894 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4896 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4898 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4900 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4902 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4904 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4906 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4908 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4910 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4912 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4915 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4917 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4919 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4921 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4922 map_addr +=2; /* DIDN'T GET ONE */
4923 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4925 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4931 SGRAM_ACCESS(p_port);
4934 /*---------------------------------------------------------------------
4936 * Function: Auto Command Complete
4938 * Description: Post command back to host and find another command
4941 *---------------------------------------------------------------------*/
4943 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4946 unsigned char status_byte;
4948 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4950 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4952 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4954 if (status_byte != SSGOOD) {
4956 if (status_byte == SSQ_FULL) {
4959 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4960 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4962 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4963 if(FPT_BL_Card[p_card].discQCount != 0)
4964 FPT_BL_Card[p_card].discQCount--;
4965 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4969 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4970 if(currSCCB->Sccb_tag)
4972 if(FPT_BL_Card[p_card].discQCount != 0)
4973 FPT_BL_Card[p_card].discQCount--;
4974 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4977 if(FPT_BL_Card[p_card].discQCount != 0)
4978 FPT_BL_Card[p_card].discQCount--;
4979 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4983 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4985 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4990 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4992 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4993 (unsigned char)SYNC_SUPPORTED;
4995 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4996 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4998 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4999 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5001 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5002 if(FPT_BL_Card[p_card].discQCount != 0)
5003 FPT_BL_Card[p_card].discQCount--;
5004 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5008 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5009 if(currSCCB->Sccb_tag)
5011 if(FPT_BL_Card[p_card].discQCount != 0)
5012 FPT_BL_Card[p_card].discQCount--;
5013 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5016 if(FPT_BL_Card[p_card].discQCount != 0)
5017 FPT_BL_Card[p_card].discQCount--;
5018 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5025 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5028 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5029 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5030 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5032 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5033 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5035 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5036 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5038 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5039 if(FPT_BL_Card[p_card].discQCount != 0)
5040 FPT_BL_Card[p_card].discQCount--;
5041 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5045 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5046 if(currSCCB->Sccb_tag)
5048 if(FPT_BL_Card[p_card].discQCount != 0)
5049 FPT_BL_Card[p_card].discQCount--;
5050 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5053 if(FPT_BL_Card[p_card].discQCount != 0)
5054 FPT_BL_Card[p_card].discQCount--;
5055 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5062 if (status_byte == SSCHECK)
5064 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5066 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5068 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5070 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5072 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5077 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5079 currSCCB->SccbStatus = SCCB_ERROR;
5080 currSCCB->TargetStatus = status_byte;
5082 if (status_byte == SSCHECK) {
5084 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5088 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5090 if (currSCCB->RequestSenseLength == 0)
5091 currSCCB->RequestSenseLength = 14;
5093 FPT_ssenss(&FPT_BL_Card[p_card]);
5094 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5096 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5097 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5099 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5100 if(FPT_BL_Card[p_card].discQCount != 0)
5101 FPT_BL_Card[p_card].discQCount--;
5102 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5106 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5107 if(currSCCB->Sccb_tag)
5109 if(FPT_BL_Card[p_card].discQCount != 0)
5110 FPT_BL_Card[p_card].discQCount--;
5111 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5114 if(FPT_BL_Card[p_card].discQCount != 0)
5115 FPT_BL_Card[p_card].discQCount--;
5116 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5126 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5127 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5128 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5130 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5133 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5136 #define SHORT_WAIT 0x0000000F
5137 #define LONG_WAIT 0x0000FFFFL
5140 /*---------------------------------------------------------------------
5142 * Function: Data Transfer Processor
5144 * Description: This routine performs two tasks.
5145 * (1) Start data transfer by calling HOST_DATA_XFER_START
5146 * function. Once data transfer is started, (2) Depends
5147 * on the type of data transfer mode Scatter/Gather mode
5148 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5149 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5150 * data transfer done. In Scatter/Gather mode, this routine
5151 * checks bus master command complete and dual rank busy
5152 * bit to keep chaining SC transfer command. Similarly,
5153 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5154 * (F_HOST_XFER_ACT bit) for data transfer done.
5156 *---------------------------------------------------------------------*/
5158 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
5162 currSCCB = pCurrCard->currentSCCB;
5164 if (currSCCB->Sccb_XferState & F_SG_XFER)
5166 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5169 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5170 currSCCB->Sccb_SGoffset = 0x00;
5172 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5174 FPT_busMstrSGDataXferStart(port, currSCCB);
5179 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5181 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5183 FPT_busMstrDataXferStart(port, currSCCB);
5189 /*---------------------------------------------------------------------
5191 * Function: BusMaster Scatter Gather Data Transfer Start
5195 *---------------------------------------------------------------------*/
5196 static void FPT_busMstrSGDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
5198 unsigned long count,addr,tmpSGCnt;
5199 unsigned int sg_index;
5200 unsigned char sg_count, i;
5201 unsigned long reg_offset;
5204 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5206 count = ((unsigned long) HOST_RD_CMD)<<24;
5210 count = ((unsigned long) HOST_WRT_CMD)<<24;
5215 sg_index = pcurrSCCB->Sccb_sgseg;
5216 reg_offset = hp_aramBase;
5219 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5222 WR_HARPOON(p_port+hp_page_ctrl, i);
5224 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5225 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5227 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
5230 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
5233 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
5234 ((sg_index * 2) + 1));
5237 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5239 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5240 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5242 tmpSGCnt = count & 0x00FFFFFFL;
5245 WR_HARP32(p_port,reg_offset,addr);
5248 WR_HARP32(p_port,reg_offset,count);
5251 count &= 0xFF000000L;
5257 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5259 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5261 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5263 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5266 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5267 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5273 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5274 (tmpSGCnt & 0x000000001))
5277 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5282 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5284 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5285 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5289 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5294 /*---------------------------------------------------------------------
5296 * Function: BusMaster Data Transfer Start
5300 *---------------------------------------------------------------------*/
5301 static void FPT_busMstrDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
5303 unsigned long addr,count;
5305 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5307 count = pcurrSCCB->Sccb_XferCnt;
5309 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5313 addr = pcurrSCCB->SensePointer;
5314 count = pcurrSCCB->RequestSenseLength;
5318 HP_SETUP_ADDR_CNT(p_port,addr,count);
5321 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5323 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5324 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5326 WR_HARPOON(p_port+hp_xfer_cmd,
5327 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5332 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5333 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5335 WR_HARPOON(p_port+hp_xfer_cmd,
5336 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5342 /*---------------------------------------------------------------------
5344 * Function: BusMaster Timeout Handler
5346 * Description: This function is called after a bus master command busy time
5347 * out is detected. This routines issue halt state machine
5348 * with a software time out for command busy. If command busy
5349 * is still asserted at the end of the time out, it issues
5350 * hard abort with another software time out. It hard abort
5351 * command busy is also time out, it'll just give up.
5353 *---------------------------------------------------------------------*/
5354 static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5356 unsigned long timeout;
5358 timeout = LONG_WAIT;
5360 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5362 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5366 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5367 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5369 timeout = LONG_WAIT;
5370 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5373 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5375 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5385 /*---------------------------------------------------------------------
5387 * Function: Host Data Transfer Abort
5389 * Description: Abort any in progress transfer.
5391 *---------------------------------------------------------------------*/
5392 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
5395 unsigned long timeout;
5396 unsigned long remain_cnt;
5397 unsigned int sg_ptr;
5399 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5401 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5404 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5406 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5407 timeout = LONG_WAIT;
5409 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5411 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5413 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5415 if (FPT_busMstrTimeOut(port)) {
5417 if (pCurrSCCB->HostStatus == 0x00)
5419 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5423 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5425 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5427 if (pCurrSCCB->HostStatus == 0x00)
5430 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5436 else if (pCurrSCCB->Sccb_XferCnt) {
5438 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5441 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5444 WR_HARPOON(port+hp_sg_addr,0x00);
5446 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5448 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5450 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5453 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5455 while (remain_cnt < 0x01000000L) {
5459 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
5460 DataPointer) + (sg_ptr * 2)))) {
5462 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
5463 DataPointer) + (sg_ptr * 2)));
5474 if (remain_cnt < 0x01000000L) {
5477 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5479 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5482 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5483 && (remain_cnt == 0))
5485 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5491 if (pCurrSCCB->HostStatus == 0x00) {
5493 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5499 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5502 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5504 FPT_busMstrTimeOut(port);
5509 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5511 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5513 if (pCurrSCCB->HostStatus == 0x00) {
5515 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5526 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5528 timeout = SHORT_WAIT;
5530 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5531 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5535 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5537 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5540 timeout = LONG_WAIT;
5542 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5545 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5549 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5551 if (pCurrSCCB->HostStatus == 0x00) {
5553 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5556 FPT_busMstrTimeOut(port);
5560 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5562 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5564 if (pCurrSCCB->HostStatus == 0x00) {
5566 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5577 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5579 timeout = LONG_WAIT;
5581 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5583 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5585 if (pCurrSCCB->HostStatus == 0x00) {
5587 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5590 FPT_busMstrTimeOut(port);
5595 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5597 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5599 if (pCurrSCCB->HostStatus == 0x00) {
5601 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5607 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5609 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5612 WR_HARPOON(port+hp_sg_addr,0x00);
5614 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5616 pCurrSCCB->Sccb_SGoffset = 0x00;
5619 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5620 pCurrSCCB->DataLength) {
5622 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5624 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5631 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5633 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5637 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5642 /*---------------------------------------------------------------------
5644 * Function: Host Data Transfer Restart
5646 * Description: Reset the available count due to a restore data
5649 *---------------------------------------------------------------------*/
5650 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5652 unsigned long data_count;
5653 unsigned int sg_index;
5654 unsigned long *sg_ptr;
5656 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5658 currSCCB->Sccb_XferCnt = 0;
5660 sg_index = 0xffff; /*Index by long words into sg list. */
5661 data_count = 0; /*Running count of SG xfer counts. */
5663 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5665 while (data_count < currSCCB->Sccb_ATC) {
5668 data_count += *(sg_ptr+(sg_index * 2));
5671 if (data_count == currSCCB->Sccb_ATC) {
5673 currSCCB->Sccb_SGoffset = 0;
5678 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5681 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5685 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5691 /*---------------------------------------------------------------------
5693 * Function: FPT_scini
5695 * Description: Setup all data structures necessary for SCAM selection.
5697 *---------------------------------------------------------------------*/
5699 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5702 unsigned char loser,assigned_id;
5703 unsigned long p_port;
5705 unsigned char i,k,ScamFlg ;
5707 PNVRamInfo pCurrNvRam;
5709 currCard = &FPT_BL_Card[p_card];
5710 p_port = currCard->ioPort;
5711 pCurrNvRam = currCard->pNvRamInfo;
5715 ScamFlg = pCurrNvRam->niScamConf;
5716 i = pCurrNvRam->niSysConf;
5719 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5720 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5722 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5725 FPT_inisci(p_card,p_port, p_our_id);
5727 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5728 too slow to return to SCAM selection */
5731 FPT_Wait1Second(p_port);
5733 FPT_Wait(p_port, TO_250ms); */
5735 FPT_Wait1Second(p_port);
5737 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5739 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5744 FPT_scxferc(p_port,SYNC_PTRN);
5745 FPT_scxferc(p_port,DOM_MSTR);
5746 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5747 } while ( loser == 0xFF );
5751 if ((p_power_up) && (!loser))
5753 FPT_sresb(p_port,p_card);
5754 FPT_Wait(p_port, TO_250ms);
5756 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5761 FPT_scxferc(p_port, SYNC_PTRN);
5762 FPT_scxferc(p_port, DOM_MSTR);
5763 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5765 } while ( loser == 0xFF );
5780 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5783 if (ScamFlg & SCAM_ENABLED)
5786 for (i=0; i < MAX_SCSI_TAR; i++)
5788 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5789 (FPT_scamInfo[i].state == ID_UNUSED))
5791 if (FPT_scsell(p_port,i))
5793 FPT_scamInfo[i].state = LEGACY;
5794 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5795 (FPT_scamInfo[i].id_string[1] != 0xFA))
5798 FPT_scamInfo[i].id_string[0] = 0xFF;
5799 FPT_scamInfo[i].id_string[1] = 0xFA;
5800 if(pCurrNvRam == NULL)
5801 currCard->globalFlags |= F_UPDATE_EEPROM;
5807 FPT_sresb(p_port,p_card);
5808 FPT_Wait1Second(p_port);
5809 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5811 FPT_scasid(p_card, p_port);
5816 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5818 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5820 FPT_scwtsel(p_port);
5823 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5825 i = FPT_scxferc(p_port,0x00);
5828 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5830 i = FPT_scxferc(p_port,0x00);
5833 k = FPT_scxferc(p_port,0x00);
5838 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5839 FPT_inisci(p_card, p_port, p_our_id);
5840 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5841 FPT_scamInfo[currCard->ourId].id_string[0]
5849 else if (i == SET_P_FLAG)
5851 if (!(FPT_scsendi(p_port,
5852 &FPT_scamInfo[p_our_id].id_string[0])))
5853 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5855 }while (!assigned_id);
5857 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5860 if (ScamFlg & SCAM_ENABLED)
5863 if (currCard->globalFlags & F_UPDATE_EEPROM)
5865 FPT_scsavdi(p_card, p_port);
5866 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5872 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5874 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5875 (FPT_scamInfo[i].state == LEGACY))
5880 currCard->globalFlags |= F_SINGLE_DEVICE;
5882 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5887 /*---------------------------------------------------------------------
5889 * Function: FPT_scarb
5891 * Description: Gain control of the bus and wait SCAM select time (250ms)
5893 *---------------------------------------------------------------------*/
5895 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5897 if (p_sel_type == INIT_SELTD)
5900 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5903 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5906 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5909 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5911 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5913 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5921 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5923 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5924 ~(SCSI_BSY | SCSI_SEL)));
5930 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5932 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5933 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5934 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5935 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5937 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5939 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5942 FPT_Wait(p_port,TO_250ms);
5948 /*---------------------------------------------------------------------
5950 * Function: FPT_scbusf
5952 * Description: Release the SCSI bus and disable SCAM selection.
5954 *---------------------------------------------------------------------*/
5956 static void FPT_scbusf(unsigned long p_port)
5958 WR_HARPOON(p_port+hp_page_ctrl,
5959 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5962 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5964 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5967 WR_HARPOON(p_port+hp_scsisig, 0x00);
5970 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5973 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5976 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5978 WR_HARPOON(p_port+hp_page_ctrl,
5979 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5984 /*---------------------------------------------------------------------
5986 * Function: FPT_scasid
5988 * Description: Assign an ID to all the SCAM devices.
5990 *---------------------------------------------------------------------*/
5992 static void FPT_scasid(unsigned char p_card, unsigned long p_port)
5994 unsigned char temp_id_string[ID_STRING_LENGTH];
5996 unsigned char i,k,scam_id;
5997 unsigned char crcBytes[3];
5998 PNVRamInfo pCurrNvRam;
5999 unsigned short * pCrcBytes;
6001 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6008 for (k=0; k < ID_STRING_LENGTH; k++)
6010 temp_id_string[k] = (unsigned char) 0x00;
6013 FPT_scxferc(p_port,SYNC_PTRN);
6014 FPT_scxferc(p_port,ASSIGN_ID);
6016 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6019 pCrcBytes = (unsigned short *)&crcBytes[0];
6020 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6021 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6022 temp_id_string[1] = crcBytes[2];
6023 temp_id_string[2] = crcBytes[0];
6024 temp_id_string[3] = crcBytes[1];
6025 for(k = 4; k < ID_STRING_LENGTH; k++)
6026 temp_id_string[k] = (unsigned char) 0x00;
6028 i = FPT_scmachid(p_card,temp_id_string);
6030 if (i == CLR_PRIORITY)
6032 FPT_scxferc(p_port,MISC_CODE);
6033 FPT_scxferc(p_port,CLR_P_FLAG);
6034 i = 0; /*Not the last ID yet. */
6037 else if (i != NO_ID_AVAIL)
6040 FPT_scxferc(p_port,ID_0_7);
6042 FPT_scxferc(p_port,ID_8_F);
6044 scam_id = (i & (unsigned char) 0x07);
6047 for (k=1; k < 0x08; k <<= 1)
6049 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6051 FPT_scxferc(p_port,scam_id);
6053 i = 0; /*Not the last ID yet. */
6064 FPT_scxferc(p_port,SYNC_PTRN);
6065 FPT_scxferc(p_port,CFG_CMPLT);
6072 /*---------------------------------------------------------------------
6074 * Function: FPT_scsel
6076 * Description: Select all the SCAM devices.
6078 *---------------------------------------------------------------------*/
6080 static void FPT_scsel(unsigned long p_port)
6083 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6084 FPT_scwiros(p_port, SCSI_MSG);
6086 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6089 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6090 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6091 (unsigned char)(BIT(7)+BIT(6))));
6094 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6095 FPT_scwiros(p_port, SCSI_SEL);
6097 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6098 ~(unsigned char)BIT(6)));
6099 FPT_scwirod(p_port, BIT(6));
6101 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6106 /*---------------------------------------------------------------------
6108 * Function: FPT_scxferc
6110 * Description: Handshake the p_data (DB4-0) across the bus.
6112 *---------------------------------------------------------------------*/
6114 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
6116 unsigned char curr_data, ret_data;
6118 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6120 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6122 curr_data &= ~BIT(7);
6124 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6126 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6127 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6129 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6131 curr_data |= BIT(6);
6133 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6135 curr_data &= ~BIT(5);
6137 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6139 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6141 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6142 curr_data |= BIT(7);
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6146 curr_data &= ~BIT(6);
6148 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6150 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6156 /*---------------------------------------------------------------------
6158 * Function: FPT_scsendi
6160 * Description: Transfer our Identification string to determine if we
6161 * will be the dominant master.
6163 *---------------------------------------------------------------------*/
6165 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
6167 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6171 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6173 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6176 ret_data = FPT_scxferc(p_port,00);
6178 else if (p_id_string[byte_cnt] & bit_cnt)
6180 ret_data = FPT_scxferc(p_port,02);
6184 ret_data = FPT_scxferc(p_port,01);
6189 if ((ret_data & 0x1C) == 0x10)
6190 return(0x00); /*End of isolation stage, we won! */
6192 if (ret_data & 0x1C)
6195 if ((defer) && (!(ret_data & 0x1F)))
6196 return(0x01); /*End of isolation stage, we lost. */
6203 return(0x01); /*We lost */
6205 return(0); /*We WON! Yeeessss! */
6210 /*---------------------------------------------------------------------
6212 * Function: FPT_sciso
6214 * Description: Transfer the Identification string.
6216 *---------------------------------------------------------------------*/
6218 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
6220 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6224 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6226 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6228 ret_data = FPT_scxferc(p_port,0);
6230 if (ret_data & 0xFC)
6236 if (ret_data & BIT(1)) {
6241 if ((ret_data & 0x1F) == 0)
6244 if(bit_cnt != 0 || bit_cnt != 8)
6248 FPT_scxferc(p_port, SYNC_PTRN);
6249 FPT_scxferc(p_port, ASSIGN_ID);
6261 p_id_string[byte_cnt] = the_data;
6270 /*---------------------------------------------------------------------
6272 * Function: FPT_scwirod
6274 * Description: Sample the SCSI data bus making sure the signal has been
6275 * deasserted for the correct number of consecutive samples.
6277 *---------------------------------------------------------------------*/
6279 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6284 while ( i < MAX_SCSI_TAR ) {
6286 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6299 /*---------------------------------------------------------------------
6301 * Function: FPT_scwiros
6303 * Description: Sample the SCSI Signal lines making sure the signal has been
6304 * deasserted for the correct number of consecutive samples.
6306 *---------------------------------------------------------------------*/
6308 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6313 while ( i < MAX_SCSI_TAR ) {
6315 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6327 /*---------------------------------------------------------------------
6329 * Function: FPT_scvalq
6331 * Description: Make sure we received a valid data byte.
6333 *---------------------------------------------------------------------*/
6335 static unsigned char FPT_scvalq(unsigned char p_quintet)
6337 unsigned char count;
6339 for (count=1; count < 0x08; count<<=1) {
6340 if (!(p_quintet & count))
6344 if (p_quintet & 0x18)
6352 /*---------------------------------------------------------------------
6354 * Function: FPT_scsell
6356 * Description: Select the specified device ID using a selection timeout
6357 * less than 4ms. If somebody responds then it is a legacy
6358 * drive and this ID must be marked as such.
6360 *---------------------------------------------------------------------*/
6362 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6366 WR_HARPOON(p_port+hp_page_ctrl,
6367 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6369 ARAM_ACCESS(p_port);
6371 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6372 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6375 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6376 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6378 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6380 WRW_HARPOON((p_port+hp_intstat),
6381 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6383 WR_HARPOON(p_port+hp_select_id, targ_id);
6385 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6386 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6387 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6390 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6391 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6393 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6394 FPT_Wait(p_port, TO_250ms);
6396 DISABLE_AUTO(p_port);
6398 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6399 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6401 SGRAM_ACCESS(p_port);
6403 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6405 WRW_HARPOON((p_port+hp_intstat),
6406 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6408 WR_HARPOON(p_port+hp_page_ctrl,
6409 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6411 return(0); /*No legacy device */
6416 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6417 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6419 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6424 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6426 WR_HARPOON(p_port+hp_page_ctrl,
6427 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6429 return(1); /*Found one of them oldies! */
6433 /*---------------------------------------------------------------------
6435 * Function: FPT_scwtsel
6437 * Description: Wait to be selected by another SCAM initiator.
6439 *---------------------------------------------------------------------*/
6441 static void FPT_scwtsel(unsigned long p_port)
6443 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6447 /*---------------------------------------------------------------------
6449 * Function: FPT_inisci
6451 * Description: Setup the data Structure with the info from the EEPROM.
6453 *---------------------------------------------------------------------*/
6455 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
6457 unsigned char i,k,max_id;
6458 unsigned short ee_data;
6459 PNVRamInfo pCurrNvRam;
6461 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6463 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6470 for(i = 0; i < max_id; i++){
6472 for(k = 0; k < 4; k++)
6473 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6474 for(k = 4; k < ID_STRING_LENGTH; k++)
6475 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6477 if(FPT_scamInfo[i].id_string[0] == 0x00)
6478 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6480 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6484 for (i=0; i < max_id; i++)
6486 for (k=0; k < ID_STRING_LENGTH; k+=2)
6488 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6489 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6490 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6492 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6495 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6496 (FPT_scamInfo[i].id_string[0] == 0xFF))
6498 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6501 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6505 for(k = 0; k < ID_STRING_LENGTH; k++)
6506 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6510 /*---------------------------------------------------------------------
6512 * Function: FPT_scmachid
6514 * Description: Match the Device ID string with our values stored in
6517 *---------------------------------------------------------------------*/
6519 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6522 unsigned char i,k,match;
6525 for (i=0; i < MAX_SCSI_TAR; i++) {
6529 for (k=0; k < ID_STRING_LENGTH; k++)
6531 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6537 FPT_scamInfo[i].state = ID_ASSIGNED;
6545 if (p_id_string[0] & BIT(5))
6550 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6551 match = p_id_string[1] & (unsigned char) 0x1F;
6559 if (FPT_scamInfo[match].state == ID_UNUSED)
6561 for (k=0; k < ID_STRING_LENGTH; k++)
6563 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6566 FPT_scamInfo[match].state = ID_ASSIGNED;
6568 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6569 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6579 if (p_id_string[0] & BIT(5))
6582 match = MAX_SCSI_TAR-1;
6588 if (p_id_string[0] & BIT(7))
6590 return(CLR_PRIORITY);
6594 if (p_id_string[0] & BIT(5))
6599 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6600 match = p_id_string[1] & (unsigned char) 0x1F;
6609 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6611 for (k=0; k < ID_STRING_LENGTH; k++)
6613 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6616 FPT_scamInfo[match].id_string[0] |= BIT(7);
6617 FPT_scamInfo[match].state = ID_ASSIGNED;
6618 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6619 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6629 if (p_id_string[0] & BIT(5))
6632 match = MAX_SCSI_TAR-1;
6636 return(NO_ID_AVAIL);
6640 /*---------------------------------------------------------------------
6642 * Function: FPT_scsavdi
6644 * Description: Save off the device SCAM ID strings.
6646 *---------------------------------------------------------------------*/
6648 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6650 unsigned char i,k,max_id;
6651 unsigned short ee_data,sum_data;
6656 for (i = 1; i < EE_SCAMBASE/2; i++)
6658 sum_data += FPT_utilEERead(p_port, i);
6662 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6664 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6670 for (i=0; i < max_id; i++)
6673 for (k=0; k < ID_STRING_LENGTH; k+=2)
6675 ee_data = FPT_scamInfo[i].id_string[k+1];
6677 ee_data |= FPT_scamInfo[i].id_string[k];
6678 sum_data += ee_data;
6679 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6680 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6685 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6686 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6689 /*---------------------------------------------------------------------
6691 * Function: FPT_XbowInit
6693 * Description: Setup the Xbow for normal operation.
6695 *---------------------------------------------------------------------*/
6697 static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6701 i = RD_HARPOON(port+hp_page_ctrl);
6702 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6704 WR_HARPOON(port+hp_scsireset,0x00);
6705 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6707 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6710 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6712 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6714 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6715 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6717 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6719 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6720 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6722 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6723 FPT_default_intena |= SCAM_SEL;
6725 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6727 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6729 /* Turn on SCSI_MODE8 for narrow cards to fix the
6730 strapping issue with the DUAL CHANNEL card */
6731 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6732 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6734 WR_HARPOON(port+hp_page_ctrl, i);
6739 /*---------------------------------------------------------------------
6741 * Function: FPT_BusMasterInit
6743 * Description: Initialize the BusMaster for normal operations.
6745 *---------------------------------------------------------------------*/
6747 static void FPT_BusMasterInit(unsigned long p_port)
6751 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6752 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6754 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6757 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6759 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6762 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6763 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6764 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6769 /*---------------------------------------------------------------------
6771 * Function: FPT_DiagEEPROM
6773 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6776 *---------------------------------------------------------------------*/
6778 static void FPT_DiagEEPROM(unsigned long p_port)
6780 unsigned short index,temp,max_wd_cnt;
6782 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6783 max_wd_cnt = EEPROM_WD_CNT;
6785 max_wd_cnt = EEPROM_WD_CNT * 2;
6787 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6789 if (temp == 0x4641) {
6791 for (index = 2; index < max_wd_cnt; index++) {
6793 temp += FPT_utilEERead(p_port, index);
6797 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6799 return; /*EEPROM is Okay so return now! */
6804 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6806 for (index = 0; index < max_wd_cnt; index++) {
6808 FPT_utilEEWrite(p_port, 0x0000, index);
6813 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6815 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6817 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6819 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6821 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6823 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6825 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6827 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6830 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6832 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6834 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6837 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6839 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6841 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6851 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6855 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6857 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6859 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6861 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6863 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6865 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6867 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6869 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6872 index = ((EE_SCAMBASE/2)+(7*16));
6873 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6874 temp += (0x0700+TYPE_CODE0);
6876 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6877 temp += 0x5542; /* BUSLOGIC */
6879 FPT_utilEEWrite(p_port, 0x4C53, index);
6882 FPT_utilEEWrite(p_port, 0x474F, index);
6885 FPT_utilEEWrite(p_port, 0x4349, index);
6888 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6889 temp += 0x5442; /* BT- 930 */
6891 FPT_utilEEWrite(p_port, 0x202D, index);
6894 FPT_utilEEWrite(p_port, 0x3339, index);
6896 index++; /*Serial # */
6897 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6900 FPT_utilEEWrite(p_port, 0x5453, index);
6903 FPT_utilEEWrite(p_port, 0x5645, index);
6906 FPT_utilEEWrite(p_port, 0x2045, index);
6909 FPT_utilEEWrite(p_port, 0x202F, index);
6912 FPT_utilEEWrite(p_port, 0x4F4A, index);
6915 FPT_utilEEWrite(p_port, 0x204E, index);
6918 FPT_utilEEWrite(p_port, 0x3539, index);
6923 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6925 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6930 /*---------------------------------------------------------------------
6932 * Function: Queue Search Select
6934 * Description: Try to find a new command to execute.
6936 *---------------------------------------------------------------------*/
6938 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6940 unsigned char scan_ptr, lun;
6941 PSCCBMgr_tar_info currTar_Info;
6944 scan_ptr = pCurrCard->scanIndex;
6947 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6948 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6949 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6951 if (currTar_Info->TarSelQ_Cnt != 0)
6955 if (scan_ptr == MAX_SCSI_TAR)
6958 for(lun=0; lun < MAX_LUN; lun++)
6960 if(currTar_Info->TarLUNBusy[lun] == 0)
6963 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6966 while((pCurrCard->currentSCCB != NULL) &&
6967 (lun != pCurrCard->currentSCCB->Lun))
6969 pOldSccb = pCurrCard->currentSCCB;
6970 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6973 if(pCurrCard->currentSCCB == NULL)
6975 if(pOldSccb != NULL)
6977 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6979 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6981 currTar_Info->TarSelQ_Cnt--;
6985 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6987 if (currTar_Info->TarSelQ_Head == NULL)
6989 currTar_Info->TarSelQ_Tail = NULL;
6990 currTar_Info->TarSelQ_Cnt = 0;
6994 currTar_Info->TarSelQ_Cnt--;
6995 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
6998 pCurrCard->scanIndex = scan_ptr;
7000 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7010 if (scan_ptr == MAX_SCSI_TAR) {
7018 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7019 (currTar_Info->TarLUNBusy[0] == 0))
7022 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7024 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7026 if (currTar_Info->TarSelQ_Head == NULL)
7028 currTar_Info->TarSelQ_Tail = NULL;
7029 currTar_Info->TarSelQ_Cnt = 0;
7033 currTar_Info->TarSelQ_Cnt--;
7034 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7038 if (scan_ptr == MAX_SCSI_TAR)
7041 pCurrCard->scanIndex = scan_ptr;
7043 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7051 if (scan_ptr == MAX_SCSI_TAR)
7057 } while (scan_ptr != pCurrCard->scanIndex);
7061 /*---------------------------------------------------------------------
7063 * Function: Queue Select Fail
7065 * Description: Add the current SCCB to the head of the Queue.
7067 *---------------------------------------------------------------------*/
7069 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7071 unsigned char thisTarg;
7072 PSCCBMgr_tar_info currTar_Info;
7074 if (pCurrCard->currentSCCB != NULL)
7076 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7077 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7079 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7081 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7083 if (currTar_Info->TarSelQ_Cnt == 0)
7085 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7090 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7094 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7096 pCurrCard->currentSCCB = NULL;
7097 currTar_Info->TarSelQ_Cnt++;
7100 /*---------------------------------------------------------------------
7102 * Function: Queue Command Complete
7104 * Description: Call the callback function with the current SCCB.
7106 *---------------------------------------------------------------------*/
7108 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7109 unsigned char p_card)
7112 unsigned char i, SCSIcmd;
7113 CALL_BK_FN callback;
7114 PSCCBMgr_tar_info currTar_Info;
7116 SCSIcmd = p_sccb->Cdb[0];
7119 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7121 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7122 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7123 (p_sccb->TargetStatus != SSCHECK))
7125 if ((SCSIcmd == SCSI_READ) ||
7126 (SCSIcmd == SCSI_WRITE) ||
7127 (SCSIcmd == SCSI_READ_EXTENDED) ||
7128 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7129 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7130 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7131 (pCurrCard->globalFlags & F_NO_FILTER)
7133 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7137 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7139 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7140 p_sccb->SccbStatus = SCCB_ERROR;
7142 p_sccb->SccbStatus = SCCB_SUCCESS;
7145 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7147 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7148 for (i=0; i < 6; i++) {
7149 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7153 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7154 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7156 FPT_utilUpdateResidual(p_sccb);
7159 pCurrCard->cmdCounter--;
7160 if (!pCurrCard->cmdCounter) {
7162 if (pCurrCard->globalFlags & F_GREEN_PC) {
7163 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7164 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7167 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7168 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7172 if(pCurrCard->discQCount != 0)
7174 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7175 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7176 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7178 pCurrCard->discQCount--;
7179 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7183 if(p_sccb->Sccb_tag)
7185 pCurrCard->discQCount--;
7186 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7189 pCurrCard->discQCount--;
7190 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7196 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7198 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7199 pCurrCard->currentSCCB = NULL;
7203 /*---------------------------------------------------------------------
7205 * Function: Queue Disconnect
7207 * Description: Add SCCB to our disconnect array.
7209 *---------------------------------------------------------------------*/
7210 static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
7212 PSCCBMgr_tar_info currTar_Info;
7214 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7216 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7217 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7219 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7223 if (p_sccb->Sccb_tag)
7225 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7226 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7227 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7230 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7233 FPT_BL_Card[p_card].currentSCCB = NULL;
7237 /*---------------------------------------------------------------------
7239 * Function: Queue Flush SCCB
7241 * Description: Flush all SCCB's back to the host driver for this target.
7243 *---------------------------------------------------------------------*/
7245 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7247 unsigned char qtag,thisTarg;
7249 PSCCBMgr_tar_info currTar_Info;
7251 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7252 if(currSCCB != NULL)
7254 thisTarg = (unsigned char)currSCCB->TargID;
7255 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7257 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7259 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7260 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7263 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7265 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7267 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7268 currTar_Info->TarTagQ_Cnt--;
7276 /*---------------------------------------------------------------------
7278 * Function: Queue Flush Target SCCB
7280 * Description: Flush all SCCB's back to the host driver for this target.
7282 *---------------------------------------------------------------------*/
7284 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7285 unsigned char error_code)
7288 PSCCBMgr_tar_info currTar_Info;
7290 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7292 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7294 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7295 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7298 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7300 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7302 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7303 currTar_Info->TarTagQ_Cnt--;
7314 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
7316 PSCCBMgr_tar_info currTar_Info;
7317 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7319 p_SCCB->Sccb_forwardlink = NULL;
7321 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7323 if (currTar_Info->TarSelQ_Cnt == 0) {
7325 currTar_Info->TarSelQ_Head = p_SCCB;
7330 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7334 currTar_Info->TarSelQ_Tail = p_SCCB;
7335 currTar_Info->TarSelQ_Cnt++;
7339 /*---------------------------------------------------------------------
7341 * Function: Queue Find SCCB
7343 * Description: Search the target select Queue for this SCCB, and
7344 * remove it if found.
7346 *---------------------------------------------------------------------*/
7348 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
7351 PSCCBMgr_tar_info currTar_Info;
7353 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7355 q_ptr = currTar_Info->TarSelQ_Head;
7357 while(q_ptr != NULL) {
7359 if (q_ptr == p_SCCB) {
7362 if (currTar_Info->TarSelQ_Head == q_ptr) {
7364 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7367 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7369 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7372 if (q_ptr->Sccb_forwardlink != NULL) {
7373 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7376 if (q_ptr->Sccb_backlink != NULL) {
7377 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7380 currTar_Info->TarSelQ_Cnt--;
7386 q_ptr = q_ptr->Sccb_forwardlink;
7396 /*---------------------------------------------------------------------
7398 * Function: Utility Update Residual Count
7400 * Description: Update the XferCnt to the remaining byte count.
7401 * If we transferred all the data then just write zero.
7402 * If Non-SG transfer then report Total Cnt - Actual Transfer
7403 * Cnt. For SG transfers add the count fields of all
7404 * remaining SG elements, as well as any partial remaining
7407 *---------------------------------------------------------------------*/
7409 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7411 unsigned long partial_cnt;
7412 unsigned int sg_index;
7413 unsigned long *sg_ptr;
7415 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7417 p_SCCB->DataLength = 0x0000;
7420 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7422 partial_cnt = 0x0000;
7424 sg_index = p_SCCB->Sccb_sgseg;
7426 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7428 if (p_SCCB->Sccb_SGoffset) {
7430 partial_cnt = p_SCCB->Sccb_SGoffset;
7434 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
7435 p_SCCB->DataLength ) {
7437 partial_cnt += *(sg_ptr+(sg_index * 2));
7441 p_SCCB->DataLength = partial_cnt;
7446 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7451 /*---------------------------------------------------------------------
7453 * Function: Wait 1 Second
7455 * Description: Wait for 1 second.
7457 *---------------------------------------------------------------------*/
7459 static void FPT_Wait1Second(unsigned long p_port)
7463 for(i=0; i < 4; i++) {
7465 FPT_Wait(p_port, TO_250ms);
7467 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7470 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7476 /*---------------------------------------------------------------------
7478 * Function: FPT_Wait
7480 * Description: Wait the desired delay.
7482 *---------------------------------------------------------------------*/
7484 static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7486 unsigned char old_timer;
7487 unsigned char green_flag;
7489 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7491 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7492 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7494 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7495 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7496 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7499 WR_HARPOON(p_port+hp_portctrl_0,
7500 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7502 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7504 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7507 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7511 WR_HARPOON(p_port+hp_portctrl_0,
7512 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7514 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7515 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7517 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7519 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7523 /*---------------------------------------------------------------------
7525 * Function: Enable/Disable Write to EEPROM
7527 * Description: The EEPROM must first be enabled for writes
7528 * A total of 9 clocks are needed.
7530 *---------------------------------------------------------------------*/
7532 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
7534 unsigned char ee_value;
7536 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7540 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7545 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7547 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7548 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7552 /*---------------------------------------------------------------------
7554 * Function: Write EEPROM
7556 * Description: Write a word to the EEPROM at the specified
7559 *---------------------------------------------------------------------*/
7561 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
7564 unsigned char ee_value;
7567 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7572 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7575 ee_value |= (SEE_MS + SEE_CS);
7577 for(i = 0x8000; i != 0; i>>=1) {
7582 ee_value &= ~SEE_DO;
7584 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 ee_value |= SEE_CLK; /* Clock data! */
7587 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7588 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7589 ee_value &= ~SEE_CLK;
7590 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7591 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7593 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7594 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7596 FPT_Wait(p_port, TO_10ms);
7598 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7599 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7600 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7603 /*---------------------------------------------------------------------
7605 * Function: Read EEPROM
7607 * Description: Read a word from the EEPROM at the desired
7610 *---------------------------------------------------------------------*/
7612 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
7614 unsigned short i, ee_data1, ee_data2;
7617 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7620 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7622 if(ee_data1 == ee_data2)
7625 ee_data1 = ee_data2;
7633 /*---------------------------------------------------------------------
7635 * Function: Read EEPROM Original
7637 * Description: Read a word from the EEPROM at the desired
7640 *---------------------------------------------------------------------*/
7642 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
7645 unsigned char ee_value;
7646 unsigned short i, ee_data;
7648 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7652 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7655 ee_value |= (SEE_MS + SEE_CS);
7658 for(i = 1; i <= 16; i++) {
7660 ee_value |= SEE_CLK; /* Clock data! */
7661 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7662 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7663 ee_value &= ~SEE_CLK;
7664 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7665 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7669 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7673 ee_value &= ~(SEE_MS + SEE_CS);
7674 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7675 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7681 /*---------------------------------------------------------------------
7683 * Function: Send EE command and Address to the EEPROM
7685 * Description: Transfers the correct command and sends the address
7688 *---------------------------------------------------------------------*/
7690 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
7692 unsigned char ee_value;
7693 unsigned char narrow_flg;
7698 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7702 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7704 ee_value |= SEE_CS; /* Set CS to EEPROM */
7705 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7708 for(i = 0x04; i != 0; i>>=1) {
7713 ee_value &= ~SEE_DO;
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 ee_value |= SEE_CLK; /* Clock data! */
7718 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7719 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7720 ee_value &= ~SEE_CLK;
7721 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7722 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7738 ee_value &= ~SEE_DO;
7740 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 ee_value |= SEE_CLK; /* Clock data! */
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7745 ee_value &= ~SEE_CLK;
7746 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7755 unsigned short crc=0;
7758 for (i=0; i < ID_STRING_LENGTH; i++)
7760 ch = (unsigned short) buffer[i];
7761 for(j=0; j < 8; j++)
7764 crc = (crc >> 1) ^ CRCMASK;
7773 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7778 for(i = 0; i < ID_STRING_LENGTH; i++)
7786 The following inline definitions avoid type conflicts.
7789 static inline unsigned char
7790 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7792 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7796 static inline FlashPoint_CardHandle_T
7797 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7799 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7803 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7805 FlashPoint_ReleaseHostAdapter(CardHandle);
7810 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7812 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7817 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7819 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7823 static inline boolean
7824 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7826 return FlashPoint_InterruptPending(CardHandle);
7831 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7833 return FlashPoint_HandleInterrupt(CardHandle);
7837 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7838 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7839 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7840 #define FlashPoint_StartCCB FlashPoint__StartCCB
7841 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7842 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7843 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7846 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7850 Define prototypes for the FlashPoint SCCB Manager Functions.
7853 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7854 extern FlashPoint_CardHandle_T
7855 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7856 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7857 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7858 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7859 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7860 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7863 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */